PR - Fuzzing: a survey

原文作者:J Li, B Zhao, C Zhang

原文标题:Fuzzing a survey

原文链接:https://seclab.bu.edu/papers/cname_cloaking-asiaccs2021.pdf

原文来源:Cybersecurity

笔记作者:outx

介绍

​ 互联网和世界数字经济运行在一个共享的、关键的开源软件(OSS)基础设施上。单个库中的安全缺陷可能会产生严重后果。例如,OpenSSL实现了用于安全通信的协议,并被包括大多数HTTPS网站在内的Internet服务器广泛使用。早期版本的OpenSSL中的“心脏滴血”漏洞会泄露机密数据并造成巨大的经济损失。目前,fuzzing是这方面最有前途的技术之一,现阶段有三种主要的fuzzing技术:黑盒,灰盒和白盒fuzzing。

​ 黑盒fuzzing是在不了解程序内部构造的情况下产生输入的。其有两个主要的变种:突变型和生成型。在突变型黑盒fuzzing中,fuzzing从一个或多个种子输入开始。这些种子被修改以产生新的输入。随机突变被应用于输入中的随机位置。在生成型黑fuzzing中,输入是从头开始生成的。 如果提供了输入格式的结构规范,就会以此生成符合语法规范的新输入。Peach是一个流行的黑盒fuzzing工具。

​ 灰盒fuzzing往往会利用程序来获得轻量级的反馈,用于指导fuzzer的工作。通常来说,程序中的一些控制位置在编译时进行检测,并提供初始种子语料库。 种子输入被改变以产生新的输入。产生的输入覆盖了新的控制位置,从而增加了代码覆盖率,进而被添加到种子语料库中。覆盖率反馈允许灰盒fuzzing逐渐深入到代码中。为了识别错误和漏洞,清理程序会将断言注入到程序中。现有的灰盒Fuzzing工具包括AFL、LibFuzzer和Honggfuzz。

​ 白盒fuzzing技术是基于一种叫做符号执行的技术,它使用程序分析和约束解算器来系统地列举可能出现漏洞的程序路径。 在白盒fuzzing中用作后台的约束解算器是Satisfiability Modulo Theory(SMT)解算器,它允许对(无量子)一阶逻辑公式进行推理,其平等和函数/谓语符号来自不同的背景理论。白盒fuzzer会计算一个输入i的路径条件与i走过相同路径的输入集合。给定一个种子输入,计算并改变路径条件(与改变程序输入相反)。改变路径条件然后被发送到约束解算器以生成新的输入。这种技术的主要优点是其能够通过跟踪到目前为止的所有输入的路径条件,生成一个穿过新路径(新控制流)的输入。现有的白盒模糊工具包括KLEE和SAGE。

Fuzzing原理

Fuzzing的工作流程

​ 下图描述了传统Fuzzing的工作流程,由四个主要阶段组成,即测试用例生成阶段、测试用例运行阶段、程序执行状态监控和异常分析。

image-20210618145110707

​ Fuzzing是从生成一堆程序输入开始的,也就是测试用例。生成的测试用例的质量直接影响测试效果。输入应该尽可能地满足被测程序对输入格式的要求。而另一方面,输入应该足够碎片化,以便在图1的模糊测试工作过程中导致程序执行出现问题。根据目标程序,输入可以是不同文件格式的文件、网络通信数据、具有特定特征的可执行二进制文件等。如何产生足够多的测试用例是现阶段Fuzzing的主要挑战。一般来说,最先进的模糊器使用两种生成器,即基于生成的生成器和基于变异的生成器。测试用例在上一阶段生成后被送入目标程序。模糊器自动启动和完成目标程序的过程,并驱动目标程序的测试用例处理过程。在执行之前,分析人员可以配置目标程序的启动和结束方式,并预先定义参数和环境变量。通常情况下,模糊处理过程会在预定义的超时、程序执行挂起或崩溃时停止。Fuzzer会在目标程序的执行过程中监测执行状态,期待异常和崩溃。常用的异常监测方法包括对特定系统信号的监测、崩溃和其他违规行为。对于没有直观程序异常行为的违规行为,可以使用很多工具,包括AddressSanitizer、DataFlowsanitizer、ThreadSanitizer、LeakSanitizer等。当捕捉到违规行为时,Fuzzer会存储相应的测试用例,供后者回放和分析。在分析阶段,分析员试图确定捕获的违规行为的位置和根本原因。分析通常在调试器的帮助下进行,如GDB、windbg,或其他二进制分析工具,如IDAPro、OllyDbg等。二进制工具,如Pin,也可以用来监测收集的测试用例的确切执行状态,如线程信息、指令、寄存器信息等等。

Fuzzer的分类

​ Fuzzer可以以各种方式进行分类,主要分为基于生成的和基于突变的[8]。

​ 对于基于生成的Fuzzer,需要了解程序输入的知识。对于文件格式的Fuzzing,通常需要提供一个预先定义文件格式的配置文件。测试用例是根据配置文件生成的。有了给定的文件格式,由基于生成的Fuzzer生成的测试用例能够更容易地通过程序的验证,并更有可能测试目标程序的深层代码。然而,如果没有一个好的文件,分析文件格式是一项艰难的工作。因此,基于突变的Fuzzer更容易启动,也更适用。对于基于突变的模糊器,需要一组有效的初始输入。测试用例是通过初始输入的突变和Fuzzing过程中产生的测试用例产生的。下表中比较了基于生成的fuzzers和基于突变的fuzzers。

