commoncollections1反序列化调试(基础知识)
Java安全之commonscollections1链分析(一)
0x00 前言
本篇文章记录一下commoncollections1链反序列化执行命令的原理,由于涉及到的分析基础相对于URLDNS链略显复杂,这里先整理一下cc1链构造的知识基础。
0x01 前置知识
1.Transformer
这里可以看到Transformer是cc链中提供的一个接口,其中有一个方法叫做transform。
2.ConstantTransformer
看一下源码实现,这里可以看到ConstantTransformer实现了Transformer接口,并且重写了transform方法。实际就是把传递给ConstantTransformer的值封装一下返回。
3.InvokerTransformer
源码中InvokerTransformer构造方法用来赋值,重写的transform方法使用反射调用并执行命令,并返回执行结果。
4.ChainedTransformer
这里ChainedTransformer方法实际上做了链式操作,将一个执行完重写transform方法的返回值作为下一个执行transform方法的形参,最后返回链式操作的整体返回值。
为什么要介绍这些transformer的实现类呢,因为ysoserial就是通过这些Transformer实现类达到反射执行任意命令的实现。
看一下源码可知,红框第一部分声明了一个Transformer数组,包含一个ConstantTransformer,3个InvokerTransformer,最后一个ConstantTransformer无执行命令的意义,暂时不关注。这里将Runtime.getRuntime().exec("calc.exe")使用反射调用和链式组装实现了出来。
那么具体什么时候会触发回调每个Transformer的transform方法呢?
5.LazyMap.decorate(innerMap, transformerChain);
被修饰过的Map在调用get方法时,会触发transform回调.
我们看一下调用流程就大概明白了
LazyMap#decorate public static Map decorate(Map map, Transformer factory) { return new LazyMap(map, factory); }
LazyMap类不能直接通过new来获取一个LazyMap,需要通过调用一个decorate方法生产一个LazyMap,第一个参数是被修饰的map,第二个参数是个Transfomer类型的
LazyMap#get public Object get(Object key) { if (!super.map.containsKey(key)) { Object value = this.factory.transform(key); super.map.put(key, value); return value; } else { return super.map.get(key); } }
接下来看一下get方法,我们可以发现get方法首先判断了map集合是否有这个key,如果没有则调用this.factory的transform方法自己获取一个值,也就是这个时候可以触发transform方法,造成链式操作的执行,进而执行命令。换句话说我们需要通过反序列化入口点找一个可以调用LazyMap的get方法的链,进而命令执行。
0x03 后续
大概介绍了下cc1中构造链的基础后,下一篇我们将分析cc1链具体是怎么实现和触发的。





浙公网安备 33010602011771号