【网络安全研究进展系列】APICRAFT:闭源SDK库的模糊测试驱动生成

编者按:2022年5月,由网络安全研究国际学术论坛(InForSec)汇编的《网络安全国际学术研究进展》一书正式出版。全书立足网络空间安全理论与实践前沿,主要介绍网络和系统安全领域华人学者在国际学术领域优秀的研究成果,内容覆盖创新研究方法及伦理问题、软件与系统安全、基于模糊测试的漏洞挖掘、网络安全和物联网安全等方向。全书汇总并邀请了近40篇近两年在网络安全国际顶级学术议上发表的论文(一作为华人),联系近百位作者对研究的内容及成果进行综述性的介绍。从即日起,我们将陆续分享《网络安全国际学术研究进展》的精彩内容。

本文论文原文“APICraft: Fuzz Driver Generation for Closed-source SDK Libraries”发表于Usenix Security 2021,作者是Cen Zhang,Xingwei Lin,Yuekang Li,Yinxing Xue,Jundong Xie,Hongxu Chen,Xinlei Ying,Jiashui Wang,Yang Liu,来自南洋理工大学,蚂蚁集团,中国科学技术大学。

一、摘要

模糊测试驱动是构建模糊测试库的必要条件。模糊测试驱动是一种通过模糊测试工具提供的输入来执行库函数的程序。在实践中,模糊测试驱动是手动编写的,驱动的质量取决于编写者的技能和知识。为了减轻手动工作量并确保测试质量,业界提出了用于自动生成模糊测试驱动的不同技术。然而,现有技术大多依赖于源代码的静态分析,这使得闭源SDK库的模糊测试驱动生成成为了一个尚待解决的问题。闭源库的模糊测试驱动生成主要面临两大挑战:

■ 仅可从库中提取有限的信息;

■ API函数之间的语义关系复杂,但仍需要保证其正确性。

为了应对上述挑战,我们提出了一种自动化模糊测试驱动生成技术——APICRAFT。APICRAFT的核心策略是收集-组合。首先,APICRAFT利用静态和动态信息(头文件、二进制文件和轨迹),以切实可行的方式收集API函数的控制和数据依赖关系。然后,它使用多目标遗传算法将收集到的依赖关系进行组合,并构建高质量的模糊测试驱动。我们将APICRAFT作为模糊测试驱动生成框架,并使用macOS SDK中的5个攻击面对其进行评估。在评估过程中,APICRAFT生成的模糊测试驱动表现出比手动编写更出色的代码覆盖率,使代码覆盖率平均提高了64%。我们进一步用APICRAFT生成的模糊测试驱动开展了长期的模糊测试活动。经过8个月左右的模糊测试,我们目前已在macOS SDK中发现了142个漏洞,并被分配了54个CVE,这些漏洞可能会影响到Safari、Messages、Preview等热门的苹果产品。

二、背景

自20世纪90年代引入模糊测试以来,它已经成为从业者和研究人员最常用的漏洞检测技术之一。AFL、libFuzzer和Honggfuzz等最先进的模糊测试工具已在实际使用的数百个软件程序和库中检测出了16000多个漏洞。

若要对某个程序执行模糊测试,模糊测试工具需要找到可以提供输入的入口点。若要对某个库执行模糊测试,模糊测试工具需要将使用该库的某个应用程序作为入口点。这种应用程序被称为模糊测试驱动,亦称为模糊测试夹具。在实践中,模糊测试驱动主要由安全分析师手动创建,模糊测试驱动的质量取决于编写者的技能和知识。因此,创建有效的模糊测试驱动往往是一项颇具挑战性的耗时任务。

为了解决模糊测试驱动生成问题,研究人员提出了FUDGE、FuzzGen等技术。这些技术利用调用库的现有消费者应用程序源代码来合成模糊测试驱动。一方面,消费者应用程序的源代码提供了正确的API用例,这对模糊测试驱动来说十分重要;另一方面,对源代码的需求限制了这些技术在闭源SDK库中的使用。尽管如此,鉴于闭源SDK库的普及程度和市场主导地位,其安全性不容忽视。以Preview为例,在macOS SDK中不同文件解析库的支持下,它可以显示各种类型的文件。由于Preview预安装在每台苹果台式/笔记本计算机上,相关库中的漏洞可能会影响数百万普通用户。总之,闭源SDK库的模糊测试驱动生成是一个尚未进行充分研究的重要问题。

闭源SDK库的模糊测试驱动生成主要面临以下两个挑战。

