Java反序列化利用链分析
一、反序列化漏洞基础
序列化与反序列化是什么?
- 序列化:将Java对象转换为字节流(如保存到文件或网络传输)
- 反序列化:将字节流还原为Java对象
- 漏洞本质:攻击者构造恶意字节流,触发反序列化过程中的危险操作(如命令执行)
为何会产生漏洞?
当程序对不可信数据(如网络传输、文件读取)直接调用
ObjectInputStream.readObject()时,若该数据包含精心设计的恶意对象链,会触发预期外的代码执行。
二、利用链(Gadget Chain)核心逻辑
🔑 1. 利用链三要素
| 组件 | 作用 | 示例类/方法 |
|---|---|---|
| 入口点 | 反序列化时自动调用的起点方法 | HashMap.readObject(), BadAttributeValueExpException.readObject() |
| 传递链 | 通过方法调用、属性访问连接入口和出口的中间环节 | Map.put(), Transformer.transform(), equals() |
| 出口点 | 最终执行危险操作的方法(如命令执行、DNS请求) | Runtime.exec(), URLStreamHandler.hashCode() |
🌰 2. 形象比喻
把利用链看作多米诺骨牌:
- 入口点是第一张牌(
readObject被推倒)- 传递链是中间连锁反应(牌与牌之间的碰撞)
- 出口点是最后一张牌(命令执行倒地)
⚠️ 3. 关键特性
- 动态反射调用:通过反射执行任意类的方法(如
InvokerTransformer.transform()调用Runtime.exec()) - 对象嵌套控制:恶意对象需满足字段约束(如特定类属性值需满足条件分支)
- 延迟触发:利用反射修改对象状态,避免序列化时立即执行(如URLDNS链修改
url.hashCode=-1)
三、经典利用链案例解析
🎯 1. URLDNS链(无害探测)
用途:探测目标是否存在反序列化漏洞(仅触发DNS请求,不执行命令)
调用链:
graph LR A[HashMap.readObject] --> B[HashMap.putVal] B --> C[HashMap.hash] C --> D[URL.hashCode] D --> E[URLStreamHandler.hashCode] E --> F[发起DNS请求]绕过技巧:
用反射临时修改
url.hashCode=1234→ 执行map.put(url)→ 再改回hashCode=-1,避免提前触发。
💥 2. CommonsCollections1链(命令执行)
漏洞类:
InvokerTransformer(通过反射执行任意方法)核心调用链:
BadAttributeValueExpException.readObject() → TiedMapEntry.toString() → LazyMap.get() → ChainedTransformer.transform() // 串联多个Transformer → InvokerTransformer.transform() // 反射调用Runtime.exec("calc")依赖条件:
- Apache Commons Collections ≤ 3.2.1
- JDK ≤ 8u71(后续版本修复了
AnnotationInvocationHandler的利用)
🛡️ 3. JDK 8u71后的绕过(CC6链)
修复绕过:不再依赖
AnnotationInvocationHandler,改用TiedMapEntry作为入口新调用链:
HashMap.readObject() → TiedMapEntry.hashCode() → TiedMapEntry.getValue() → LazyMap.get() // 触发后续Transformer调用链
四、漏洞防御方案
🛠️ 1. 代码层防护
输入过滤:禁用
ObjectInputStream,改用JSON等安全格式(如Gson)白名单控制(JDK≥9):
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter( "com.trusted.pkg.*;!*" // 仅允许指定包名的类 ); ois.setObjectInputFilter(filter);字段验证:在
readObject()中校验关键字段合法性
📦 2. 依赖与环境
升级基础库:
<!-- Commons Collections安全版本 --> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.2+</version> </dependency>JVM参数加固:
-Djdk.serialFilter=!org.apache.commons.collections.functors.* -Dcom.sun.jndi.rmi.object.trustURLCodebase=false
🔍 3. 检测工具
- 漏洞扫描:使用
ysoserial生成Payload测试(命令:java -jar ysoserial.jar CommonsCollections5 "id" > payload.bin) - 动态分析:结合
SerializationDumper解析序列化流结构
五、学习资源推荐
- 工具实践:
- 调试技巧:在IDEA中下载
commons-collections 3.2.1源码,断点跟踪LazyMap.get()调用流程 - 靶场环境:Vulhub(
WebLogic/JBoss反序列化漏洞场景)
💡 小白学习路线:先掌握URLDNS链(理解触发逻辑) → 再调试CC1链(学习反射调用) → 最后分析CC6(了解绕过技巧),配合靶场实战巩固。