Hi!请登陆

百度安全再次亮相安全顶级会议NDSS–研究幽灵代码利用片段检测的技术详解

2021-2-24 41 2/24

百度安全在系统安全深耕多年,持续发表多项顶级会议论文。近日百度安全又一重磅研究成果收录安全顶级会议 NDSS。幽灵 ( Spectre ) 作为开启侧信道攻击的热核时代一类漏洞,它以变种多,影响范围广而受到业界关注。Spectre
是利用现代处理器芯片预测执行机制的一类漏洞的总称。利用该类漏洞,黑客可以绕过了传统的软件防御壁垒,窃取私人敏感数据,泄露内核地址空间相关信息,更甚至可以绕过虚拟机的隔离防护机制,访问其他用户的内存数据,导致其他云用户的敏感信息泄漏。

近年来学术界和工业界纷纷提出各式防御方案。Spectre 作为一种硬件漏洞,提出硬件解决方案是最直接和有效的措施,但是硬件的解决方案涉及到整个底层硬件结构的改变,从初始的设计到大规模实际生产周期太长,很难快速应对多变的 Spectre 攻击,因此大部分的防御措施还处于研究阶段。跟硬件防御相比,软件层的加固是一个比较有效而且快速的防御方案。其中软件补丁是比较受业界追捧的一种防御 Spectre
的手段。它试图在代码层减少 Spectre 攻击面从而达到防御效果。具体来说,软件补丁是在代码层检测跟 Spectre 漏洞相关的,有潜在可以被利用的代码片段,我们称之为 gadget,然后对该段代码片段强制序列化,使得攻击者无法利用这些 gadget 进行攻击。强制序列化就是禁用 gadget 部分的代码的预执行功能,这样会降低软件运行的整体性能。现有 gadget
扫描技术的准确性决定了被补丁后软件的运行性能。已有的 Gadget 检测技术的误报率和漏报率都很高,它们检测的绝大部分 gadget 都是不具备 Spectre Gadget 的特点的。百度安全联合 UC Riverside 以及 MIT 研究设计研发了一款基于污点分析检测 Spectre Gadget 的工具 SpecTaint。实验证明 SpecTaint 的检测准确率高出其他工具平均
30 个百分点。下来我们将揭秘该工具的神奇之处。

SpecTaint 的整体软件架构

在软件层寻找可利用的 gadget 是黑客进行 Spectre 攻击的第一步。它需要结合现代处理器芯片预测执行机制的 Spectre 漏洞一起来完成攻击。传统动态二进制平台可以提供比较准确的程序行为分析,但是它只支持常规的程序行为,对芯片预执行的这种硬件行为没有模拟。Spectaint 是对二进制动态分析平台做了一个额外的拓展,使其支持芯片的预执行,并且在其基础上提供了 Spectre
Gadget 的行为建模和精准检测功能。

图 1.SpecTaint 整体构架图

具体来说,SpecTaint 的流程涉及到两种状态:软件常规行为模拟和预执行模拟。在常规模拟状态,SpecTaint 模拟执行正常程序指令流,监控其执行行为。在预执行模拟状态下,SpecTaint 将模拟预执行操作,执行原本不可能有输入触发的程序路径并监控预执行行为。SpecTaint 模拟正常程序指令流是为了增加代码覆盖率。给定一个输入,SpecTaint
先进行正常指令流模拟并执行输入触发的正常路径。在执行的过程过,遇到一个分支指令,SpecTaint 将存档当前的正常执行状态,然后进入预执行模拟状态,执行其他非输入触发的路径。等到预执行指令达到预执行执行的上限,SpecTaint 将回滚之前存档的正常执行状态,然后继续执行正常路径上的指令。

图 2.SpecTaint 模拟预执行流程图

SpecTaint 实现原理

1. SpecTaint 的预执行分析平台

SpecTaint 的预执行模拟是扩展了已有的二进制动态分析平台 Decaf, 在其基础上添加了预执行的功能。SpecTaint 将以 Spectre v1 的 gadget 检测为样例,解释整个分析平台的原理。Spectre v1
是利用预执行的分支误判所产生的内存溢出来进行信道泄露攻击。分支误判对系统运行环境有关,为了减少误判率,我们将假设处理器会对每个分支都会产生误判。为了模拟误判,对遇到的分支,SpecTaint 将存档当前执行状态,然后对分支计算结果进行逆反操作,这样就可以执行输入无法触发的预执行路径。预执行会有上限,当模拟预执行指令数目到达预设的上限,SpecTaint
将回滚到正常操作,根据原有的分支结果继续正常路径指令的模拟。执行状态的存档是指保存当前 cpu 执行到当前分支所有寄存器以及内存值。执行状态回滚是复原之前存档的所有寄存器和使用内存的值。

2. 污点分析并检测 Spectre Gadget

SpecTaint 利用二进制动态分析中的污点分析功能监控每个执行变量的数据依赖关系。传统污点分析不支持预执行的路径,SpecTaint 将扩展污点分析到预执行路径,并监控预执行路径上的变量数据依赖。在存档过程中,SpecTaint 也需要将污点分析的相关结果保存下来,保证污点分析的正确性。为了保证检测到的 Spectre Gadget 是可以被黑客控制,SpecTaint
将对所有的输入变量作为污染源,然后进行动态污点分析。每执行一个指令,SpecTaint 将监控它和输入变量的数据依赖关系,在污点分析的过程中,判断是否当前执行指令含有 Spectre Gadget。为了有效的检测 gadget 行为,我们严格分析了 Spectre V1 的 gadget 的行为特征,形式化地定义了 gadget 的行为模式,具体如下:

