分享自:

FreeWill:通过二进制引用计数错误检测自动诊断释放后使用漏洞

期刊:31st USENIX Security Symposium

在USENIX安全研讨会(USENIX Security Symposium)这一顶级学术会议上,2022年8月,来自中国科学院软件研究所可信计算与信息保障实验室(TCA / Institute of Software, Chinese Academy of Sciences)、宾夕法尼亚州立大学(Pennsylvania State University)、中国科学院大学网络空间安全学院(School of Cyber Security, University of Chinese Academy of Sciences)以及新加坡国立大学(National University of Singapore)的研究团队,发表了一篇题为《FreeWill:通过二进制程序上的引用计数错误检测自动诊断释放后重用漏洞》的学术论文。本研究聚焦于软件安全领域一个长期且棘手的核心问题——释放后重用(Use-After-Free, UAF)漏洞的自动化根因诊断。

学术背景与动因 内存安全漏洞,尤其是UAF漏洞,一直是操作系统、浏览器等大型复杂软件系统中严重且普遍的安全威胁,每年都有数百个新漏洞被披露。尽管已有众多技术方案致力于预防或检测UAF漏洞的发生,但自动化诊断一个已报告的UAF漏洞(即找出其根本原因以便修复)仍然极具挑战且耗时费力。现有的诊断方法通常仅能报告漏洞对象分配或释放的位置,无法为开发者提供足够信息来理解漏洞根源或合成正确的补丁。

研究团队通过对大量真实世界UAF漏洞的分析,发现了一个常见的根本原因:引用计数错误(Reference Miscounting)。在依赖引用计数(Reference Counting)管理对象生命周期的程序中,如果开发者在创建新引用(如指针赋值)时忘记增加对应的引用计数器(Reference Counter),可能导致对象被过早释放,使得其他引用变为悬空指针,进而触发UAF。这种错误可分为两类:错误省略(本该计数的引用被错误地优化掉了)和不一致的减少(只有减少操作而没有对应的增加操作)。由于引用计数操作的复杂性和大量存在的性能优化性省略,自动化诊断此类问题面临巨大挑战,尤其是在仅有二进制程序的情况下。

因此,本研究的目标是开发一种自动化方法,能够高效诊断UAF漏洞是否由引用计数错误引起,并精确定位错误的引用计数位置,甚至提供补丁建议。该方法无需源代码,适用于现实世界的大规模程序。

详细的研究工作流程 FreeWill作为实现该方法的工具,其工作流程包含四个核心组件:UAF对象生命周期识别、引用分析、引用计数检测和UAF诊断。

1. UAF对象生命周期识别: 首先,给定易受攻击的程序和一个可触发漏洞的概念验证(Proof-of-Concept,PoC)输入,FreeWill通过动态插桩(扩展了QEMU模拟器,对于命令行程序也支持PinTool)收集触发漏洞的执行轨迹(Trace)和运行时信息(如堆分配、崩溃点)。执行轨迹平均包含超过1.3亿条指令,体积约24GB。 若源代码可用,则利用AddressSanitizer(ASan)识别UAF对象的生命周期(分配与释放时间点)。若仅有二进制程序,则设计了一种基于后向切片的方法:从程序崩溃点(如访问了一个损坏的函数指针)开始,逆向分析找到其父指针所指向的堆块。考虑到现代内存分配器会重用已释放的内存块,FreeWill通过切片找出正确的对象及其生命周期,并能处理多级UAF(Multi-Level UAF)场景,即悬空指针本身能被正常解引用,但其指向的次级对象已释放。

