CommonsCollections3反序列化链分析

简介

调试分析 ysoserial 种的 Apache Commons Collections 系列第三条链子。

这篇开始算是脱离了萌新期,有重点地针对核心部分进行分析,篇幅也开始

复现

jdk1.7+tomcat8+Apache Commons Collections3.1

(cc2 的环境是 4.4 所以要换一下)

image-20220320132820-4tpc4xo.png

分析

ysoserial 中的注释说明;

1
2
* Variation on CommonsCollections1 that uses InstantiateTransformer instead of
* InvokerTransformer.

这回我们不用 InvokerTransformer 了,改用 InstantiateTransformer 替代,回顾一下前者在 cc1 里的作用。

1
2
3
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()

是最后执行反射调用的类。

Gadgets.createTemplatesImpl(command)

这个方法在 cc2 里面分析过了

它返回一个 templates 对象,其中包含了动态构造的恶意字节码,当恶意类被加载实例化的时候会触发恶意代码。

image-20220320133246-v9pwg8q.png

image-20220320133610-8jf5xlw.png

new ChainedTransformer

初始化一个 ChainedTransformer 对象,并新建一个 Transformer 数组,其中为初始值,这是 ysoserial 的常规操作。

由于这里还是 ChainedTransformer 对象,所以和 cc1 一样,利用方法是将数组中第一个元素的 transform 方法返回值作为下一个数组元素 transform 方法的输入值

image-20220320134613-qrjnqsr.png

随后构造真正的 chain

image-20220320134852-7m5urdz.png

开始分析这个 transformer 数组

new ConstantTransformer

返回 TrAXFilter.class

image-20220320135407-bq8jy27.png

new InstantiateTransformer

image-20220320135811-mlmbv31.png

跟进构造器和这个类的 transform 方法

image-20220320135934-zyngloh.png

构造方法传入了 Templates.class 和刚刚包含了恶意字节码的 templatesImpl 实例对象

然后这里 input 参数是上个数组元素传回来的 TrAXFilter.class,所以反射拿到的是 TrAXFilter 类的构造器,接着通过构造器传入我们构造的 templatesImpl 恶意对象反射实例化类并返回。

image-20220320140547-5bmu12l.png

可以清楚的看到 TrXFilter 类中对传入的 templates 调用了 newTransformer 方法。

在 CC2 中分析过了,这里会实例化我们的恶意 class 并加载它静态块里的内容。

所以这里其实是整条链子的最后一环,TrAXFilter+InstantiateTransformer,十分巧妙的配合。

至此我们获得了构造好的 transformer 数组,并且当 ChainedTransformer.transform 被调用的时候就会自动加载整条链子完成调用。

构造 LazyMap 攻击链

同 CC1 一样的 LazyMap 攻击链,此处不再多分析。

最后设置的入口是 AnnotationInvocationHandler.readObject(),在 cc1 中我们分析过这个方法此处不再赘述。

sun.reflect.annotation.AnnotationInvocationHandler

image-20220320141808-q7xsv5j.png

反射赋值

最后把刚开始初始化的值用我们构造好的 transformer 数组替换掉,ysoserial 这样做为了防止在 payload 初始化的时候就出发了攻击链,并且也起到安全保护等效果,个人看来最后把真正的 payload 加载进去像装子弹一样,很清晰。

image-20220320142012-sfhhy48.png

调试

和 cc1,cc2 一样,基本没变,和 cc1 相比这么多是一样的

1
2
3
4
5
6
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
AnnotationInvocationHandler.invoke()
LazyMap.get()
ChainedTransformer.transform()

image-20220320145254-1a0lbfh.png

很清晰的方法栈。

template 对象和 TrAXFilter 构造器

image-20220320145346-rg5aw3v.png