■ 第一个挑战是仅可从库中提取有限的信息。由于缺失库源代码,因此我们很难提取出合成模糊测试驱动所需的正确API用法。更糟糕的是,消费者程序往往是闭源的,如Preview。由于存在一些臭名昭著的陷阱,如间接函数调用,因此在没有源代码的情况下,我们无法准确提取库API的控制流和数据流信息。

■ 第二个挑战是API函数之间的语义关系很复杂,但又需要保证其正确性。为了触发库中的深层代码,测试驱动就必须包含语义正确的API调用序列。事实上,不仅API调用组合的搜索空间巨大,API调用序列的语义正确性也很难保证。

为解决上述挑战,我们提出了APICRAFT,回答了“要提取哪些信息”和“如何利用这些信息”这两个问题。图1说明了APICRAFT的整体结构。

从根本上讲,APICRAFT将目标SDK及其消费者应用程序作为输入,并生成模糊测试驱动作为输出。APICRAFT使用自下而上的方法来合成模糊测试驱动,可以将其描述为一种收集-组合方法。这种方法包含两个主要阶段。第一阶段是收集目标SDK库中API函数之间的依赖关系。在此阶段中,APICRAFT将目标SDK的消费者应用程序的执行轨迹作为参考来确定API的正确使用。APICRAFT不会收集所有数据依赖关系和控制依赖关系,因为这种做法不切实际,因此,APICRAFT只收集与错误处理相关的API函数间数据依赖关系和控制依赖关系。第二阶段是将收集到的API函数依赖关系组合起来,以构建具有期望属性(如紧凑性和依赖多样性)的模糊测试驱动套件。由于期望属性可能相互冲突,因此APICRAFT使用基于多目标遗传算法的策略来优化整个模糊测试驱动种群,以满足一组预定义的目标。

图1

我们将APICRAFT作为一个框架,用来为闭源SDK生成模糊测试驱动套件,并进行彻底地评估。我们使用来自macOS SDK的5个攻击面评估了APICRAFT生成的模糊测试驱动。我们在实验中发现,生成的模糊测试驱动在代码覆盖率(在24小时内平均增加64%的基本块)和独特崩溃次数(在24小时内平均增加12次独特崩溃)方面都优于人工编写的模糊测试驱动。此外,我们使用生成的模糊测试驱动开展了长期模糊测试活动。到目前为止,macOS SDK中已检测到142个漏洞(54个CVE),这些漏洞影响了一些知名的商用现成产品,如Safari、Preview等。

我们的贡献可概括如下。

■ 我们确定了为闭源SDK生成模糊测试驱动的主要挑战,并提出了收集-组合方法。

■ 我们开发了第一个用于闭源SDK的自动模糊测试驱动生成框架APICRAFT,它展示了测试实际应用程序的能力。

■ 我们在macOS SDK上评估了APICRAFT,并发现了142个以前未知的漏洞。我们负责任地披露了这些漏洞,并帮助供应商修复它们。

为了方便未来的研究,我们发布了APICRAFT的源代码和生成的模糊测试驱动。

三、路线图

1.实例

考虑以下情境:Jane是一名安全分析师,她的任务是对macOS SDK中的一个闭源库(如CoreText库)进行模糊测试,她将如何执行该任务?Jane首先需要弄清楚库的功能。在这个例子中,CoreText是一个字体渲染库。然后,她将尝试找到一个使用该库的程序,以查看该程序是否符合作为模糊测试驱动的条件。她可能会发现Messages和Safari正在使用该库。不幸的是,这些应用程序也是闭源的,并且在执行过程中涉及大量的GUI交互,这意味着它们不适合用作模糊测试驱动。因此,Jane必须为CoreText创建自定义模糊测试驱动。

我们假设,Jane不想从文档中学习,而是想通过学习现有消费者应用程序如何使用库函数来创建模糊测试驱动。由于CoreText库的消费者应用程序几乎都是闭源的复杂商业软件,我们很难通过反汇编和静态分析来提取库函数的正确用法。或者,Jane可以使用消费者应用程序的执行轨迹来推断调用库函数的正确序列。从这个意义上说,Jane可以根据每个执行轨迹构建一个微小的消费者应用程序。假设Jane已经获得了两个消费者应用程序,如图2所示。在CoreText中,Font是一种不透明类型,用于保存已解析的字体数据。它可以从用原始字体数据(data)创建FontDescriptor或DataProvider中提取。CoreText用Font对象可以进行很多操作,如计算字形的前导空间(CalcLeadingSpace)或加倍前导空间(DoubleLeadingSpace)。

图2 