2. 引用分析: 在确定了UAF对象的生命周期后,FreeWill使用一种灰染污点分析(Gray-Taint Tracking)技术来追踪该对象地址的所有传播路径,从而识别所有潜在的引用。 * 潜在引用跟踪: 当对象地址被存入寄存器或内存(堆、栈、全局区)时,标记为引用创建。当持有引用的内存被覆写或因内存释放/函数返回而不再使用时,标记为引用销毁。同时追踪涉及引用的算术和逻辑运算(如位操作),处理计算引用(Computed Reference)。 * 强引用识别: 为了过滤掉编译器生成的大量临时引用,FreeWill基于引用存储位置识别强引用,主要包括:存储在堆内存中的引用(通常是开发者有意创建的)、栈上的局部变量以及作为函数参数传递的引用。实验表明,此步骤能过滤掉超过90%的潜在引用,极大便利了后续诊断。

3. 引用计数检测: 此步骤旨在识别管理UAF对象的引用计数器及其增减操作。若有源代码,可通过开发者标注或调试信息识别。对于二进制程序,FreeWill提出了一种新颖的启发式方法HR-CDFree。 * HR-CDFree启发式: 核心思想是:如果引用计数器变为零,那么应该有一个free操作在控制上依赖于该计数器。FreeWill为对象中的每个字段(如4字节)在轨迹中建立值序列。当任何字段变为零时,它会检查后续轨迹中是否很快出现零条件跳转指令(如jz),并检测在当前函数返回前是否调用了free函数。这种方法能有效处理引用计数器低位被用作标志位等复杂情况。在包含543个对象(65个引用计数,478个非引用计数)的数据集上,HR-CDFree达到了98%的准确率和90%的精确度,显著优于传统的固定步长检测方法。

4. UAF诊断: 这是FreeWill的核心,基于一个“省略感知”的引用计数模型。 * 引用计数匹配: 首先需要将检测到的引用计数器增减操作与具体的引用创建/销毁事件进行匹配。针对不同的编程风格(内联操作 vs. 非内联封装函数),FreeWill提出了两种基于距离的匹配方法:基于执行距离(ED)和基于封装函数距离(WD)的匹配。 * 引用计数错误检测: 研究团队提出了一个形式化的引用表示(创建/销毁时间,是否有增减操作)和四条省略规则(OR):重叠省略、传递重叠省略、包含省略、重叠包含省略。这些规则描述了在何种情况下,对引用的计数操作可以被安全地省略。基于此模型,FreeWill设计了算法(见论文Algorithm 1)来分析所有强引用。算法遍历引用,根据其是否具有增减操作,将它们分类,并应用上述四条省略规则来检查每个省略是否合法。任何违反规则的省略都被报告为引用计数错误。如果未发现引用计数错误,则将所有悬空指针报告为诊断结果(即悬空使用漏洞)。此外,当发现缺失的引用计数增加操作时,FreeWill会建议添加该操作以修复漏洞。

主要研究结果 研究团队在收集自真实世界的76个UAF漏洞(涵盖Internet Explorer、Firefox、Chrome、Linux/macOS内核、Python/PHP脚本引擎)上对FreeWill进行了全面评估。

  1. UAF对象识别成功率: FreeWill成功复现并分析了73个漏洞。成功识别出66个UAF漏洞(包括5个多级UAF和5个多线程UAF),识别出5个实际为空指针解引用(Null-Pointer Dereference)的误报UAF漏洞,并对18个涉及内存块重用的漏洞进行了正确分析。
  2. 引用与引用计数识别准确性: 成功识别了所有UAF对象生命周期内的引用,并通过强引用过滤极大简化了分析。使用HR-CDFree启发式方法,成功识别出52个采用引用计数管理的UAF对象,并准确定位了其计数器的内存偏移量。
  3. 诊断与根因分类结果: FreeWill成功诊断出48个由引用计数错误引起的UAF漏洞,以及18个由悬空使用(Dangling Usage)引起的漏洞。
    • 引用计数错误漏洞细分为:
      • 错误省略:36个。主要成因包括:实现复制功能时未考虑被复制对象的生命周期管理;调用函数时未增加传入/传出对象的引用计数,而函数内部进行了减少操作。
      • 不一致的减少:12个。其中6个为“只有减没有增”,6个为“一次增加伴随两次减少”。
    • 此外,研究还根据引用创建方式(通过计算、mov指令、rep movsd指令或push指令)对漏洞进行了有意义的分类,有助于理解漏洞模式和生成补丁。
  4. 补丁建议有效性: FreeWill为漏洞自动生成了补丁建议。在71个可分析的漏洞中,有56个建议与官方补丁完全匹配。特别地,在48个引用计数错误漏洞中,有37个建议与官方补丁一致。这证明了FreeWill不仅能诊断根因,还能提供切实可行的修复方案。
  5. 发现错误/不完整补丁: FreeWill的分析还发现了3个官方补丁是错误或不完整的。例如,Linux内核的一个补丁错误地增加了另一个对象的引用计数;macOS和PHP的两个补丁试图通过添加条件检查来防止对象替换,但检查条件不完备,仍存在绕过路径。
  6. 性能表现: FreeWill对每个漏洞的平均分析时间在15分钟以内,展示了其在真实世界大型程序诊断中的实用性。

