近期,国防科技大学网络空间安全系在软件缺陷检测方向取得新成果。团队深挖语法类程序的安全痛点,聚焦灰盒模糊测试技术在应用于语法类程序时的不足与缺陷,开展了针对语法类程序特点的灰盒模糊测试优化技术研究,最新的研究工作“从一个解析器中发现语法信息以增强所有基于解析器的应用程序模糊测试”被CISNS 2022接收。

题目

Discovering Grammar Information from One Parser to Enhance All Parser-Based Application Fuzzing

作者

Chen Chen, Bo Yu, Wenke Wang, Runhao Liu, Ke Yan

主要内容

模糊测试近年来发展迅速,但主要集中在没有专门解析阶段的程序上。具有结构化输入(例如XML和Tcl)的应用程序通常有一个专门的解析阶段来检查输入的有效性。此外,具有相同输入结构的不同应用程序在实现过程中会添加自定义语法规则,例如在 XML 中定义特殊的标签名称和标签层次结构。为了测试这些应用程序,利用输入结构的模糊测试器可以实现比传统模糊测试方法更高的代码覆盖率。然而,对于应用程序的自定义语法,现有的大多数解决方案都依赖于手动编写的语法文档和包含所有自定义语法的种子集。

国防科技大学的硕士生陈晨、刘润昊、燕珂在喻波副研究员、王文珂副研究员的联合指导下,提出了一种基于归纳的语法发现方法,并开发了一个通用的模糊测试引擎——FSFuzz。该引擎可以通过插桩语法解析器来自动化的发现目标程序的自定义语法,以使得模糊测试器适配所有使用了相同解析器的不同应用程序。FSFuzz分两步工作,其框架如图一所示。首先,它在解析器上执行轻量级检测以提取语法的特征。然后,它使用提取的特征对基于此解析器的所有应用程序进行模糊测试。

图一 FSFuzz引擎框架

A. 语法提取模块

他们观察到,由于每个语法解析器的解析过程都是固定的,因此可以通过跟踪解析器的动作来学习程序的语法。该方法避免了分析不同目标程序的复杂代码,而是分析一个通用的语法解析器,然后专注于那些在被认为是关键步骤中的语法检测语句。如图二所示是一款基于libexpat的应用层程序的典型XML解析代码,程序通常使用“XML_SetStartElementHandler”外部接口来设置用户回调函数,该函数将用于处理 XML 输入的所有开始标记。然后,通过记录这些回调函数执行过程中的上下文信息,可以自动收集到开始标签字符串上的所有约束。使用这种方法,我们可以反向推断程序的自定义语法,更重要的是,这种方法适用于所有使用libexpat的目标。

图二 基于libexpat解析器的应用程序代码片段

自动语法提取过程的算法如图三所示。首先,构造包含特殊标签名称的 XML 作为输入,使用 Pintool 运行目标二进制文件,并解析结果。这样就得到了所有顶级节点的标签名,并将它们添加到任务队列(第 4-8 行)。接下来,从任务队列中取出一个标签路径,构造一个包含路径上的前序节点的XML 字符串,并将特殊字符串的属性对添加到底部节点(第 10-11 行)。和以前一样,使用 Pintool 运行程序并分析结果以获得该节点的所有合法属性对(第 12-13 行)。为了严谨起见,他们将两个属性名称相同但属性值不同的节点放到不同的标签路径中。根据每个属性名称的合法值的数量,获得属性对的所有可能情况。接下来,程序遍历所有情况,使用 Pintool 来判断是否还有合法的子节点。如果不存在子节点,则认为找到完整的标签路径;否则,继续将子节点添加到任务队列(第 14-23 行)。最后,根据获得的所有标签路径生成合法的 XML 片段(第 25-28 行)。

图三 自定义语法提取算法

B. 语法引导的变异策略

为了使用收集到的语法片段来生成有效的测试用例,他们设计了一个在抽象语法树(AST)级别工作的语法引导突变。将测试用例转换为AST后,可以通过选择不同大小的子树来控制变异的范围,而不会破坏语法结构。FSFuzz使用ANTLR语言处理工具来执行转换。ANTLR根据目标结构的语法将文本转换为C++中的类对象,并提供访问接口。ANTLR 网站上有200多个描述不同结构的语法文件,可以直接使用。

图四展示了语法定向突变的过程。首先,根据目标结构(第2行)将测试用例转换为AST。但是,如果在转换过程中发生任何错误,这意味着测试用例的格式不正确,则跳过突变(第3-5行)。这是正常的,因为测试用例是由破坏结构的其他突变策略产生的。如果转换成功,则迭代AST的所有子树并记录其在文本中的位置(第6行)。接下来,遍历之前生成的语法片段列表,在记录的位置替换原始文本,并将替换结果作为新的测试用例(第7-11行)。最后,获得了一个新测试用例列表(第13行)。

图四 语法引导的变异算法

图五显示了对Tcl测试用例的变异过程。左边是初始测试用例。其中,以节点2为根的子树代表一个命令,节点6代表一个命令名。假设引擎记录了这个的位置,并想用语法片段替换它,那么会在右边得到一棵新树。正如图中展示的那样,它是一个结构良好的Tcl脚本,并从语法片段中获取新的“pllightsource”命令,这将触发额外的功能代码。

图五 语法引导的变异策略示例

为了评估FSFuzz在实际程序中的有效性,引擎在两个基于libexpat解析器的XML程序和两个基于Tcl Interpreter解析器的Tcl程序上进行了对比试验。结果表明,FSFuzz能够自动发现所有 278 个自定义语法关键字,并且与其他成熟的现有工具(AFL和Superion)相比,FSFuzz显著提高了代码覆盖率(行覆盖率分别为25%和21.5%,分支覆盖率分别为23.2%和20.4%)。

声明:本文来自ipasslab,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。