一、 Shiro简介
1、Shiro简述
Apache Shiro 是一个强大的 Java 安全框架,用于执行身份验证、授权、密码和会话管理等核心安全功能。其“记住我”(RememberMe)特性如果存在加密密钥泄露,无论 Shiro 是什么版本,都可能导致反序列化漏洞,进而引发远程代码执行。
2、Shiro漏洞原理
Apache Shiro框架的“记住我”功能会在用户登录成功后,生成一个经过加密和编码的Cookie,其Key为“rememberMe”。Cookie的值是对用户信息进行序列化,再使用AES加密,最后经过Base64编码处理形成的。
服务端在接收到该Cookie值时,会按照以下步骤进行解析:
- 检索
RememberMe Cookie 的值
- 进行 Base64 解码
- 使用 AES 解密(依赖于加密密钥)
- 对解密后的数据进行反序列化操作
漏洞关键点在于,在调用反序列化时未进行任何过滤。如果攻击者能够获取AES加密密钥,就可以构造恶意的序列化数据,经过加密编码后发送给服务器,服务器解密后触发反序列化,从而执行任意代码。
3、Shiro序列化利用条件
利用该漏洞的核心在于获取AES加密密钥。在Shiro 1.2.4及之前的版本中,使用了默认的硬编码密钥。其Base64编码后的值为kPH+bIxk5D2deZiIxcaaaA==。攻击者可以利用此默认密钥直接构造攻击载荷。
尽管后续版本官方移除了硬编码密钥,改为每次生成随机密钥,但许多开源系统、示例代码中仍可能使用固定的密钥。通过搜索引擎、GitHub等渠道收集这些密钥,可以显著提高漏洞检测与利用的成功率。
4、Shiro漏洞指纹识别
识别一个网站是否使用了Shiro框架,并可能受到此漏洞影响,可以观察以下特征:
- 在HTTP响应包中,检查是否存在
Set-Cookie: rememberMe=deleteMe。
- 观察URL路径中是否包含
shiro 字样。
- 主动在请求包中添加
Cookie: rememberMe=1,如果响应中包含 rememberMe=deleteMe,则基本可以确认。
二、 本地环境搭建与测试
1、环境下载
从 GitHub 下载 Apache Shiro 1.2.4 版本的源码包进行测试:
https://github.com/apache/shiro/releases/tag/shiro-root-1.2.4

2、环境安装
安装Java
因为运行Tomcat需要Java环境,需先安装JDK。

安装Tomcat
安装Tomcat 8.5作为Web服务器容器。


部署Shiro
将下载的 shiro.war 包放入 Tomcat 的 webapps 目录下。Tomcat会自动解压并部署该应用。

注:如果目录下没有自动生成 shiro 文件夹,需要启动Tomcat服务器(运行 tomcat/bin 目录下的 tomcat8.exe 或 startup.bat)来完成部署。

访问测试
部署成功后,访问以下地址进行测试:
http://127.0.0.1:8080/shiro/

访问登录页面:
http://127.0.0.1:8080/shiro/login.jsp

三、 Shiro漏洞复现:出网与不出网场景
1、Linux出网环境渗透(CVE-2016-4437)
漏洞描述
Apache Shiro <= 1.2.4 版本中,由于RememberMe功能使用的AES加密密钥硬编码,导致攻击者可以构造恶意的序列化数据,在反序列化时执行任意代码。
漏洞启动 (使用Vulhub)
- 进入漏洞环境目录:
cd /root/vulhub-master/shiro/CVE-2016-4437
- 启动漏洞环境:
sudo docker-compose up -d

- 验证容器是否运行:
sudo docker ps

漏洞复现步骤
- 访问靶机:
http://192.168.200.128:8080/
- 指纹识别:使用Burp Suite等工具抓取登录请求包,将Cookie修改为
rememberMe=1 并发送。若响应包中出现 Set-Cookie: rememberMe=deleteMe,则确认存在Shiro框架。


- 利用工具攻击:使用
shiro_attack 等综合利用工具。输入目标地址,工具会自动探测默认密钥,选择相应的Gadget(如CommonsCollectionsK1)和回显方式(如TomcatEcho),即可执行命令。



2、Linux不出网环境渗透利用
在目标服务器无法访问外网(不出网)的情况下,反弹Shell等常规方式会失效。此时需要采用不同的利用思路。
环境搭建
使用另一个漏洞镜像搭建不出网测试环境:
# 拉取镜像
docker pull medicean/vulapps:s_shiro_1
# 运行容器,将容器8080端口映射到主机8888端口
docker run -d -p 8888:8080 medicean/vulapps:s_shiro_1


访问 http://192.168.200.128:8888/ 确认环境搭建成功。


不出网攻击利用(使用延时检测脚本)
出网环境下,我们可以让目标服务器直接连接我们的监听端口。但在不出网时,我们需要借助“延时”来判断命令是否执行成功。其原理是执行 sleep 等命令,通过对比响应时间来判断漏洞是否存在以及密钥是否正确。
- 使用Python脚本探测:存在一些利用脚本(如
shiro-1.2.4-rce.py),通过循环尝试密钥和Gadget组合,并发送带有 sleep 命令的Payload,根据响应延迟来判断是否利用成功。

- 脚本执行与交互:运行脚本攻击目标,脚本在找到正确密钥和Gadget后,会提供一个交互式的Shell。注意,由于不出网,此Shell无法直接反弹到攻击机,但可以在目标服务器当前容器或系统权限内执行命令。
python3 shiro-1.2.4_rce.py http://192.168.200.128:8888/


- 局限性:这种方式的命令执行结果(回显)依赖于应用服务器的配置,在某些情况下可能无法直接看到命令输出。但其价值在于验证了漏洞存在并具备代码执行能力,为后续的横向移动或内存马注入提供了基础。
四、 总结与思考
- 漏洞原理核心:Shiro反序列化漏洞的根源在于RememberMe功能采用了可预测或泄漏的AES密钥对用户数据进行加密,且在服务端反序列化数据前未做任何安全过滤。理解这个流程对于渗透测试中的漏洞利用和防御至关重要。
- 环境搭建是基础:无论是使用官方War包在Tomcat中部署,还是利用Docker漏洞镜像快速搭建,掌握环境复现能力是深入学习漏洞的前提。
- 区分利用场景:
- 出网环境:可以利用工具直接获取交互式Shell或执行命令回显,是理想的利用条件。
- 不出网环境:利用变得复杂,需要借助延时盲注的方式探测密钥与利用链。成功后的利用也受到限制,通常需要结合写入内存马、进行内网横向渗透等手段。这要求安全人员不仅会使用工具,更要理解Java反序列化漏洞的原理和各种Gadget的适用场景。
在实际的服务攻防演练或安全评估中,遇到不出网的内网系统是常态。因此,掌握在不出网环境下对Shiro这类框架的漏洞验证和初步利用方法,是提升攻防能力的关键一环。