浅析反序列化利用链自动化挖掘工具GadgetInspector
/0x00 工具地址
https://github.com/JackOfMostTrades/gadgetinspector
0x01 BlackHat议题解读
下面按照BlackHat 2018中的演讲PPT展开介绍。
反序列化漏洞及利用工具概述
作者先介绍了什么是反序列化漏洞,其中提到了反序列化漏洞之所以危害那么大是因为反序列化器会自动调用魔法函数。
魔法函数包括主要的readObject()和readResolve(),当然还有finalize()。除此之外,还有那些实现了这些魔法函数并调用了其他方法的可序列化的JDK类,归纳来说如下:
- Object.readObject()
- Object.readResolve()
- Object.finalize()
- HashMap
- Object.hashCode()
- Object.equals()
- PriorityQueue
- Comparator.compare()
- Comparable.compareTo()
如下图从hashCode()这个魔术方法看整条利用链:
这里readObject()函数中是调用了hashCode()函数;看到AbstractTableModel$ff19274a类的hashCode()函数实现是由调用IFn接口类的invoke()函数的;再看到实现IFn接口类的FnCompose类,其中自己实现的invoke()函数中分别调用了两个IFn类型的成员变量的invoke()函数,其中包括FnEval类的invoke()函数,这个方法中就是执行系统命令的Runtime.exec()。
所以直接构造如下Exp即可成功触发反序列化漏洞:
1 | { |
哪些Java库是有漏洞的?作者列出了以下几种(当然现在就不止了):
- JDK (ObjectInputStream)
- XStream (XML, JSON)
- Jackson (JSON)
- Genson (JSON)
- JSON-IO (JSON)
- FlexSON (JSON)
那么如何挖掘这种类型的漏洞呢?其实和挖掘应用安全问题一样:
- 外部输入会传进漏洞出发点;
- 现有的静态和动态工具可以很好地辅助发现此类问题;
已知的一些反序列化利用工具:
- ysoserial:通常仅限于特定库中的链,并侧重于JDK ObjectInputStream的攻击利用;
- marshalsec:可供选择的反序列化库的利用范围更广;
但是,如果我们使用的是非标准反序列化库或者classpath上一些特定组合的库时,上面的工具就无法进行攻击利用了。
现存的Gadget链工具:
- ysoserial:收集已知的Gadget链和Exp;
- joogle:以编程方式查询类路径上的类型/方法;
- Java Deserialization Scanner:BurpSuite插件,使用已知payload(ysoserial)来发现和利用漏洞;
- marshalsec:用于许多库和Gadget链的反序列化payload生成器;
- NCC Group Burp Plugin:“主要基于穆尼奥斯和米罗什的《星期五13:JSON攻击》”
接着作者引出我们实际需要一个新工具,这个工具不需要自己生成payload,而是能够评估安全风险,即给定一个反序列化漏洞能否被攻击利用,有哪些利用方式比如RCE或DoS或SSRF。
因此,作者对该工具提出如下需求:
不用于寻找漏洞,只在漏洞挖掘阶段使用此工具辅助发现问题;
它需要查看应用程序的整个classpath;
报错信息应该是误报而不是漏报;
它应该在字节码上操作;我们通常将整个classpath打包为一个war,并且可能没有源代码(特别是如果我们包括专有的第三方库);
另外,它可能包括用Groovy、Scala、Clojure编写的库;
Gadget Inspector
Gadget Inspector是一个为辅助挖掘Gadget链而生的Java字节码分析工具。
具有以下特点:
在任意给定的classpath上操作,即特定的库或整个war包;
将发现的Gadget链作为方法调用序列进行报告;
执行一些简单的符号执行,以理解从方法参数到后续方法调用的可能数据流;
简化了许多假设,使代码分析更容易;
原理步骤
Step1.枚举类/方法的层次结构
Step2.发现“透传”数据流
Step3.枚举“透传”调用图
Step4.枚举使用已知Tricks的Sources
Step5.在调用图上应用BFS算法关联链
反序列化库的灵活性
Gadget Inspector支持自定义分析规则。
- 什么被视为“可序列化”?
- 对于JRE反序列化,任何实现java.lang.Serializable接口的类;
- 对于XStream,这取决于启用的转换器;当使用定制转换器时,它会变得更巧妙;
- 对于Jackson,任何没有参数构造函数的类;
- 什么是反序列化源(即魔术方法)?
- 对于Jackson,我们只从构造函数开始;
- 我们应该关注哪些方法实现?
- 对于JRE反序列化,所有实现了可序列化类的类;
- 对于Jackson,取决于注释和配置;
提升空间
- 反射
- 大多数反射调用被视为有趣的,导致FPs。例如,可以控制类,但不能控制方法名,反之亦然;
- 调用图枚举盲点,
foo.getClass().getMethod("bar").invoke(…)
;
- 假设
- 即使是很小的改进,Gadget Inspector也可以围绕条件可满足性或虚拟方法调用解析做出更好的决策,从而减少FPs;
- 限制
- 使用“已知的Tricks”来列举入口点,最初的研究仍然可以帮助我们找到许多其他聪明的方法来构建Gadget链;
- 带有“有趣行为”的sinks是硬编码的,许多空间可以发现和添加sinks;
0x02 浅析Gadget Inspector源码
待补充…
0x0n 参考
Java 反序列化工具 gadgetinspector 初窥