2017-A Review of Fuzzing Tools and Methods

1 介绍

识别软件漏洞的技术首先可以分为两种不同的方法:静态分析和动态分析。软件的静态分析涉及检查源代码或编译的二进制文件而不执行它的方法。动态分析涉及在运行时检查软件,通常在附加某种调试器之后。
静态分析虽然有用,但通常会产生许多在实践中无法利用的误报,并且需要大量的手动验证工作来确定哪些问题是真正的漏洞。但是,它确实允许在检查整个应用程序时实现完整的代码覆盖率。
这种方法有很多优点,因为自动化的易用性,并且能够测试代码审查过于耗时的非常大的应用程序。

2 软件漏洞

3 漏洞检测

3.1 静态分析

静态代码分析(SCA)技术通常涉及对应用程序源代码的检查或对已编译的二进制代码的反汇编。重要的一点是,被检查的软件没有被执行[72]。静态地分析源代码或二进制代码可以覆盖完整的代码。完全可以检查整个程序。这样做的缺点是,经常会标记出用户在运行时无法触及的问题。从安全的角度来看,这些错误并不重要,因为它们无法被利用。因此就有了分类的问题;通常需要对大量的漏洞进行排序,以识别出安全研究人员感兴趣的一小部分漏洞[69]。在不了解运行时环境的情况下,一些漏洞无法被检测或理解,因此在静态分析期间不太可能被检测到。静态分析的另一个潜在问题是,如果不同时分析这些库,目标程序导入的第三方库中的漏洞就会丢失。这些问题在我们稍后将讨论的模糊处理中都不存在。
一些比较流行的免费静态代码分析工具包括Cppcheck[33]和用于查找C/ c++源代码漏洞的FlawFinder[31],用于PHP的RIPS[29],以及用于Java的FindBugs[13]。流行的商业解决方案可以处理多种编程语言的软件,包括VeraCode[14]和Fortify[15]。有些工具是独立的,而其他工具(例如FindBugs)可以集成到常见的开发环境(如Eclipse或Visual Studio)中。
SCA工具依赖于各种方法来识别潜在的漏洞。在这个范围的最简单的一端是那些本质上只是搜索特定函数名或黑名单中的其他事件的工具。FlawFinder工具[31]就是这样工作的。该工具有一个C/ c++函数数据库,这些函数与缓冲区溢出、格式字符串问题、竞争条件和其他已知问题有关。这些被列入黑名单的函数在源代码中出现时,工具会将其标记,并向用户提供每种情况下可能存在的漏洞的解释。开发人员在[30]中描述的Jslint工具,通过检查12个安全编程最佳实践的遵从性来检测Java源代码中的漏洞。这类工具对于发现“容易实现的目标”很有用,但不太可能发现更复杂的问题。
一个更复杂的技术是污染分析,RIPS[29]使用了这种技术,在测试Java应用程序时也在[34]中进行了讨论。在这个过程中,首先要把用户可以修改的每一段输入标记为“源”,并把任何这样的输入数据标记为“受污染的”。从这种受污染的输入中获得的任何数据也受到了污染。受污染的数据流可以通过程序进行静态跟踪,每当看到它到达一个危险的函数,标记为“sink”,这个事实就会被标记。然后可以检查这种情况,以确保在数据到达洗涤槽之前进行了充分的处理。污点分析也被应用到模糊处理中,我们将在后面讨论。

3.2 动态分析

主要缺点是难以获得完整的代码覆盖率,执行全面测试所需的时间长度,以及我们只能检查由一组有限输入而不是所有可能的输入产生的应用程序状态的事实

4 模糊

4.1 Instrumentation

当没有源代码可用时,通常使用动态分析工具,如Valgrind [36], DynamoRIO[75]或PaiMei[37]。还可以简单地附加一个如IDA Pro[79]的调试器来检测目标何时崩溃。这些工具都可以将自己附加到一个已经运行的流程上,并动态地添加工具。
Valgrind运行在Linux上,包含自己的内存错误检测器和两个线程错误检测器[76]。这允许在fuzzing期间使用它来检测内存损坏,即使它没有导致程序崩溃。DynamoRIO既可以运行在Windows上,也可以运行在Linux上,可以用来提取代码覆盖信息以及其他很多东西[75]。PaiMei是一个反向工程框架,它也可以通过Pstalker模块[37]来监控Windows应用程序的代码覆盖,Flayer是一个建立在Valgrind之上的工具,可以在运行时进行污染分析[77]。当对没有源代码可用的目标进行探测时,所有这些工具都可以用于检测需求。
如果源代码可用,则可以在编译时添加插装。例如,在Linux系统上,AddressSanitizer工具允许检测内存错误,如缓冲区溢出和在应用程序编译时添加“after-free”[68]。如果在执行Asan仪器化程序期间的任何时候检测到任何内存损坏,程序将被终止,并将记录崩溃跟踪,并自动诊断发生了什么。这有两个好处。通常不会导致程序崩溃的漏洞将被检测到,此外,为了修复问题或开发漏洞,将通过Asan提供的数据进行进一步调查。
一些fuzzers,特别是AFL(美国Fuzzy Lop),在编译时[41]添加了他们自己的自定义仪表。这允许模糊器在每个测试用例执行期间从目标应用程序获得精确的反馈。未来测试用例的创建可以基于这个反馈。这种基于进化的模糊在4.3节中有更深入的解释。

