模糊测试
-
Fuzzing或模糊测试是一种自动化的软件测试技术,通常用于识别程序中的潜在漏洞。对程序进行模糊测试是通过向其提供随机输入语句并记录导致程序中的崩溃或非崩溃的内存损坏的测试用例来完成的。在某种意义上,模糊测试就是通过蛮力搜索漏洞。几乎所有需要某种输入的软件都可以进行模糊测试,比如——浏览器,通过查看或编辑文件的应用程序,系统内核,大多数API和其他程序接口,驱动程序,网络守护程序,Web应用程序等等都可以对其进行fuzzing。
-
Fuzzing 是一种自动发现 bug 的方法; 理想情况下,Fuzzing 可以简单地在机器上运行并且不受干扰。 因为它不需要太多的手动交互,所以它可以是一种廉价的测试技术。另一方面,手工测试非常耗费资源,它揭示的错误数量取决于测试人员的技能。模糊测试和手动测试的结合是最佳的一种做法,因为这两种技术通常会发现不同类型的错误,并且它们可以互补。应用程序越复杂,就会有越多的 bug,随着复杂性的增加,攻击面也会增加。 对非常复杂的应用程序进行手工测试需要花费大量时间,并且需要良好的测试技能。 例如,如果一个公司决定只手动测试一个浏览器,那么在下一个版本完成之前,就需要很多技能熟练的测试人员来测试整个应用程序。一个fuzzer可以简单的永久运行并且可以在软件发布之前完成测试。 大多数fuzzer的规模相当不错,所以如果需要测试的更快,找到更多的bug,那么你可以只是增加更多的测试机器或更多的CPU内核。也可以使用 Fuzzing 回归测试来确保不会再次引入任何已知的 bug。
-
缺点:
模糊测试不能发现程序中的所有漏洞,所有模糊测试只能是对其他安全措施的一个补充。
模糊测试可以产生许多误报,无法利用的bug以及重复的结果。
-
优点:成本较低、效率较高,自动化,容易配置,是一种有效的软件测试方法
-
要开始模糊测试,你需要一个接受输入的目标。应用程序越复杂,就越有可能使用fuzzer找到bug。它可以是内部软件,也可以是第三方软件,这取决于你的测试用例。你需要考虑你想要捕捉的bug的类型。一个 fuzzer 需要知道什么时候它发现了一个 bug,所以最容易发现的 bug 是那些导致崩溃的 bug,因为这将表明一个潜在的安全漏洞。
-
理论上,通过模糊测试工具可以找到所有可能的 bug 类型。fuzzer需要一种检测机制来将程序的行为分类为无意的或恶意的。因此,有些 bug 的类比其他 bug 的类在代码中更容易找到,因为它们会产生明显的错误行为。例如,内存损坏bug在触发时导致崩溃是很容易检测到的。另一方面,逻辑错误可能非常难以检测,因为程序没有明显的不正常行为,而且预先定义检测逻辑错误的规则可能比较棘手。
-
一个典型的fuzzer由三个不同的部分组成。 一个测试用例生成器生成输入,输入到被测试的程序; 一个worker程序执行给定的输入,并识别意外的行为; 一个日志记录器记录有趣的测试用例以及分析 bug 所需的一切。大多数fuzzer还包括一个服务器或主机,它协调其他三个部分并管理它们之间的通信。
-
测试用例生成器主要负责创建新的测试用例。为了创建新的测试用例,它可以自己识别出输入的结构,这被称为智能fuzzer。相反,不知道输入结构的测试用例生成器被称为愚蠢fuzzer。测试用例可以从头开始生成,也可以从现有的测试用例中变异。复杂的fuzzer也可以将生成和变异结合从而生成测试用例。
-
由测试用例生成器创建的测试用例在质量上有很大的不同。因此,测试用例生成器需要某种指导来决定变更或生成哪些测试用例。最常见的启发式指导是代码覆盖率。理论上,代码覆盖的越多,模糊测试就能发现更多的错误。测试用例生成器可以配置为创建类似于发现新覆盖率测试用例的测试用例。与覆盖率导向的模糊测试类似,基本上所有与发现更多bug相关的指标都可以用作测试用例生成器的指导,例如数据流指导。
-
不需要输入结构模型来生成新测试用例的测试用例生成器称为愚蠢fuzzer。愚蠢fuzzer的优点是它不需要输入结构的信息,因此适合对很多不同的程序进行模糊测试而不需要太多的调整。使用愚蠢fuzzer的最大缺点是,大多数输入需要预定义的结构或包含校验和,fuzzer将很难生成有效的输入,因此主要是测试应用程序的解析代码。
-
与愚蠢fuzzer相反的是一个智能fuzzer,它的测试用例生成器能够理解输入文件的结构。输入文件的结构称为输入模型。例如,输入模型可以是编程语言的语法或数据格式模型。智能fuzzer的优点是它主要创建有效的输入文件,这将导致实际程序中更高的代码覆盖率。然而,一个智能fuzzer通常是高度专业化的特定类型的输入,它需要一个好的输入模型才能够创建测试用例,从而可能触发bug。