背景
Apache Shiro 中一个已知的反序列化漏洞——Shiro-550,它尽管存在已久,但由于其自带的加密特性和影响力,在近几年的安全演练中受到了特别关注。Yakit 中也很早就添加了 Shiro 相关的漏洞检测插件,但在 YAK 引擎的更新迭代中,一些 bug 影响了一些漏洞的检出。为了确保我们没有无意中破坏了现有的功能(这称为回归错误),我们对一些插件进行了内置化,同时结合 vulinbox
靶场当作测试靶场,对目前的几个社区呼声较高的插件来了一波 "出厂检验"。
01
Shiro RememberMe 反序列化漏洞检测
shiro 漏洞相关的原理以及利用工具已经有很多师傅分享了。如今主流的检测 Shiro Key 的方式是由 l1nk3r
师傅分享的,使用一个空的 SimplePrincipalCollection
序列化后和要检测的 Key 进行加密作为 payload 发送,判断响应头中的 deleteMe
个数。
在总结和学习了很多师傅的检测逻辑后,目前 Yakit shiro 插件的检测逻辑如下:
使用的四条回显链分别为,CB183NOCC、CB192NOCC、CCK1、CCK2
完整的代码可以直接在 Yakit 插件商店查看
检测到 Shiro(Cookie) 框架使用
(Shiro 默认 KEY)
(Shiro Header 回显)
(Shiro 利用链探测)
02
Vulinbox Shiro 靶场设计
启动靶场时,随机使用 Shiro Key 列表中的一个当作默认的 Key,随机使用 Gadget 列表(CB183NOCC、CB192NOCC、CCK1、CCK2)中的一个,模拟可利用链
为了简单,在非在 SimplePrincipalCollection 序列化加密后的 payload 请求的响应头中添加 Set-Cookie: rememberMe=deleteMe
获取 Cookie rememberMe 的值,Base64 解码后再使用第一步中的默认 Key 进行 AES/GCM 解密
判断解密后的数据是否是一个正常的 Java 序列化对象,如果是,反序列化Java对象流,判断是否包含值为org.apache.shiro.subject.SimplePrincipalCollection 的 ClassName,如果包含,去掉响应头中的 Set-Cookie: rememberMe=deleteMe 字段
SerialVersionUID
是不一样的,所以除了类名org.apache.commons.beanutils.BeanComparator
我们也要判断 SerialVersionUID
, 上图中的 serial_version
字段在经过转换后,其实就是常见的 -3490850999041592962
这种 SerialVersionUID 了。yv66
,那接下来的思路就简单多了,反序列化 Java 对象流(也就是解密后的payload) -> 拿到 Class
字节码 -> 解析 Class
字节码 -> 遍历常量池,找到 setHeader
的传入值 -> 靶场 Server 响应头添加对应回显 -> Shiro 插件检出(Shiro Header 回显)
风险。03
Vulinbox Shiro 靶场漏洞检出
IduElDUpDDXE677ZkhhKnQ==
和 gadget CCK1
:Vhmymv: emImhYiW。
04
不按套路出牌的环境
body
中存在 rememberMe=1
或者 rememberMe=true
时,才会进入后续的 Cookie rememberMe
处理流程。总结
Yakit更新记录
Yakit 1.2.2-sp1
1. webfuzzer新增标签与编解码辅助工具,支持新增常用标签
2. 修复批量发包列表加载问题
3. 恢复发包后可提取数据的功能
4. 新增靶场功能,安装即可使用(设置—试验性功能)
Yaklang 1.2.2-sp3
1. 新增插件自动评估机制的 gRPC 接口,可以自动检查插件质量
2. 新增 Web Fuzzer Tag 缓存机制
3. 优化 HTTP2 中 :authority 被强制加端口的情况
4. 修复 params 的对 JSON 的展示信息
5. 修复浏览器爬虫库的一些小问题
6. 新增靶场管理的 gRPC 接口
扫码添加客服
加入YAK技术交流群