一旦Jane收集了有关CoreText正确使用的知识,下一步就是使用这些知识来构建模糊测试驱动。基于消费者应用程序生成的潜在模糊测试驱动套件(带有虚线边框的矩形),如图3所示。每个圆圈代表图中的一个函数。每个圆圈链代表一个模糊测试驱动(由函数调用组成)。

图3

自然地,从执行轨迹中分割的两个消费者应用程序可以用作模糊测试驱动,如图3(a)所示。然而,Jane很快注意到,由于覆盖的程序行为缺乏多样性,直接分割的模糊测试驱动并不理想。在此示例中,函数ExtractFont作为连接Font存根的创建及其使用的支点。具体来说,CalcLeadingSpace 和DoubleLeadingSpace都将Font对象作为输入。因此,Jane可以交换这两个函数来创建具有新函数组合的模糊测试驱动。图3(b)显示了根据支点交换函数后生成的模糊测试驱动。尽管包含比分割模糊测试驱动更多的API函数组合,但交叉生成的模糊测试驱动仍然很不理想,具体表现如下。

■ 部分API函数组合仍然缺失。例如,DoubleLeadingSpace和CalcLeadingSpace都使用ExtractFont的结果。它们可以组合成一个模糊测试驱动并触发更多程序行为,而不是相互替换。在这种情况下,如果先执行DoubleLeadingSpace,CalcLeadingSpace可能会遇到整数溢出错误。

■ 有些组合是多余的。例如,图3(b)中引入的两个新组合并没有真正触发更多的程序行为。原因在于,程序使用Font对象的方式通常不受其生成方式的影响,调用CreateFontDescriptor或ProviderCreateWithData将最终生成相同的Font对象。总之,通过交叉构建的模糊测试驱动套件缺乏多样性和紧凑性。但是,在大多数情况下,这两个所期望的属性是独立的,并且可能会相互冲突。

因此,要构建一组符合期望的模糊测试驱动,就需要平衡不同的目标(如紧凑性和多样性)。

现在,Jane意识到从执行轨迹中明确提取的模糊测试驱动需要改进,并且在提高模糊测试驱动的质量方面存在一些陷阱。她也许可以将所有分割的模糊测试驱动分解为函数之间的依赖关系,然后将这些依赖关系组合起来以重建可以实现多个独立目标的新模糊测试驱动。经过一些推理和反复试验,Jane最终意识到使用消费者应用程序生成,符合期望的模糊测试驱动应该如图3(c)所示,因为这些模糊测试驱动很紧凑,但可以触发最多样化的程序行为。这标志着整个过程的结束。

事实上,在APICRAFT中,我们系统地将整个推理和这个故事的试错过程描述为算法,并且可以自动生成图3(c)所示的,符合期望的模糊测试驱动。

2.概述

我们提出了用于为商业SDK库自动生成模糊测试驱动套件APICRAFT。APICRAFT的工作流程如图4所示,包含3个主要阶段。

图4

(1) 在预处理阶段,APICRAFT通过多种分析(即头文件分析、静态二进制分析和动态二进制分析)从多个来源提取目标SDK的信息并进行分组。它输出一组库的元数据和消费者程序的执行轨迹。

(2) APICRAFT从预处理的输出中收集数据依赖关系和控制依赖关系。对于数据依赖关系,APICRAFT主要关注API函数间的数据依赖关系。对于控制依赖关系,APICRAFT旨在识别并收集用于错误处理的函数输出。

(3) APICRAFT应用多目标遗传算法将收集到的依赖关系组合到模糊测试驱动中,并促使生成的模糊测试驱动达到所期望的属性。

(本文选取了文章部分章节,更多精彩内容请阅读《网络安全国际学术研究进展》一书。)

作者简介

张岑,南洋理工大学博士研究生,他的主要研究方向包括虚拟化安全和模糊测试。他在包括USENIX Security、ACM CCS、ASE等顶级期刊发表过相关论文。

林性伟,蚂蚁安全光年实验室安全研究员,他的研究领域包括虚拟化安全、macOS&Windows系统安全、程序分析和Fuzzing。他曾在学术界以及工业界顶级安全会议上发表论文与演讲,包括ACM CCS、USENIX Security和BlackHat Asia。他获得过来自苹果、QEMU、微软和Oracle等厂商的致谢。

版权声明:本书由网络安全研究国际学术论坛(InForSec)汇编,人民邮电出版社出版,版权属于双方共有,并受法律保护。转载、摘编或利用其它方式使用本研究报告文字或者观点的,应注明来源。

Bookmark the permalink.

Comments are closed.