基于内存加载 ( Load ) 操作的 BCB Gadget- Spectre V1 的一种变种是基于内存加载操作的攻击。具体来说,就是加载的内存索引是攻击者的控制,因此攻击者可以操纵访问任意内存地址的内存。但是这些加载的内存值不可以直接被攻击者获取,因为处理器会在回滚时候清空所有操纵。因此 Spectre Gadget
需要另一组以内存加载内容为索引的操作,通过这组操作,攻击者就可以通过侧信道技术获取内存加载的内容。通过分析,我们给出基于内存加载操作的 BCB gadget 的形式化定义:

Eq. 1 定义了基于内存加载操作的 BCB gadget 的行为模式。在预执行模拟过程中 , SpecTaint 用动态污点分析每个内存加载变量是否和输入变量有数据依赖关系,也就是为真。如果有依赖关系,SpecTaint 将检查是否加载的指令执行结果会被另一个内存加载指令所依赖 . 如果整个布尔表达式为真,证明这段代码是一个潜在的 BCB Gadget。

基于内存存储 ( Store ) 操作的 BCB Gadget. Spectre v1 的另一种变种是基于内存存储的攻击。通过操作存储内存的索引,攻击者可以更改任意内存地址,比如函数返回值。这样攻击者可以指定函数跳转到任意可能含有可以利用的信道泄露代码片段。Eq. 2 给出了基于内存存储操作的 BCB gadget 如下:

通过对 Spectre V1 的 gadget 的定义, Spectaint 将在动态模拟执行的过程中检测执行代码的 gadget。理论上来说,Spectaint 将会对每一个含有内存操作预执行的模拟指令进行模式匹配检测,但是这种检测方式性能太低。所以 Spectain 仅仅对跟污染变量相关的指令进行跟踪模式匹配。

SpecTaint 性能展示

为了展示 SpecTaint 的性能,我们选取工业界和学术界比较前沿的三款 Spectre gadget 作为我们的对照实验组,在准确性,覆盖率以及运行时间三个方面做对比。我们选用三组实验数据集做对比实验 : 1 ) Spectre 样本数据集 ; 2 ) 公有数据集 3 ) 公有人工数据集。数据集 1 ) 包含 15 个公用 spectre gadget 的简单样本。2 ) 是
SpecFuzz 的实验数据集。这个数据集包含 6 个常用的开源软件,其中包括 1 个加密软件,一个压缩软件和 4 个解析程序。为了更好的对比性能,数据集 3 ) 是在 数据集 2 ) 上人工插入了一些 Spectre gadgets,用插入的 gadgets 作为检测基准用于系统化的对比性能。我们选取文章里的关键实验结果在此介绍,其他详细实验请参照论文。

表 1.SpecTaint 对照实验在公有人工数据集 3 ) 上测试结果

表 1 显示了 SpecTaint 在公有人工数据集上的测试结果。如表 1 所示,SpecTaint 相比其他检测工具覆盖率平均提高了 50%,尤其是在样本 Brotli,SpecTaint 的召回率达到 90%,而其他三组工具漏报了大部分的 Gadget。

表 2.SpecTaint 对照实验在公有人工数据集 2 ) 上测试结果

我们着重跟 SpecFuzz 在公有数据集上做了对比实验。跟公有人工数据集相比,数据集 2)没有 ground truth。因此我们采用人工筛检的方法,去除那些不可能被利用的检测结果,表 2 显示了相关对比实验结果。如表 2 所示,SpecTaint 性能远远超过了 SpecFuzz。

图 3..SpecTaint 对照实验在公有人工数据集上性能测试结果

我们在公有数据集 2 ) 上对比了经过 specTaint 和 SpecFuzz 加固软件运行性能。对每一个数据集 2 ) 的样本,分别用 SpecTaint 和 SpecFuzz 对其进行 gadget 的检测,用 lfence 加固对应的样本,然后分别运行该样本,记录运行时间。图 3 显示了 6 个样本的运行时间对比。从图中看出 SpecTaint 加固后的样本性能远远高于
SpecFuzz。因为 SpecFuzz 的误报率高,导致需要加固的开销大。然而 SpecTaint 的准确率更高,所以样本的加固开销低,相对运行时间就少。

表 4.SpecTaint 性能测试分析

最后,我们在数据集 2 ) 上展示 SpecTaint 的运行性能。我们利用传统 fuzzing 技术分别 fuzz 数据集 2)中的 6 个样本并采集输入样本,然后运行 SpecTaint。在运行的过程中,我们分别统计执行的输入样本的个数,预执行路径 p 的个数,总的运行时间,以及执行每个预执行路径的检测时间等。表 4 展示了 SpecTaint 的性能分析结果。如表 4
所示,SpecTaint 平均在 1 秒内完成一条预执行指令的模拟加检测。比如样本 Brotli,SpecTaint 在 40 分钟内完成 8,900 个分支的预执行。相对于比较重量级的污点分析来说,SpecTaint 的分析时间是可以接受的。

总结和展望

百度安全联合提出的有效检测幽灵攻击代码利用片段的分析检测方法,极大减少幽灵漏洞在软件层的工具面。此次论文入选 NDSS,再次展现了百度安全在前沿研究的能力和国际水准。近年来百度安全已经有多篇文章发表在包括 IEEE S&P, Usenix Security, ACM CCS, NDSS, DSN, ACSAC, ICSE
等国际顶级会议和期刊。未来,百度安全也将继续深耕系统安全,在安全研究方面继续保持学术领先。

相关推荐