花了一周的时间对现有的CommonsCollections利用链分析了一遍,这篇文章是总结一下各利用链的特点、适用场景以及我自己对于Java反序列化链的一点思考。
各利用链利用点
从前面的分析中,对于每个利用链,我们可以从外层触发点、中间承接点、命令执行点来分析。
外层触发点:
- AnnotationInvocationHandler
- CommonsCollections1
- CommonsCollections3
- BadAttributeValueExpException
- CommonsCollections5
- CommonsCollections9
- HashSet
- HashMap.hash
- CommonsCollections6
- HashMap.hash
- Hashtable
- CommonsCollections7
- CommonsCollections10
- PriorityQueue
- CommonsCollections2
- CommonsCollections4
- TreeBag
- CommonsCollections8
中间承接点
- Proxy.invoke
- CommonsCollections1
- AbstractMap.equals
- CommonsCollections7
- TreeMap
- CommonsCollections8
- TransformingCompare
- CommonsCollections2
- CommonsCollections4
- TiedMapEntry.getValue
- hashCode
- CommonsCollections6
- CommonsCollections10
- toString
- CommonsCollections5
- CommonsCollections9
- hashCode
- LazyMap.get
- CommonsCollections1
- CommonsCollections3
- CommonsCollections6
- CommonsCollections5
- CommonsCollections10
- DefaultedMap.get
- CommonsCollections9
这里可以看到LazyMap.get和DefaultedMap.get是可作为中间承接点的第二层,即找到一个调用它的类作为中间承接点。
命令执行点
- InvokerTransformer提供了通过反射创建实例对象
- constant+invoker+invoker
- CommonsCollections1
- CommonsCollections3
- CommonsCollections5
- CommonsCollections6
- CommonsCollections7
- CommonsCollections9
- CommonsCollections10
- Invoker反射调用
newTransformer方法- CommonsCollections8
- CommonsCollections2
- constant+invoker+invoker
- InstantiateTransformer提供了实例化当前传入的类的方法
- TrAXFilter类的构造方法中含有
templates.newTransformer()- CommonsCollections4
- TrAXFilter类的构造方法中含有
根据commons-collections版本
commonscollections3.1
- CommonsCollections1
- CommonsCollections3
- CommonsCollections5
- CommonsCollections6
- CommonsCollections7
- CommonsCollections10
commonscollections3.2.1
- CommonsCollections1
- CommonsCollections3
- CommonsCollections5
- CommonsCollections6
- CommonsCollections7
- CommonsCollections9
- CommonsCollections10
commonscollections4.0
- CommonsCollections2
- CommonsCollections4
- CommonsCollections8
其他
未配置security-manager
- CommonsCollections5
- CommonsCollections9
<= JDK8u72
- CommonsCollections1
- CommonsCollections3
在实际使用中,在3.x版本下使用6,7,10来进行测试会更好,没有太多的限制;在4.0版本下使用4,8来进行测试。
思考
其实分析完上述的payload之后,很容易发现,在很多链中,都是由其他链分断合并而来。在找这样的利用链时,可以从执行最终的命令触发开始,往前寻找能够触发这一条件的方法,以及调用这些方法类,然后进行筛选,这样一层一层往外找,直到找到一个最外层。
对于外层触发点,一般需要具有以下条件:
- 可被序列化
- 重写了readObject类
- readObject类中有其他函数(除类似
defaultReadObject之类的)调用
对于中间承接点,一般需要具有以下条件:
- 可被序列化
- 该类的类属性有函数调用
- 实现了InvocationHandler,具有invoke函数(考虑动态代理的方式)
对于命令执行点,一般需要具有以下条件:
- 能够加载并实例化类
- 或者能够反射调用创建对象并调用方法
这是我的一个直观的想法,可能已经有工具使用来自动化地分析与寻找这些点。例如Gadget Inspector。