4.1.1 代码覆盖率
度量代码覆盖率有三种常见的方法;线路、分支和路径覆盖[71]。

4.2 文件格式和协议模糊测试

大多数模糊器要么是文件格式模糊器,要么是协议模糊器。

4.3 测试用例综合

有三种主要方法可以创建测试用例或输入以用于模糊测试活动;突变,生成和进化[71,99]。
进化模糊测试本身可以细分为三个常见的近似方法:基于覆盖,基于污染和符号辅助模糊。
基于覆盖范围的进化模糊测试尝试演进测试用例,从而导致在目标中执行新的行、分支或路径。执行新代码的测试用例优先于不执行新代码的测试用例。AFL 执行文件格式突变模糊测试,因此最初使用有效输入文件的示例进行种子设定。然后,它测量每个测试用例的代码覆盖率,并使用遗传算法[108]来进化出覆盖最大代码量的测试用例群体。
基于污点的进化模糊试图演化出执行特定已知危险代码路径的测试用例。而不是简单地以最大的代码覆盖率为目标,目标是发展将用户输入传播到程序中的特定目标函数的测试用例[96]。污斑分析既可以作为一种静态技术预先进行,也可以在模糊过程中进行动态分析。
符号辅助的进化fuzzing结合了符号执行[82]和fuzzing,试图享受两者的优势。与基于覆盖率的模糊化一样,它在生成新测试用例时的目标是增加代码覆盖率。然而,尽管基于覆盖的fuzzing可以监控代码覆盖,并通过某种形式的尝试和错误来增加它(甚至使用遗传算法也属于这一类),但符号辅助的fuzzing走得更远。测试用例使用动态符号执行引擎进行修改,以做出已知的导致执行之前未揭示代码的特定段的更改[83]。一个符号辅助的模糊器的例子是SAGE(可伸缩自动引导执行),这是一个专有工具,微软内部使用它来搜索他们自己的软件[1]中的漏洞。
在[88]中记录的TaintScope fuzzing工具将动态污染分析与动态符号执行相结合,因此不仅能够定位目标的危险区域,而且能够说明如何制作输入,以便fuzzing会话能够到达这些区域。Confuzzer在[106]中采用了类似的方法。

4.4 模糊测试网页浏览器

当对Web浏览器进行模糊测试以查找漏洞时,通常将重点放在渲染引擎上[44,57]。浏览器的这一部分负责获取构成网页的HTML文档,CSS和图像,并将它们转换为向用户显示的内容。呈现引擎解析 HTML 和 CSS,然后使用 DOM(文档对象模型)API 从中构造树结构。然后,脚本语言(如 JavaScript)可以通过DOM API 调用与呈现的文档进行交互,以在客户端对其进行更改,而无需进一步连接到 Web 服务器。目前使用的流行渲染引擎包括EdgeHTML,Trident,Gecko,WebKit和Blink(本身就是WebKit的分支)[47]。渲染引擎是查找可利用的 UAF(释放后使用)漏洞的常用位置 [56]。
有两种方法可以模糊浏览器的渲染引擎;文件格式模糊和DOM模糊。文件格式fuzzing方法只需要简单地应用变异或生成技术,我们已经研究过这些技术来创建畸形的网页,并将这些技术作为输入提供给浏览器。因此,这是应用一种通用的模糊方法,并使用与用于模糊PDF阅读器或视频播放器相同的方法。
DOM fuzzing方法应用了特定于web浏览器的技术[44,59],这些动作是由浏览器自己通过JavaScript执行的。有许多变化,但一个典型的方法是爬行测试用例文档的DOM树,并收集元素引用。然后可以修改元素的属性,也可以删除随机的DOM节点。也可以对集合而不是单个DOM元素执行突变。DOM树可以以各种伪随机的方式重新排列。然后以某种方式触发垃圾收集,并重复此过程[59,60]。这可能导致发现和触发各种内存损坏。
从文档树创建逻辑视图也可以作为DOM模糊处理的一部分完成,因为它迫使呈现引擎在发生变化时试图保持逻辑视图和DOM之间的一致性。此活动还可能导致内存损坏bug被触发并暴露在[59]中。
DOM fuzzing工具通常在生成测试用例以有效地再现崩溃时存在问题。典型的DOM fuzzing工具通过从数组中随机选择HTML标记并调用文档来构建DOM树。与每个createElement。JavaScript中内置的PRNG (Math.random)经常被使用,它不能被显式地指定一个已知的值。然后,脚本对DOM树进行了一些突变(通常也涉及到Math.random的使用),这可能会导致崩溃,如果浏览器没有崩溃,脚本将重新加载页面并重新开始。这可能会持续几个小时,直到浏览器最终崩溃。当浏览器崩溃时,没有特定的测试用例来重现崩溃。这与将一系列变异的HTML文件加载到web浏览器形成对比,在浏览器中,任何崩溃都可以立即追溯到精确的测试用例。

