HEALER: Relation Learning Guided Kernel Fuzzing学习笔记

        现代操作系统是最复杂的计算机程序之一,但在其开发的过程中不可避免地会引入错误或漏洞。并且由于操作系统的广泛应用和重要地位,这些漏洞可能带来严重的威胁并导致损失。因此,挖掘操作系统中隐藏的错误和漏洞对提高系统的整体安全性具有重要意义。模糊测试是目前最流行、最有效的软件测试技术之一,被广泛用于各个主流软件的测试,其中也包括操作系统内核的测试。

        但是,目前的内核模糊测试工具在生成和变异测试用例时,没能充分考虑系统调用之间的关系。本文的作者提出了一种动静态相结合的关系学习算法,捕捉系统调用之间的依赖关系,并通过捕捉到的依赖关系来指导生成更有效的测试用例。作者搭建了基于上述算法的模糊测试工具HEALER,并对其进行了实验。实验结果表明,与目前主流的内核模糊测试工具Syzkaller和Moonshine相比,Healer平均提升28%与21%的分支覆盖率,并且效率提升了2.2倍与1.8倍。实验中,Healer在Linux内核中发现了218个漏洞,其中有33个首次发现的漏洞。

一、研究背景

        操作系统内核的测试用例其实就是系统调用的序列。Syzkaller并不是完全没有考虑系统调用之间的影响,它利用一张系统调用选择表来记录一个系统调用在另一个系统调用之前被调用的概率,以确定要测试的系统调用的顺序。虽然这个表体现了系统调用之间的资源依赖关系,但选择表并不能显示出系统调用之间的影响关系。而且,系统调用的组合的空间巨大,并且其中大多数组合是无效的或是与别的组合等价,需要采取有效的方法来减少搜索空间并增加生成有效测试用例的概率。

        为此,作者提出了新的内核模糊测试工具Healer。Healer通过关系学习算法来处理测试用例,推断用例中的系统调用之间是否存在影响关系,然后将学习到的关系存储在关系表中。关系表会在模糊测试的过程中被逐步细化,用于指导测试用例的生成和变异,最终使得测试用例中的每个系统调用都能够深入到内核的深层逻辑。

二、Healer的结构设计


       上图展示了Healer的主要组件和整体工作流程。Healer借用了Syzkaller的系统调用格式Syzlang来描述被测内核的系统调用信息,比如参数的输入结构和部分语义。Healer可以基于给定的信息来生成满足结构和部分语义约束的系统调用序列,同时为每个特定类型使用不同的变异算子。输入语料库是一组高质量的测试用例,由模糊测试过程中积累的调用序列组成。用户可以自定义初始语料库以提高效率。系统调用描述包含现有的系统调用信息。关系学习模块对最小化的测试用例进行分析,并在模糊测试过程中对关系表进一步细化。同时,引导式生成和变异模块根据学习到的关系生成系统调用序列。

        Healer的输入是一系列系统调用描述符和种子集。种子集是非必须的,如果没有,HEALER会通过随机组合系统调用来构造初始语料集。

        Healer启动后,对于给定的种子,首先进行静态学习获得系统调用间相关关系,并记录到关系表中。然后基于关系表生成新种子或将已有的种子进行变异来得到测试用例。随后将测试用例交由内核执行并记录序列中各个系统调用的覆盖率。基于覆盖率进行动态学习获得系统调用的相关关系,并更新关系表。Healer将上述步骤循环执行,并保存测试过程中crash的相关信息。

三、Healer的关系学习过程

        Healer的核心就是其关系学习算法。在本文中,系统调用之间的影响关系定义如下:如果系统调用Ci的执行可以通过修改内核的内部状态来影响的系统调用Cj的执行路径,则称Ci对Cj有影响。

Healer的关系学习算法分为两类,即静态学习与动态学习。

        1. 静态学习

        静态学习是为了捕捉系统调用间显式的相关关系,例如一个系统调用的返回值可以作为另一个系统调用的参数。如果两个系统调用Ci和Cj满足以下规则,则将其标记为相关:

        (1)Ci的返回值为资源类型r0或者Ci中的参数是该资源类型的数据流流向向外的指针

        (2)Cj中至少一个参数是资源类型r0;或是具有向内的数据流方向且兼容r0的资源类型r1。

        2. 动态学习

        动态学习是为了捕捉系统调用间隐式的相关关系。动态学习可以使用syzlang无法表达的信息来更好地更新和细化关系表。

        基于这些关系学习过程,Healer将系统调用间的相关关系整理成一张关系表。接下来就利用学习到的关系表来生成高质量的测试用例,并指导种子的变异。