结论与意义 本研究提出并实现了FreeWill,一个能够自动化诊断由引用计数错误引发的UAF漏洞的有效工具。其核心贡献在于: 1. 提出了“省略感知”的引用计数模型,首次系统性地建模并自动化检测两种类型的引用计数错误。 2. 开发了一系列针对二进制程序的实用技术,包括基于灰染污点的引用分析、基于控制依赖自由(HR-CDFree)的启发式引用计数器识别,以及基于距离的引用计数匹配方法。 3. 构建并评估了自动化工具,在涵盖多种软件类型的76个真实漏洞上验证了方法的有效性和实用性。

该研究的科学价值在于,它超越了单纯的漏洞检测,深入到了漏洞根因分析的自动化领域,为解决UAF这一经典难题提供了新的、可操作的思路。其应用价值显著:能够帮助安全分析人员和开发人员快速理解复杂UAF漏洞的根源,减少手动调试的时间,并提供准确的补丁建议,从而提升软件修复的效率和安全性。研究结果也揭示了引用计数错误在真实软件中的普遍性和模式,以及现有部分官方补丁的不足,对软件工程和安全实践具有重要启示。

研究的亮点 1. 问题洞察新颖: 将UAF漏洞的根因系统性地归结和建模为“引用计数错误”,并细分为两类,抓住了大型复杂软件(如浏览器、内核)中UAF漏洞的一个关键且常见的产生机制。 2. 方法创新性强: 提出的“省略感知”模型和四条省略规则,巧妙地将本为性能优化而存在的合法省略纳入分析框架,使得自动化区分“错误”与“正确”的省略成为可能。HR-CDFree启发式方法有效解决了二进制环境下引用计数器的识别难题。 3. 工程实现务实: 设计的工具FreeWill充分考虑了现实约束(如无源代码、大规模GUI程序),通过扩展QEMU等方式保证了分析的可行性。整个工作流程设计完整,从轨迹收集、对象识别、引用追踪到最终诊断和补丁建议,形成了闭环。 4. 评估全面有力: 使用了大规模、多样化的真实漏洞数据集进行评估,不仅验证了诊断准确率,还评估了补丁建议的有效性,甚至发现了官方补丁的问题,充分证明了研究成果的实战价值。

其他有价值的内容 论文通过一个详细的激励性示例(图1)清晰地展示了引用计数错误如何导致UAF,并对比了现有诊断方法的局限性(表1),突出了本研究的必要性。此外,研究还讨论了FreeWill的局限性(如对竞争条件漏洞的诊断能力有限、对自定义堆管理器的识别不足),并指明了未来的改进方向,体现了研究的严谨性。对于内核驱动程序的漏洞,研究团队通过提取相关代码构建用户态动态库的方式进行测试,这也为分析无源代码或环境复杂的系统软件提供了可行的实验方法论参考。

上述解读依据用户上传的学术文献,如有不准确或可能侵权之处请联系本站站长:admin@fmread.com