一个引擎来模糊测试所有:使用语义验证的通用语言处理器进行模糊测试(一)

36 篇文章 65 订阅
1 篇文章 0 订阅

One Engine to Fuzz ‘em All: Generic Language Processor Testing with Semantic Validation 一个引擎来模糊测试所有:使用语义验证的通用语言处理器进行模糊测试(一)

本文发表在2021 IEEE安全与隐私研讨会(SP ,第一作者为来自佐治亚理工学院 Yongheng ChenIEEE Symposium on Security and Privacy(简称 S&P)是信息安全领域四大顶级学术会议之一,始于1980年,今年是第42届。S&P 2021共录取107篇论文

 

 

摘要

编译器和解释器这种语言处理器,在构建现代软件的过程中是不可缺少的。语言处理器中的错误,比如不正确的功能实现,甚至是针对语言处理器的恶意代码攻击等,都会导致严重的后果。然而,使用自动化检测技术来检测语言处理器中的bug并非易事。现有的测试方法(模糊测试 fuzzers)要么不能产生出高质量的(即语义解析正确的)测试用例,要么只支持有限的编程语言范围。

本文提出了POLYGLOT,一个通用的模糊测试框架,目的是为了探索不同编程语言的处理器而生成高质量的模糊测试用例,实现各个语言之间的通用性和适用性。POLYGLOT中和了各个编程语言在语法和语义上的差异,使用了统一中间语言(IR)表示。为了提高语言的有效性,POLYGLOT执行了有约束的变异和语义验证,以确保语法的正确性,以及具备能够修复语义错误的功能。目前已经应用了9种编程语言的21种流行的语言处理器,识别出了173个新的bug,并获得了18个CVE漏洞编号,其中113个bug已经被修复。实验表明,POLYGLOT可以支持广泛的编程语言,并且在代码覆盖率方面比现有的fuzzers提高了百分之三十。

1.介绍

语言处理器,例如编译器和解释器,对于构建现代软件是必不可少的,它们把高级语言编写的程序翻译成硬件可以理解和执行的低级机器码。语言处理器的正确性保证了源程序和编译后的目标代码语义的一致性。而错误的语言处理器可以把正确的程序翻译成错误的代码,这样可能会导致安全漏洞的产生,例如,有关内存安全的程序的错误编译会产生内存不安全的二进制文件。

然而,传统的软件测试技术要自动检测语言处理器中的错误并不容易,因为处理器对其输入的语法和语义有效性有严格的要求。程序中的任何错误都可能终止语言处理器的执行,并阻碍测试人员对其代码深层的逻辑分析。

当前业界使用的软件测试工具,如灰盒模糊,试图有效地测试语言处理器。起初,对于结构不敏感的突变很难生成语法正确的测试用例;高级别的 fuzzers在抽象语法树(AST)或中间表示(IR)中采用更高层次的变异来保持输入结构。或者,基于生成器的fuzzers利用一个精确的模型来描述输入结构,因此可以从头生成语法正确的测试用例。为了进一步提高语义的正确性,近期的一些fuzzers普遍采用了对特定语言的高度专业化分析。

但是,对于一种特定语言,fuzzers将失去其通用性和适用性。 用户不能简单地利用专门的fuzzer来测试不同的编程语言,但必须以此来处理另一种编程语言。 考虑到不同编程语言特定功能的复杂性(例如,CSmith 80K行代码组成)和大量编程语言类型,实现特定的fuzzer去自定义每一个编程语言是不切实际的。 这是目前的fuzzers所面临的困境:追求高有效性的语义,就牺牲了它们的通用性,同时保持正常的通用性、适用性却无法保证测试用例的正常获取。

在论文中,作者提出了一个模糊测试框架POLYGLO,该框架可以生成语义上有效的测试用例,用来广泛测试不同编程语言的处理器。要实现其通用性和适用性,作者设计了统一的中间语言IR去中和不同编程语言之间的语法和语义的差异。 鉴于语言的BNF(巴科斯范式)语法,POLYGLOT会生成将源程序语言转化为此中间语言IR的前端语言。 同时,用户可以提供语义注释,以便对语言的定义范例以及类型,进行特定语义的注释。 该定义包括变量的范围,功能和复合类型。 在论文中,可以互换地使用变量和相关定义。 这些注释将在IR前端语言中产生语义属性。 例如,在C语言中的巴科斯范式中的 <func  := ret-type func-name arg-list func-body> 作者可以提供一些诸如“func defines a new function”“func-body creates a new scope”这类注释。 通过这种方式,不同的编程语言在中间语言IR中进行解释性的统一。

为了实现编程语言的高有效性,作者开发了两种技术,分别用于生成测试用例的约束变异和语义验证。 约束变异保留了变异测试用例的语法结构,有助于保持其语法的正确性。 此外,它试图维护未生成测试用例部分的用例语义正确性。例如,它避免了在C语言中,如果语句中的其它部分使用x,如果对语句“int x = 1”进行突变, 就会出现未定义变量的错误。由于保留了测试案例的语法正确性,并且未变异的传统部分语义正确性仍然有效,因此唯一要解决的是:固定突变部分的潜在语义,其中的误差需要下一步的修复。突变的部分可以引出语法错误,因为它可能会引入无效的变量。 要修复这些错误,作者可以根据范围和类型的规则替换这些无效变量,例如,作者的突变程序P仅定义两个变量即可,只要可以插入语句“unKnownVar + 1;” 。假设设定num的类型为整数,arr 的类型为数组,即应该使用num替换unKnownVar,因为其值加1,就要求变量具有整数类型。语义验证利用IR的语义属性,要收集测试用例中变量的类型和范围信息,并将其集成到符号表中。这些符号表描述了每个变量的类型,使用范围和其名称。然后,语义验证会利用它们的突变代码。以此来替换有效的变量,以缩小代码中的有效性,从而使得语义的正确性。

作者用7016c++python代码实现了POLYGLOT,这些代码专注于IR生成、受限制的突变和最终的语义验证。POLYGLOT目前支持9种编程语言,可以很容易地将其应用到其他语言中。

作者评估了POLYGLOT在使用21个主流的编译器和解释器中的9种不同的编程语言,成功地发现了173个新bug。在写论文的时候,113bug已经被修复了,并获得了18cve。作者的实验表明POLYGLOT相比于当前最先进的通用型fuzz:包括基于变异的fuzzer AFL以及混合型fuzzer QSYM和基于语法的fuzzer Nautilus能够更有效地生成高质量的测试用例(100个的语言有效性的改善)、探索程序的状态、(多于30个新路径)并且检测出了漏洞(8个更为特殊的bug)

作者还比较了POLYGLOT与特定语言的测试工具,比如C语言的CSmithJavaScriptDIE。最终的比较结果显示出POLYGLOT可以探索更多的程序状态:

  • 提出的通用型框架,可以产生高质量的输入来测试不同的语言处理器。
  • 实现了系统的原型,POLYGLOT可以有效地测试了语言处理器。
  • 评估了9个编程语言的21个语言处理器,并确定发现了173个新的bug。目前作者已发布POLYGLOT1的源代码。

总结:

针对论文的前一个章节,做了简单翻译,有错误之处还请指出。论文从当前常用的模糊测试工具所存在的问题出发,提出了POLYGLOT。由于语言处理器中存在的bug可能会将正确的源代码转换为故障代码导致安全漏洞。作者将POLYGLOT用于针对9种程序语言的21个语言处理器发现了173个新的bug其中18个获得了CVE113个已得到修复,成果显著。在后续的文章中,将会着重介绍和分析作者提出的POLYGLOT模糊测试框架,以及它对模糊测试所带来的新变化。

Ref

https://www.youtube.com/watch?v=tcTbXr8zf-Y  

https://www.computer.org/csdl/proceedings-article/sp/2021/893400b217/1t0x95QZOEg

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值