4.4.1 现有的浏览器模糊测试工具
最早的浏览器模糊工具是由Michal Zalewski在2004年发布的Mangleme[89]。这个工具是生成畸形HTML页面的一代模糊器。它是用C语言实现的,并部署成一个编译好的CGI程序,运行在web服务器上。通过在要测试的web浏览器中导航到CGI程序的URL,页面会反复刷新,每次都会处理不同的HTML测试用例。测试用例的生成是通过引用一个包含所有可能的HTML标记和每个标记的所有属性的二维数组来完成的。通过选择随机标签并从数组中添加随机属性,同时在整个页面中散布一些随机字符和字节,可以构造出畸形的HTML页面。整个工具由大约200行c组成。尽管这个工具很简单,但它发现了当时所有主流web浏览器的严重漏洞。
Metasploit项目的HD Moore在2005年和2006年参与了两个浏览器模糊器的发布。Hamachi是一种通过改变其元素、属性和属性来模糊动态HTML (DHTML)的工具[91]。CSSDIE被用于模糊CSS,并作为2006年7月“浏览器bug月”的一部分发布[92]。这两种工具都在当时所有主流浏览器中发现了漏洞。不幸的是,它们如何工作的精确细节和它们的源代码似乎都不再可用。
另一个CSS模糊器简单地称为“CSS语法”是由Jesse Ruderman[55]在2009年发布的。这是一个用JavaScript编写的generation fuzzer,包含了一个用于级联样式表的上下文无关语法[93]。用户可以扩展语法(甚至可以替换语法,以便针对其他语言),还可以为语法中的不同符号分配权重,以影响它们在测试用例中出现的规律。与Mangleme[89]一样,这个生成的fuzzer遵循用于创建大多数测试用例的语法,但也会抛出随机符号,并进行其他更改以产生稍微不太正常的输入。这个工具被用来发现Gecko渲染引擎中的几个bug。
Radamsa是一种通用突变模糊器,由奥卢大学安全编程小组(OUSPG)的研究人员开发。尽管它是一种通用的模糊器,但正如文献[100]所述,它已经被有效地用于针对web浏览器。Radamsa使用模型推理辅助fuzzing,也就是说,它试图基于给出的初始测试语料库中的有效输入建立自己的输入模型。然后,它使用这个模型来应用突变,这些突变很可能足够有效,能够被目标正确处理,而不是立即被视为无效而拒绝。这使得模糊器能够增加测试的深度,同时仍然不要求用户提供一些有效的输入样本。
Crossfuzz是由Michal Zalewski [48]于2011年发布的DOM模糊器。该工具的工作原理是"跨多个文档动态生成极其冗长的DOM操作序列,检查返回的对象,重归到其中,并创建对垃圾收集机制进行压力测试的循环节点引用"。该工具是用JavaScript编写的,可以从文件系统加载到Web浏览器中,也可以通过将其托管在Web服务器上来加载,与CSS Grammar工具相同。在任何一种情况下,JavaScript 都在浏览器中执行以执行 DOM 操作的顺序。该工具在2010年和2011年期间在所有主要的Web浏览器中发现了许多漏洞[90]。
LangFuzz 是 2012 年用于模糊测试解释器的工具,它采用上下文无关语法 [93] 作为输入,以及一套有效示例程序的测试套件和以前被认为会导致目标应用程序中错误的附加程序语料库。n工具结合了突变和生成模糊测试的各个方面。它使用语法来解析测试套件和以前的崩溃,然后将崩溃代码片段重新组合到测试套件中以创建新程序,以尝试发现新问题[58]。对于 example,该工具用于模糊 Mozilla JavaScript 引擎,为它提供描述 JavaScript 的上下文无关语法、JavaScript 测试套件以及以前在 Mozilla 引擎中导致错误的 JavaScript 程序集合。 LangFuzz从中新生成的JavaScript程序在3个月内发现了105个新漏洞[58]。LangFuzz可以应用于任何编译器或解释器,而不是专门针对模糊测试与Web浏览器相关的技术。它成功地通过其JavaScript解释器在Firefox浏览器中发现严重漏洞,因此值得在这里包含。
Grinder于2012年发布,是一个分布式框架,用于支持大规模模糊测试Windows Web浏览器[95]。它由在集中式Grinder服务器上运行的Web应用程序以及执行实际模糊测试的任意数量的Grinder节点组成。作为一个框架,其目的是为诸如记录崩溃,提供检测,崩溃重复数据删除,根据需要重新启动浏览器和相关功能而不是模糊测试本身等问题提供简单的解决方案。用户必须提供自己的用于创建测试用例的模糊测试程序。这种框架的价值在于,它让研究人员专注于如何创建良好的测试用例,而不必担心所有其他问题。
GramFuzz由中国的研究人员于2013年开发[8]。他们的工作研究了使用HTML,CSS和JavaScript测试用例对Web浏览rs进行模糊处理时,将生成和突变模糊模糊的技术相结合。该工具使用网络抓取从互联网获取网页语料库,然后从中构建语法树。然后,语法用于创建语料库的突变,这些突变可能足够正确,可以被浏览器的JavaScript解释器接受,而不是像纯突变模糊测试方法那样立即被拒绝。这与我们之前看到的Radamsa采取的方法非常相似。在测试期间,GramFuzz在Firefox和Internet Explorer中发现了36个新的严重漏洞。
DOMfuzz [51] 和 Jsfunfuzz [52] 是 Mozilla 在 2013 年底和 2014 年初发布的两款模糊测试器。DOMfuzz采用突变和生成技术的混合来执行DOM模糊测试。它需要 pa ges 的初始语料库,然后应用诸如通过移动节点来重新排列 DOM 树之类的技术。Jsfunfuzz 是用于测试 JavaScript 引擎的生成模糊器。它通过生成和执行随机的JavaScript函数体来工作。因此,与使用LangFuzz执行的JavaScript模糊测试不同,它不采用初始语料库,而是完全依赖于生成。
NodeFuzz是2014年发布的模块化跨平台浏览器模糊测试工具[53,56]。它解决了许多与Grinder相同的问题,但它是用Node编写的.js并且是独立于平台的。用户需要提供自己的测试用例创建模块以及自己的检测模块。因此,如有必要,这些可以特定于正在测试的确切浏览器。编写用于NodeFuzz的popular测试用例创建模块是Wadi [50]。它于2015年在Defcon 23上发布,并提供了创建模糊DOM的JavaScript测试用例的功能。语法用于生成语法正确的随机 JavaScript 例程,这些例程在执行时作用于 DOM,并且每次都会使用其中的脚本生成 HTML 测试用例。该模块旨在使用Asan作为检测内存损坏的工具测试Firefox和Chromium。
最后,ShakeIt是2015年发布的一款突变模糊测试工具,用于浏览器模糊测试框架[57]。该程序获取有效网页的语料库,并从中提取令牌。然后,它会在这些页面中相互交换随机令牌,以创建新的测试用例。Memory 损坏错误可以以这种方式暴露出来,因为渲染引擎试图理解在无效位置或以无效顺序查看有效令牌。
这绝不是所有现有浏览器模糊测试工具的完整列表,但它确实有助于突出多年来尝试的典型功能和方法。可以看出,虽然模糊测试研究总体上对测量和增加代码覆盖率给予了不可忽视的关注,但在浏览器特定的模糊测试工具上所做的工作似乎并没有将此作为优先事项。还可以看出,当一个堆叠的Web浏览器时,有一种趋势是专注于生成模糊测试,一个值得注意的例外是将 Radamsa 应用于浏览器所做的工作[100]。[100]中的工作证明,现有网页语料库的突变可能是浏览器模糊测试的成功方法,并且如果已经完成工作以确保 初始语料库的最大代码覆盖率,它可能会更加成功。

5 结论

本文回顾了一些最值得注意的学术文献和实践工作,已产生的模糊领域。我们首先检查了软件中的漏洞是如何出现的,以及安全研究人员是如何发现它们的。在简要概述了静态分析的常见漏洞类型和方法之后,我们深入研究了模糊化领域。从简单的随机输入到使用遗传算法和污染分析,对不同的模糊方法进行了研究。研究了度量代码覆盖率对评估模糊运动完整性的重要性。最后,重点是web浏览器的模糊测试以及与之相关的特定工具和技术。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值