四、Healer的实验

        作者选用Linux 5.11、5.4和4.19作为测试对象,在一台16核32G内存的服务器上进行实验。与HEALER进行对比的是其他内核模糊测试工具Syzkaller、Moonshine,其中HEALER和Syzkaller都没有加入初始种子集。每次实验进行24小时的测试,并重复十次,取平均值作为结果。

        分支覆盖情况:

        性能表现:

        除此之外,作者还针对关系学习的有效性进行了实验,将完整的Healer与不用学习到的关系表来指导用例生成和变异的Healer-进行了对比:

        作者还在文中展示了Healer所学习到的关系数量:

        论文中还将Healer学到的关系可视化。因为长时间学习后的关系表太过复杂,下图中只展示了前3小时的结果。观察可视化的过程可以发现,关系学习的过程就是系统调用间的依赖关系逐渐明确的过程。

        最后一步就是检验Healer发现真实漏洞的能力。作者在三个内核版本上选取了35个已知bug作为测试用例,用3个工具分别进行测试。Syzkaller和Moonshine分别发现了其中17、20个bug,而Healer发现了32个。并且由Healer找出而被其他工具忽略的bug所对应的测试用例更复杂、序列更长,这进一步证实了Healer的有效性。

五、总结

        Healer采用了动静态结合的方法来学习系统调用间的关系,为操作系统内核的模糊测试生成和变异出高效且实用的测试用例。使用Healer能够帮助开发人员更高效更全面地找出内核中的bug。Healer的成功体现了系统调用之间的关系在生成和变异高质量测试用例时起着重要作用。

        此外,论文中的实验设计思路非常直观,第一个实验展示了相对于已有工具性能的提升,第二个实验验证了关系学习方法的有效性,第三个实验突出了其真实漏洞的挖掘能力。

参考资料:

https://dl.acm.org/doi/epdf/10.1145/3477132.3483547

