PANGOLIN: Incremental Hybrid Fuzzing with Polyhedral Path Abstraction
Remarks
Conference: S&P 2020
Full Paper: https://qingkaishi.github.io/public_pdfs/SP2020.pdf
Summary
- 针对的问题:尽管目前已经有不少针对混合模糊测试的研究,但在很多情况下混合模糊测试依旧是低效的。
- 目前的解决方案:目前的混合模糊测试技术基本上是将符号执行和模糊测试简单结合,约束求解技术本身非常昂贵,但在实际使用时缓存和重用的计算结果很少,从而失去了很多优化的机会。此外约束求解也没有对fuzzing起到导向作用。
- 提出的创新方案概述:作者提出了渐进式(incremental)fuzzing的概念,即计算了程序执行中前部分路径约束的多面体路径抽象,以指导向嵌套路径中的的模糊测试过程。作者还利用已求解的路径约束来测试用例,同时提升了符号执行阶段和Fuzzing变异阶段的效率。
- 实验效果:PANGOLIN相比目前state-of-the-art的模糊测试技术能提升10%-30%代码覆盖率。在LAVA-M数据集里面,PANGOLIN能比目前state-of-the-art的模糊测试技术多发现500+的bugs。此外,这项工作还在真实世界的程序中发现了41个新bug,并申请了8个CVE IDs。
Introduction
混合模糊测试结合了符号执行与模糊测试的优点,已经逐渐成为覆盖导向模糊测试技术的重要发展方向之一。尽管在实现高覆盖率方面取得了巨大进展,但众所周知,混合模糊仍然存在效率问题。例如,当覆盖率低于20%时,Driller分析coreutils可能会导致超过100倍的运行时开销。如下图所示,目前混合模糊测试中所使用的约束求解技术非常昂贵,已求解的约束没有被有效的重用,并且对Mutation也没起到导向作用。
我们已经观察到,造成这种缺陷的一个重要原因是,就目前的混合模糊技术而言,混合模糊测试在嵌套路径约束的更深层次上并不是渐进的/递增的,因为很少有已探索过状态在伴随执行和变异的连续时期被保留和重用。然而,直观地说,已经探索过的状态空间应该能为搜索下一个状态空间提供很好的指导。如下图所示,如果将约束求解后对信息重用起来,是有可能实现Constrained Mutation和Guided Constraint Solving,从而提升效率。
Motivating Example
以下图中的程序为例,早期的符号执行可以生成满足第3行的条件语句的种子输入(v=20;w=5;x=3;y=4;z=30)。在fuzzing阶段,将随机变异此种子,以探索第4行和第8行的嵌套分支。这是效率低下的,因为即使有污点分析的帮助,在这个例子中,它确定只需要对z进行变异,在第3行满足约束0<z<200的概率仍然很低,因为z覆盖整个整数域。相反,如果变异算子不仅保留了第3行谓词的种子,而且保留了第3行的解区间,即x ∈ [3;3];y ∈ [4;4];z ∈ [0;200),那么通过第3行的第一个分支并专注于探索第4行和第8行的分支应该快得多。
同样的低效也发生在符号执行阶段。嵌套的分支条件一起设置并发送到约束求解器。显然,在这个示例中,封闭路径约束,例如x == 3 && y == 4 && z*z < 40000,是重复求解的,例如,在第4行和第8行。结果,随着模糊化过程在嵌套分支中越来越深,符号执行变得更加缓慢。但是,如果我们用解区间x ∈ [3;3];y ∈ [4;4];z ∈ [0;200]替换封闭路径约束,约束解算器就很容易找到新约束z>195的第4行的新种子。
Approach
下图为PANGOLIN的主要工作流程。PANGOLIN本质上是一种混合模糊技术。它与传统混合模糊技术具有相同的组成部分(符号执行组件和模糊测试组件)。不同的地方在于PANGOLIN会对约束求解器求解过的值进行重用,可以提升约束求解的效率。另一方面重用约束求解的结果可以指导fuzzing中的mutation。
多面体路径抽象(Polyhedral Path Abstraction)
在这项工作中,作者使用“路径抽象”的概念来表示路径约束的近似值。在现有的文献中,人们研究了许多不同的抽象概念,如区间(Interval)、八边形(Octagon)和多面体(Polyhedra)。如下图所示,区间抽象只包含每个变量的值范围。八边形抽象的形式是k1x+k2y <= b,其中x和y是路径约束中的变量。多面体抽象的形式更一般。在下图中,黑点表示满足给定路径约束的所有可行值,而十字表示不可行的值。路径抽象是由表示多个线性不等式的线所包围的区域。
推断多面体路径抽象
PANGOLIN首先在fuzzing中识别未被发现的分支,并将它们传递给conolic执行引擎。与传统的混合模糊算法中通过调用约束求解器直接获得可行解的混合执行不同,PANGOLIN构造了这些未发现分支的摘要,我们称之为多面体路径抽象。多面体路径抽象描述了可行输入相对于路径约束的合理搜索空间,用于指导种子的变异,加快后续路径约束的求解。
基于约束导向的Mutation策略
由于多面体路径抽象使得输入变量相对于路径前缀的路径约束有一个有界的范围,通过从这样有界的搜索空间中采样,PANGOLIN能够快速生成大量仍然满足该路径约束的新输入,同时,探索共享相同路径前缀的后续路径。具体来说,在这项工作采用了一种现有的采样技术(即Dikin-walk算法)来生成新的输入。这种抽样方法保证了新输入均匀地覆盖给定的搜索空间,保证了程序状态搜索的多样性。在对输入进行采样之后,PANGOLIN仍然保持离线多面体路径提取,以用于连续的模糊测试阶段。多面体路径抽象是对我们目前所解决的路径约束的解空间的简洁而合理的记忆,它使用前面的路径约束作为前缀,极大地简化了下一代路径约束的求解。
Evaluation
实验主要针对以下三个研究问题设计,文本省略了部分实验结果:
- RQ1: Can PANGOLIN detect more bugs in comparison with the state-of-the-art fuzzers?
- RQ2: Can PANGOLIN achieve higher coverage rate in comparison with the state-of-the-art fuzzers?
- RQ3: How effective are the path-abstraction-guided mutation and constraint solving?
在LAVA-M数据集上的实验结果,右图可以看出发现的bug数量增长速度明显快于QSYM。
下图列出了PANGOLIN相比目前state-of-the-art模糊测试技术的覆盖率变化(24小时内)。
研究案例
本文挑选了一个有趣且有代表性的bug来阐述PANGOLIN的设计直觉。如下图所示,示例包含一个缓冲区溢出漏洞(CVE-2017-9038),该漏洞与传递到第16行的变量ppool和ncols有关。第11-13行的清理可以过滤大多数(但不是全部)可能触发该漏洞的格式错误的输入。因为覆盖一个分支并不意味着我们可以触发一个漏洞,所以触发错误的输入需要满足一个非常复杂的路径约束来覆盖该分支,同时还要满足溢出约束。由于求解复杂约束的代价很高,而且随机变异也很难产生满足复杂错误触发约束的输入,因此QSYM等传统方法无法检测到它。
本文的方法可以利用第11行之前路径的多面体抽象来加速约束求解过程,从而快速覆盖易受攻击的分支。在覆盖分支之后,PANGOLIN利用约束变异来产生能够到达脆弱分支的各种输入,从而具有很高的触发错误的概率。评价结果表明,PANGOLIN很快就成功地检测到了该虫。