image-20210618145552977

​ 就对程序源代码的依赖性和程序分析的程度而言,Fuzzing技术可以被分为白盒、灰盒和黑盒。白盒可以接触到程序的源代码,因此可以通过对源代码的分析收集更多的信息,包括测试用例如何影响程序的运行状态。黑盒是指在不了解目标程序内部的情况下进行Fuzzing。灰盒测试在没有源代码的情况下也能工作,并通过程序分析获得目标程序的内部信息。下表中列出了一些常见的白盒、灰盒和黑盒fuzzer。

image-20210618145642592

​ 根据遍历程序代码的策略,可以将Fuzzer分为定向Fuzzing和基于覆盖的Fuzzing。有方向的Fuzzer旨在生成覆盖程序的目标代码和目标路径的测试用例,而基于覆盖的Fuzzer旨在生成覆盖尽可能多程序代码的测试用例。定向Fuzzing希望对程序进行更快的测试,而基于覆盖的Fuzzing则希望进行更彻底的测试,并尽可能地检测更多的错误。但对于这两种测试方法而言,如何提取执行路径的信息是一个关键问题。

​ 根据对程序执行状态的监控和测试用例的生成之间是否存在反馈,可以将模糊器分为无反馈Fuzzer和智能Fuzzer。智能Fuzzer根据收集到的信息调整测试用例的生成,即测试用例如何影响程序行为。对于基于突变的Fuzzer,反馈信息可用于确定哪部分测试用例应该被突变以及突变的方式。无反馈Fuzzer获得了更好的测试速度,而智能Fuzzer产生了更好的测试用例并获得了更好的效率。

Fuzzing中的关键挑战

​ 传统的Fuzzer在实践中通常采用基于随机的Fuzzing策略。程序分析技术的局限性导致了现在的状况,即Fuzzer不够智能。因此,Fuzzing仍然面临许多挑战。我们列出一些关键的挑战如下:

如何对种子输入进行突变

​ 基于突变的生成策略因其方便和容易设置而被最先进的Fuzzer广泛使用[9]。然而,如何变异并生成能够覆盖更多程序路径和更容易触发错误的测试用例是一个关键的挑战。具体来说,基于突变的Fuzzer在进行突变时需要解决两个问题:

  • 在哪里突变
  • 如何突变

​ 只有少数关键位置的突变会影响执行的控制流程。因此,如何定位这些关键位置是非常重要的。此外,Fuzzer对关键位置的突变方式是另一个关键问题,即如何确定可以将测试引向程序的有潜在危险路径的值。总而言之,盲目的突变测试用例会造成测试资源的严重浪费,而更好的突变策略可以显著提高模糊测试的效率。

低代码覆盖率

​ 更高的代码覆盖率代表了更高的程序执行状态覆盖率,以及更彻底的测试。先前的一些工作已经证明,覆盖率越高,发现问题的概率就越大。然而,大多数测试用例只覆盖了相同的几条路径,而大部分的代码逻辑却无法触及。因此,仅仅通过大量的测试用例生成和投入测试资源来实现高覆盖率并不是一个明智的选择。基于覆盖率的Fuzzer将在程序分析技术的帮助下解决这个问题,比如程序分析工具。

通过验证

​ 程序通常在解析和处理之前对输入进行验证。验证的作用是保护程序,节省计算资源,保护程序免受无效输入和恶意构建的输入所造成的损害。无效的测试用例总是被忽略或丢弃的。Magic numbers、Magic strings、版本号检查和校验是程序中常用的验证方法。黑盒和灰盒Fuzzer生成的测试用例很难通过生成策略的验证,这会导致Fuzzing处理的效率相当低。因此,如何通过验证是另一个关键挑战。

Fuzzing的新趋势

​ 作为一种自动检测漏洞的方法,Fuzzing已经显示出它的高效力和高效率。然而,正如第三节所述,仍有许多挑战需要解决。在本节中,我们简单介绍一下自己关于Fuzzing发展趋势的理解。

​ 首先,智能Fuzzing技术为Fuzzing的改进提供了更多可能性。在以前的工作中,传统的静态和动态分析被整合到Fuzzing中,以帮助改善这一过程。整体上来看已经有了一定的改进,但还是很有限。智能Fuzzing技术通过各种方式收集目标程序的执行信息,能够对Fuzzing过程进行了更精细的控制,并提出了很多Fuzzing策略。随着对不同类型漏洞的深入了解,并利用漏洞的特点进行模糊处理,智能模糊处理可以帮助发现更复杂的漏洞。

​ 第二,新技术可以在许多方面帮助改善脆弱性。机器学习和相关技术等这类新兴技术已经被用来改善模糊测试中的测试用例生成。如何将新技术的优势和特点与Fuzzing结合起来,如何将Fuzzing中的关键挑战转化或分割成新技术所擅长的问题,是另一个值得考虑的问题。

​ 第三,新的系统特征和硬件特征也不应该被忽视。根据前人的一些工作我们可以知道新的硬件特性能够极大地提高Fuzzing的效率。

小结

​ Fuzzing是目前最有效和最高效的漏洞发现方案。在本文中,我们对Fuzzing方法及其最新进展做了全面的回顾和总结。首先我们介绍了Fuzzing的基本原理和工作流程,然后我们介绍了Fuzzing的基本分类标准。同时,我们还介绍了Fuzzing在这些年的发展过程中遇到的问题和挑战。最后,我们总结了与Fuzzing相结合的技术,以及Fuzzing的应用和可能的新趋势。