基于关系学习的内核模糊测试 HEALER - 知乎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 作者序 译者序 前 言 第一部分 第1章 安全漏洞发掘方法学 1.1 白盒测试 1.1.1 源代码评审 1.1.2 工具和自动化 1.1.3 优点和缺点 1.2 黑盒测试 1.2.1 人工测试 1.2.2 自动测试或模糊测试 1.2.3 优点和缺点 1.3 灰盒测试 1.3.1 二进制审核 1.3.2 自动化的二进制审核 1.3.3 优点和缺点 1.4 小结 1.5 脚注 第2章 什么是模糊测试 2.1 模糊测试的定义 2.2 模糊测试的历史 2.3 模糊测试阶段 2.4 模糊测试的局限性和期望 2.4.1 访问控制缺陷 2.4.2 设计逻辑不良 2.4.3 后门 2.4.4 内存破坏 2.4.5 多阶段安全漏洞 2.5 小结 第3章 模糊测试方法和模糊器类型 3.1 模糊测试方法 3.1.1 预先生成测试用例 3.1.2 随机方法 3.1.3 协议变异人工测试 3.1.4 变异或强制性测试 3.1.5 自动协议生成测试 3.2 模糊器类型 3.2.1 本地模糊器 3.2.2 远程模糊器 3.2.3 内存模糊器 3.2.4 模糊器框架 3.3 小结 第4章 数据表示和分析 4.1 什么是协议 4.2 协议域 4.3 简单文本协议 4.4 二进制协议 4.5 网络协议 4.6 文件格式 4.7 常见的协议元素 4.7.1 名字-值对 4.7.2 块标识符 4.7.3 块长度 4.7.4 校验和 4.8 小结 第5章 有效模糊测试的需求 5.1 可重现性和文档记录 5.2 可重用性 5.3 过程状态和过程深度 5.4 跟踪、代码覆盖和度量 5.5 错误检测 5.6 资源约束 5.7 小结 第二部分 第6章 自动化测试和测试数据生成 6.1 自动化测试的价值 6.2 有用的工具和库 6.2.1ETHEREAL /WIRESHARK 6.2.2LIBDASM 和LIBDISASM 6.2.3LIBNET /LIBNETNT 6.2.4LIBPCAP 6.2.5METRO PACKET LIBRARY 6.2.6PTRACE 6.2.7PYTHON EXTENSIONS 6.3 编程语言的选择 6.4 测试数据生成和模糊启发式 6.4.1 整型值 6.4.2 字符串重复 6.4.3 字段分隔符 6.4.4 格式化字符串 6.4.5 字符翻译 6.4.6 目录遍历 6.5 小结 第7章 环境变量和参数的模糊测试 7.1 本地化模糊测试介绍 7.1.1 命令行参数 7.1.2 环境变量 7.2 本地化模糊测试准则 7.3 寻找目标程序 7.4 本地化模糊测试方法 7.5 枚举环境变量 7.6 自动化的环境变量测试 7.7 检测问题 7.8 小结 第8章 环境变量和参数的模糊测试:自动化 8.1 iFUZZ本地化模糊器的特性 8.2 iFUZZ的开发 8.3 iFUZZ的开发语言 8.4 实例研究 8.5 益处和改进的余地 8.6 小结 第9章 Web应用程序和服务器模糊测试 9.1 什么是Web应用程序模糊测试 9.2 目标应用 9.3 测试方法 9.3.1 建立目标环境 9.3.2 输入 9.4 漏洞 9.5 异常检测 9.6 小结 第10章 Web应用程序和服务器的模糊测试:自动化 10.1 Web应用模糊器 10.2 WebFuzz的特性 10.2.1 请求 10.2.2 模糊变量 10.2.3 响应 10.3 必要的背景知识 10.3.1 识别请求 10.3.2 漏洞检测 10.4 WebFuzz的开发 10.4.1 开发方法 10.4.2 开发语言的选择 10.4.3 设计 10.5 实例研究 10.5.1 目录遍历 10.5.2 溢出 10.5.3 SQL注入 10.5.4 XSS脚本 10.6 益处和改进的余地 10.7 小结 第11章 文件格式模糊测试 11.1 目标应用 11.2 方法 11.2.1 强制性或基于变异的模糊测试 11.2.2 智能强制性或基于生成的模糊测试 11.3 输入 11.4 漏洞 11.4.1 拒绝服务 11.4.2 整数处理问题 11.4.3 简单的栈和堆溢出 11.4.4 逻辑错误 11.4.5 格式化字符串 11.4.6 竞争条件 11.5 漏洞检测 11.6 小结 第12章 文件格式模糊测试:UNIX平台上的自动化测试 12.1 NOTSPIKEFILE和SPIKEFILE 12.2 开发方法 12.2.1 异常检测引擎 12.2.2 异常报告(异常检测) 12.2.3 核心模糊测试引擎 12.3 有意义的代码片段 12.3.1 通常感兴趣的UNIX信号 12.3.2 不太感兴趣的UNIX信号 12.4 僵死进程 12.5 使用的注意事项 12.5.1 ADOBE ACROBAT 12.5.2 REALNETWORKS REALPLAYRE 12.6 实例研究:REALPLAYER REALPIX格式化字符串漏洞 12.7 语言 12.8 小结 第13章 文件格式模糊测试:Windows平台上的自动化测试 13.1 Windows文件格式漏洞 13.2 FileFuzz的特性 13.2.1 创建文件 13.2.2 应用程序执行 13.2.3 异常检测 13.2.4 保存的审核 13.3 必要的背景知识 13.4 FileFuzz的开发 13.4.1 开发方法 13.4.2 开发语言的选择 13.4.3 设计 13.5 实例研究 13.6益处和改进的余地 13.7 小结 第14章 网络协议模糊测试 14.1 什么是网络协议模糊测试 14.2 目标应用 14.2.1APPLEGATE 14.2.2 网络层 14.2.3 传输层 14.2.4 会话层 14.2.5 表示层 14.2.6 应用层 14.3 测试方法 14.3.1强制性或基于变异的模糊测试 14.3.2 智能强制性模糊测试和基于生成的模糊测试 14.3.3 修改的客户端变异模糊测试 14.4 错误检测 14.4.1 人工方法(基于调试器) 14.4.2 自动化方法(基于代理) 14.4.3 其它方法 14.5 小结 第15章 网络协议模糊测试:UNIX平台上的自动化测试 15.1 使用SPIKE进行模糊测试 15.1.1 选择测试目标 15.1.2 协议逆向工程 15.2 SPIKE 101 15.2.1 模糊测试引擎 15.2.2 通用的基于行的TCP模糊器 15.3 基于块的协议建模 15.4 SPIKE的额外特性 15.4.1 特定于协议的模糊器 15.4.2 特定于协议的模糊测试脚本 15.4.3 通用的基于脚本的模糊器 15.5 编写SPIKE NMAP模糊器脚本 15.6 小结 第16章 网络协议模糊测试:Windows平台上的自动化测试 16.1 ProtoFuzz的特性 16.1.1 包结构 16.1.2 捕获数据 16.1.3 解析数据 16.1.4 模糊变量 16.1.5 发送数据 16.2 必要的背景知识 16.2.1 错误检测 16.2.2 协议驱动程序 16.3 ProtoFuzz的开发 16.3.1 开发语言的选择 16.3.2 包捕获库 16.3.3 设计 16.4 实例研究 16.5 益处和改进的余地 16.6 小结 第17章 Web浏览器模糊测试 17.1 什么是Web浏览器模糊测试 17.2 目标 17.3 方法 17.3.1 测试方法 17.3.2 输入 17.4 漏洞 17.5 错误检测 17.6 小结 第18章 Web浏览器的模糊测试:自动化 18.1 组件对象模型的背景知识 18.1.1 在Nutshell中的发展历史 18.1.2 对象和接口 18.1.3 ActiveX 18.2 模糊器的开发 18.2.1 枚举可加载的ActiveX控件 18.2.2 属性,方法,参数和类型 18.2.3 模糊测试和监视 18.3 小结 第19章 内存数据的模糊测试 19.1 内存数据模糊测试的概念及实施该测试的原因 19.2 必需的背景知识 19.3 究竟什么是内存数据模糊测试 19.4 目标 19.5 方法:变异循环插入 19.6 方法:快照恢复变异 19.7 测试速度和处理深度 19.8 错误检测 19.9 小结 第20章 内存数据的模糊测试:自动化 20.1 所需要的特性集 20.2 开发语言的选择 20.3 Windows调试API 20.4 将其整合在一起 20.4.1如何实现在特定点将"钩子"植入目标进程的需求 20.4.2如何来处理进程快照和恢复 20.4.3如何来选择植入钩子的点 20.4.4如何对目标内存空间进行定位和变异 20.5你的新的最好的朋友PYDBG 20.6 一个构想的示例 20.7 小结 第三部分 第21章 模糊测试框架 21.1 模糊测试框架的概念 21.2 现有框架 21.2.1 ANTIPARSER 21.2.2 DFUZ 21.2.3 SPIKE 21.2.4 PEACH 21.2.5 通用模糊器(General Purpose Fuzzer) 21.2.6 AUTODAF? 21.3 定制模糊器的实例研究:SHOCKWAVE FLASH 21.3.1 SWF文件的建模 21.3.2 生成有效的数据 21.3.3 对环境进行模糊测试 21.3.4 测试方法 21.4模糊测试框架SULLEY 21.4.1 SULLEY目录结构 21.4.2 数据表示 21.4.3 会话 21.4.4 21.4.5 一个完整的实例分析 21.5 小结 第22章 自动化协议解析 22.1 模糊测试存在的问题是什么 22.2 启发式技术 22.2.1 代理模糊测试 22.2.2 改进的代理模糊测试 22.2.3 反汇编启发式规则 22.3 生物信息学 22.4 遗传算法 22.5 小结 第23章 模糊器跟踪 23.1 我们究竟想要跟踪什么 23.2 二进制代码可视化和基本块 23.2.1 CFG 23.2.2 CFG示例 23.3 构造一个模糊器跟踪器 23.3.1 刻画目标特征 23.3.2 跟踪 23.3.3 交叉引用 23.4 对一个代码覆盖工具的分析 23.4.1 PSTALKER设计概览 23.4.2 数据源 23.4.3 数据探查 23.4.4 数据捕获 23.4.5局限性 23.4.6 数据存储 23.5 实例研究 23.5.1 测试策略 23.5.2 测试方法 23.6 益处和改进的余地 23.7 小结 第24章 智能故障检测 24.1 基本的错误检测方法 24.2 我们所要搜索的内容 24.3 选择模糊值时的注意事项 24.4 自动化的调试器监视 24.4.1 一个基本的调试器监视器 24.4.2 一个更加高级的调试器监视器 24.5 24.6 动态二进制插装 24.7 小结 第四部分 第25章 汲取的教训 25.1 软件开发生命周期 25.1.1 分析 25.1.2 设计 25.1.3 编码 25.1.4 测试 25.1.5 维护 25.1.6 在SDLC中实现模糊测试 25.2 开发者 25.3 QA研究者 25.4 安全问题研究者 25.5 小结 第26章 展望 26.1 商业工具 26.1.1 安全性测试工具beSTORM 26.1.2 BREAKINGPOINT系统BPS-1000 26.1.3 CODENOMICON 26.1.4 GLEG PROTOVER PROFESSIONAL 26.1.5 安全性测试工具MU-4000 26.1.6 SECURITY INNOVATION HOLODECK 26.2 发现漏洞的混合方法 26.3 集成的测试平台 26.4 小结

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值