基本信息
原文名称:ODDFUZZ: Discovering Java Deserialization Vulnerabilities via Structure-Aware Directed Greybox Fuzzing
原文作者:Sicong Cao;Biao He;Xiaobing Sun;Yu Ouyang;Chao Zhang;Xiaoxue Wu;Ting Su;Lili Bo;Bin Li;Chuanlei Ma;Jiajia Li;Tao Wei;
原文链接:https://ieeexplore.ieee.org/document/10179377
发表期刊:2023 IEEE Symposium on Security and Privacy (SP)
开源代码:https://github.com/ODDFuzz/ODDFuzz(暂时关闭)
一、引言
Java反序列化漏洞在实践中严重威胁。研究人员提出了静态分析解决方案来定位候选漏洞和模糊解决方案,以生成概念验证 (PoC) 序列化对象以触发它们。然而,现有的解决方案的有效性和效率有限。
在本文中,我们提出了一种新的混合解决方案ODDFUZZ来有效地发现Java反序列化漏洞。首先,ODDFUZZ执行轻量级静态污点分析,以识别可能导致反序列化漏洞的候选小工具链。在这一步中,ODDFUZZ试图定位所有候选链并避免假阴性。
然后,ODDFUZZ执行有向灰盒模糊(DGF)来探索这些候选链,并生成PoC测试用例来缓解误报。具体来说,ODDFUZZ采用结构感知种子生成方法来保证测试用例的有效性,并采用一种新的混合反馈和步进策略来指导有向模糊。
我们实现了一个ODDFUZZ的原型,并在流行的Java反序列化数据集ysoserial上对其进行了评估。结果表明,ODDFUZZ可以发现34个已知小工具链中的16个,而两个最先进的工具只识别其中3个。
此外,我们在包括Oracle WebLogic Server、Apache Dubbo、Sonatype Nexus和Protostuff在内的现实应用上评估了ODDFUZZ,发现了6个以前未报道的可利用的小工具链,分配了5个CVE。
一、概述
ODDFUZZ的基本框架如下图所示,主要由两部分组成:
(1) 识别模块:污点分析模块,可疑小工具链存储模块;
(2) 验证模块:种子生成模块,模糊测试模块,种子优先选取模块,前向变异模块;
ODDFUZZ以被测程序的编译文件(如Jar、War或Class文件)为输入,进行轻量级污点分析,自动枚举所有潜在的小工具链。在验证模块中,ODDFUZZ基于识别的小工具链生成结构感知种子,构建语法有效的注入对象进行模糊测试。
在模糊测试中,ODDFUZZ结合了步骤前向突变策略和混合反馈(种子距离和小工具覆盖),以指导模糊器将注入对象突变到所需的接收器。当生成的注入对象达到目标的调用站点时,给定的小工具链将报告为可利用的小工具链。
图1 ODDFUZZ流程概述图
三、污点分析
1. 方法摘要统计
ODDFUZZ首先计算PUT类路径上的所有方法的静态摘要,然后用于构建小工具链。
对于每个方法,ODDFUZZ会首先提取它所有的参数还有this关键字作为方法摘要。然后跟踪每个方法中变量的传播,专注其中有四个基本语句:分配(assign),加载(load),存储(store),调用(call)。这四个基本语句被广泛的运用于污点分析的数据流计算中。这些方法摘要会被用来识别哪些有能被攻击者使用的利用链。
2. 利用链识别
由于小工具链是指一系列方法的调用,它反映了从魔术方法到目标调用站点的堆栈跟踪,ODDFUZZ应该具体说明哪些是可利用的魔术方法和目标调用站点,并根据先前计算的方法摘要识别可疑的小工具链。在本文中,我们共指定了 16 种魔术方法和30 种目标调用站点。
图2 列出的魔术方法(源)与目标调用站点(汇)
这里展示了收集的16种魔术方法与30种目标调用站点,其中这些敏感的调用站点可用于执行远程代码执行(RCE)、JNDI注入(JNDIi)、系统资源访问(SRA)和服务器请求伪造(SSRF)攻击。
为了避免因为广度优先搜索造成忽略可利用链产生假阴性的后果,ODDFUZZ一旦找到前面所归纳的魔术方法,便会用深度优先搜索算法寻找利用链。
同时,为了避免递归调用这种产生无限循环的情况,ODDFUZZ会对候选小工具链,设置一个最大长度。此外,为了解决java语法的多态性,用类分层分析(CHA)在调用被污染的地方执行,以此来避免造成路径爆炸。如:r = x.k(a,...) 如果x被污染,所有关于k被重载的方法都被列入候选小工具链。其余情况,会是如同一般的基于调用图的污点分析工具一样。
四、结构感知的灰盒引导fuzz
1. 结构化种子生成
构建语法有效的注入对象要求:
(1)对象嵌套结构要能够反应给定小工具链的执行流程。
(2)每个对象要分配合适的属性值。这种复杂的结构嵌套要求模糊测试的种子构建需要精心构建。这对于传统的模糊测试是不友好的。
因此,构建一个分层的数据结构叫做属性树(property tree)。其中根节点,表示一个类对象有一个或多个小工具。叶节点,表示这个类包含的属性类型、名称字段。如图3所示,为了生成注入对象,我们实例化小工具链中涉及的每个类,并利用反射动态收集每个类的可用属性以构建属性树。
具体来说,如果属性树中字段节点的属性类型是由类持有目标链中下一个小工具的另一个属性树表示(或继承)的对象,我们通过将这个字段节点连接到其对应的类对象节点(即另一个属性树的根节点)来合并这两个属性树。值得注意的是,当属性树中某个字段节点的类型是另一个属性树的根节点(类对象)实现的接口时,也会合并两个属性树。
图3 对于生成的注入对象构建的一个合并的属性树
2. 基于混合反馈的种子的优先选择
因为在运行过程中,对于这种嵌套注入对象,每次变异的差异很大。这意味着随机生成和变异的一个注入对象可能会找不到最终的目标。而且,对于这种对象属性嵌套的情况,很容易让构造的注入对象在注入中失去语义,模糊测试就会把大部分时间用在探索在不可达的路径上,造成效率低下。因此,本文提出一个混合反馈的的方法,目标是希望距离调用点更近的种子能获得变异更多的资源。
图4 基于混合反馈的种子选择相关算法
ODDFUZZ用种子距离与小工具覆盖作为反馈进行种子优先选择的两种指标。
(1)种子距离:沿着AFLGo与Hawkeye的思想由图4中(1)式可得种子距离d(s,Tb),其中s是种子,Tb是目标基本块,m是基本块,ξ(s)为种子s的执行轨迹,该轨迹包含行使的基本块。˜d(s,Tb)定义为s到Tb的种子距离和之前任何种子s′∈S到Tb的最小种子距离之差除以任何种子s′∈S到Tb的最大和最小种子距离之差。
(2)小工具覆盖:我们还采用小工具覆盖(即目标链中小工具的分支覆盖Ψ(s))作为另一个指标,以优先考虑覆盖更多程序路径的种子。在初始模糊测试阶段,小工具覆盖旨在引导模糊测试工具选择和优先考虑不同的种子,避免因为偏爱具有特定执行路径的某些种子导致陷入局部最优解。然后在功率调度阶段,小工具覆盖试图给出距离相同但覆盖更多的分支的种子,以便有更高的突变机会。
(3)然后会生成两个不同队列。第一个队列按照生成距离最小,但是小工具覆盖分支不同的种子进行存储。第二个队列按照距离不同依次升序排列种子。在功率调度阶段,会利用图4中的公式(2)综合考虑种子的种子的距离,小工具覆盖来为每个选取的种子输入分配合适的能量。p(s,Tb)值处于[0,1]这个区间。
3. 前向种子变异
以前的模糊测试技术通过bit翻转等操作随机突变二进制文件以产生新输入来工作。然而,当应用于结构化输入时,这种bit级突变可能会导致无效的语法错误。为了解决这个问题,我们利用JQF,这种模糊测试框架进行测试。JQF将结构化输入映射到一系列无类型的bit上(即参数),以在bit级别变异生成的种子。这些参数上的bit级突变对应于结构化注入对象的属性级突变。
首先对于要变异的属性树,检查它的属性类型。对于原始数据(如Boolean,int)类型,用JQF伪随机。对于引用(reference)数据类型,会为它准备专门的模板。对于class类型,会用random.choose()选择一个候选类。对于array类型,会用random.nextInt()方法来随机设置array大小,会根据元素类型,随机给数组分配值。
图5 关于前向变异的一个例子
如图5上一行可以看到queue[0]是个对象数组,会调用nextInt(),choose()方法来变异。
此外,为了引导种子朝向期望的目标站点,ODDFUZZ在感兴趣的对象上bit级逐个变异因此我们会在random.nextBool()方法里加入额外标识字节。当遇到一个类对象的时候,会给一个标识字节,来确定是否改变它的属性值。对于某个对象卡在利用路径的某个位置时,将标识改为true,然后对对象进行结构变异。
图6 ODDFUZZ的主要fuzz循环过程
五、实验设计及结果
(一)具体实现
我们基于现在流行的Java模糊测试平台 JQF[1] 实现了ODDFUZZ。我们定制了它的组件,使其适用于小工具链模糊测试,同时承载 JQF 的底层功能。
1. 污点分析
ODDFUZZ使用Soot[2]将Java字节码解析为中间语言Jimple[3]。基于 Jimple 的基本类信息(例如类修饰符、字段、方法和指令),我们实现了基于方法摘要的污点分析。
2. 结构化模糊测试
ODDFUZZ不是手动编写输入格式的声明性规范,如上下文无关语法或协议缓冲区,而是修改JQF中内置的junit-quickcheck生成器[4],以随机生成和变异基于候选小工具链的结构化注入对象。为了实现和促进结构感知种子生成,我们采用了JRE 提供的 sun.msic.Unsafe类[5],允许用户在不调用其构造代码、初始化代码、各种 JVM 安全检查以及所有其他底层相关的情况下创建类实例。
3. 运行时插桩
我们使用 ASM tookit[6]通过javaagent 实时检测 Java 字节码。当测试程序开始时,ODDFUZZ插桩工具注入静态方法调用,在每次调用或跳转指令之后执行,以跟踪注入对象的执行跟踪。请注意,为了提高效率插桩仅限于小工具链相关的字节码,而不是整个程序。
4. 反馈收集
对于覆盖信息,我们对 JQF 做了最小的修改,通过基于跳转指令插桩每个基本块来收集分支覆盖。对于距离信息,ODDFUZZ根据ASM在字节码级别生成小工具链的相应过程内控制流图(CFG)。CFG 的根节点(即小工具)由方法签名识别,而其他 CFG 节点由相应基本块的跳转指令识别。当小工具链被反馈到模糊器进行验证时,ODDFUZZ距离计算器根据小工具链和生成的CFG的调用顺序计算每个基本块的有风险的目标的过程间距离。距离计算器使用 JGraphT[7]库实现。
(二)实验设置
首先,文中测量了ODDFUZZ对小工具链识别的有效性,并演示了ODDFUZZ的结构感知种子生成和语义感知模糊测试引导如何有助于触发可利用的小工具。
然后,我们将其性能与最先进的自动化小工具链识别工具(GadgetInspector[8],SerHybrid[9])进行比较,包括开源工具和之前的研究。最后,我们展示了 ODDFUZZ 可以在流行的 Java 应用程序中发现以前未知的漏洞。
我们基于 ysoserial[10]对各种小工具链进行了评估,这是一个在 22 个常见的 Java 库中发现的 34 个已知小工具链的集合,可用于执行不安全的对象反序列化。
(三)具体实验
1. 实验一:对ODDFUZZ有效性的探究
1)总体性能:为了评估ODDFUZZ的有效性,我们重复了每个实验10次,并报告了它们的平均统计性能。我们根据经验将每个小工具链的阈值设置为 15 个小工具。对于每个静态识别的小工具链,我们将ODDFUZZ的模糊活动限制为120秒。
总体而言,在 22 个 Java 库中,ODDFUZZ 静态识别了 34 个已知小工具链中的总共 20 个,并为这些链中的 16 个动态生成的接收器可达注入对象,没有误报。结果表明,ODDFUZZ在发现Java ODD小工具链方面的有效性。
表1 ODDFUZZ发现小工具链数量实验结果
2)结构感知种子生成的影响:为了评价结构感知种子生成的效果,实现了一个禁用属性树生成功能的ODDFUZZ-SU进行比较。同样,进行10次实验。
由表2可以得到ODDFUZZ中结构感知种子生成对模糊测试的结果有明显的正向影响。
表2 ODDFUZZ与ODDFUZZ-SU性能比较实验结果
3)反馈驱动的fuzzing引导的影响:为了研究对于反馈驱动的fuzz引导的影响,与原版ODDFUZZ做了三个区别,一个是随机变异即禁用了前向引导变异(RM),一个是禁用了距离这个参数(DG),一个是禁用了小工具覆盖这个参数(CG)。然后,这些不同版本的ODDFUZZ进行10次实验。
由表3,我们可以观察到,在几乎所有小工具链中,ODDFUZZ发现比ODDFUZZ-RM、ODDFUZZ-DG和ODDFUZZ-CG更多的有效分支。
表3 ODDFUZZ与ODDFUZZ的(RM)、(CG)、(DG)三个版本
性能比较实验结果
2. 实验二:ODDFUZZ与现在流行的工具进行比较
该实验的比较对象为GadgetInspector和SerHybrid。比较指标为:能够静态分析识别的小工具链、能够通过ysoserial确定可利用的链和分析时间。
ODDFUZZ与GadgetInspector和SerHybrid比较结果如下表4所示。总体而言,ODDFUZZ在所有应用中都取得了显著的性能改进。特别是,ODDFUZZ 报告了 34 个可利用的小工具链中的 16 个,没有误报,包括 13 个无法通过基线找到的独特小工具链。
相比之下,GadgetInspector 和 SerHybrid 报告的真正可利用的小工具链的数量分别为 3 和 2。
表4 ODDFUZZ与GadgetInspector和SerHybrid比较的实验结果
1) ODDFUZZ与GadgetInspector比较:GadgetInspector 平均需要 41 秒来分析每个应用程序并报告 116 个可疑小工具链。然而,其中只有三个是可利用的,这意味着其中 97.4% 是误报。其中的原因有两点:一是GadgetInspector在静态分析中,有精度问题。二是GadgetInspector没有考虑JAVA运行时的多态性。
2) ODDFUZZ与SerHybrid比较:如表4所示,SerHybrid 平均在两分钟内成功地证实了两个可利用的小工具链。尽管 SerHybrid 具有良好的性能,但 SerHybrid 的一个主要缺点是遗漏了大部分(34 个中的 32 个)可利用的小工具链。
3. 实验三:ODDFUZZ的漏洞发现
首先,ODDFUZZ选择的项目应是Java项目。第二,要存在已知的反序列化入口点。第三,ODDFUZZ的目标应该包括不同的应用领域。
根据这三个要求,我们选择了四个目标 Java 应用程序,包括Oracle WebLogic Server(商业应用程序服务器)、Sonatype Nexus(仓库管理器)、Apache Dubbo(高性能远程过程调用 (RPC) 框架)和 protostuff(Java 序列化库),以证明ODDFUZZ在实际场景中的漏洞发现能力。
由表5中发现DDFUZZ已经成功地检测到了6个以前未知的Java ODD漏洞。虽然其中三个是在 Oracle WebLogic Server 中找到的,但其余三个漏洞分别来自 Sonatype Nexus、Apache Dubbo 和 protostuff。这些漏洞可用于通过构建我们新发现的小工具链来执行 RCE 攻击。
表5 通过ODDFUZZ找到的未发现的反序列化漏洞
六、局限及不足
ODDFUZZ的局限性以及可能的解决方法如下所示。
1. 静态分析的局限:
ODDFUZZ实现的轻量污点分析,在可靠性与精度存在问题。同时,ODDFUZZ现在非常依赖已经存在的利用链作为先验知识。
2. 种子生成策略的局限:
对对象结构的感知有助于提高小工具链模糊测试的性能。然而,最优的生种子成策略需要适用于不同的反序列化场景,并且可能根据小工具链的构建而改变。
3. 最终结果利用的局限:
现在ODDFUZZ只是生成的注入对象,能最终调用目标位置的方法。以后希望能够检查这个利用链能否被攻击者控制。如果能被控制,如何把现在最后诸如只是弹个计算器这种指令改成危险的指令。
七、总结
在本文中,我们提出了一种新的混合解ODDFUZZ来有效地发现Java反序列化漏洞。ODDFUZZ执行轻量级静态污点分析来识别候选小工具链,并应用结构感知的定向模糊来缓解误报。结果表明,ODDFUZZ可以发现34个已知小工具链中的16个,而两个最先进的工具只识别其中3个。此外,我们发现了六个以前未报告的可利用的小工具链,其中五个已分配给 CVE-ID
参考文献
[1] R. Padhye, C. Lemieux, and K. Sen, "JQF: coverage-guided propertybased testing in java," in Proceedings of the 28th ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA). ACM, 2019, pp. 398–401
[2] Soot, 2022, https://soot-oss.github.io/soot/.
[3] R. Vallee-Rai and L. J. Hendren, "Jimple: Simplifying java bytecode for analyses and transformations," 1998.
[4] P. Holser, "junit-quickcheck: Property-based testing, junit-style," 2014.
[5] The Unsafe Class: Unsafe at Any Speed, 2022,
https://blogs.oracle.com/ javamagazine/post/the-unsafe-class-unsafe-at-any-speed.
[6] ASM, 2022, https://asm.ow2.io.
[7] JGraphT, 2022, hhttps://jgrapht.org/.
[8] I. Haken, "Automated discovery of deserialization gadget chains," inProceedings of the Black Hat USA, 2018.
[9] S. Rasheed and J. Dietrich, "A hybrid analysis to detect java serialisation vulnerabilities," in Proceedings of the 35th IEEE/ACM International Conference on Automated Software Engineering (ASE). IEEE, 2020, pp. 1209–1213.
[10] YSoSerial, 2022, https://github.com/frohoff/ysoserial.