云环境中的硬件侧信道攻击:从缓存到CPU流水线

本文探讨了云环境中硬件侧信道攻击的新技术,重点分析了利用CPU流水线而非传统缓存层的新型攻击方法,涵盖密钥窃取、进程监控、环境密钥识别及隐蔽通信等实际攻击案例。

云环境中的硬件侧信道攻击

在REcon 2015会议上,我展示了一种针对云中共存虚拟机的新型硬件侧信道攻击。该攻击利用CPU流水线而非侧信道攻击中常用的缓存层级。在设计或寻找基于硬件的侧信道时——特别是在云环境中——我分析了几种通用属性,这些属性定义了“正确”类型的易受攻击系统,以及针对硬件媒介量身定制的独特属性。

幻灯片和完整研究论文请参见此处

侧信道攻击的相关性只会增加。特别是针对共享硬件资源系统(如云平台)固有漏洞的攻击。

图1:物理资源的虚拟化

但什么是侧信道攻击???

任何从运行目标应用程序的环境中泄露的有意义信息,或者在这种情况下,从受害虚拟机中泄露的信息,都被视为侧信道。然而,某些信息比其他信息更好。在这种情况下,一个进程(攻击者)必须能够从一个虚拟机内部重复记录环境“工件”。

在云中,这些环境工件是虚拟机使用的共享物理资源。虚拟机监控程序动态分区每个资源,然后由单个虚拟机将其视为其私有资源。侧信道模型(图2)说明了这一点。

了解这一点后,攻击者可以以可记录的方式影响该资源分区,例如通过刷新缓存层级中的一行,等待受害进程将其用于操作,然后再次请求该地址——记录现在存在的值。

图2:侧信道模型

攻击示例

太好了!所以我们可以从受害者的环境中记录东西——但现在呢?根据受害者进程正在做什么,我们实际上可以实施几种不同类型的攻击。

1. 加密密钥窃取

加密密钥很好,私有加密密钥更好。使用这种硬件侧信道,可以泄露共存进程使用的私有密钥的字节。在一种场景中,两个虚拟机在不同时间被分配了L3缓存上的相同空间。攻击者刷新某个缓存地址,等待受害者使用该地址,然后再次查询它——记录现在存在的新值[1]。

2. 进程监控(受害者正在运行什么应用程序?)

当你记录足够多的目标行为时,这是可能的,即CPU或流水线使用情况或内存中存储的值。可以以不同程度的确定性构建记录与特定运行进程之间的映射。警告,这确实至少依赖于机器学习的初步知识。

3. 环境密钥(非常适合证明共存!)

使用从特定硬件资源获取的环境记录,你还可以在云中唯一地识别一台服务器与另一台服务器。这对于证明你控制的两个虚拟机在同一物理服务器上共存非常有用。或者,如果你知道目标所在服务器的行为特征,你可以重复创建虚拟机,记录每个系统上的行为,直到找到匹配项[2]。

4. 广播信号(无需互联网接收消息:0)

如果共谋进程故意在预先安排的硬件资源上生成行为,例如故意用0和1填充缓存行,攻击者(你的进程)可以以与记录受害者行为相同的方式记录此行为。然后,你可以将记录的值转换为预先约定的消息。从不同的硬件媒介记录会导致具有不同带宽的信道[3]。

缓存容易,流水线更难

现在所有上述示例都使用缓存来记录受害者和攻击者进程共享的环境。缓存是在文献和实践中构建侧信道最广泛使用的,也是最容易记录工件的。基本上每个人都喜欢缓存。

缓存不是唯一的共享资源:共存的虚拟机也共享CPU执行流水线。为了使用CPU流水线,我们必须能够从中记录一个值。然而,任何进程都没有简单的方法来查询流水线随时间的状态——它就像一个虚拟黑盒。进程唯一能知道的是它给流水线执行的指令集顺序以及流水线返回的结果。

乱序执行(流水线的工件)

我们可以利用这种流水线优化作为记录流水线状态的一种手段。已知的输入指令顺序将导致两个不同的返回值——一个是预期结果,另一个是如果流水线乱序执行它们的结果。

图3:外部进程可以共享相同的流水线

强内存排序

我们的目标,云处理器,可以假定为x86/64架构——意味着通常是强排序内存模型[4]。这很重要,因为流水线将优化指令的执行,但尝试维护存储到内存和从内存加载的正确顺序……

然而,来自不同线程的存储和加载可能会被乱序执行重新排序。现在,如果我们聪明,这种重新排序是可观察的。

记录指令重新排序(或如何聪明)

为了让攻击者记录来自流水线的“重新排序”工件,我们必须为我们的两个线程中的每一个记录两件事:

  • 输入指令顺序
  • 返回值

此外,每个线程中的指令必须包含对内存的STORE和从内存的LOAD。从内存的LOAD必须引用相反线程存储到的位置。这种设置确保了下面说明的四种情况的可能性。最后一种是我们记录的工件——这样做几千次可以给我们随时间变化的平均值。

图4:攻击者可以记录其指令何时被重新排序

发送消息

为了使我们的攻击更有趣,我们希望能够强制记录的乱序执行数量。这种能力对其他攻击很有用,例如构建隐蔽通信信道。

为了做到这一点,我们需要改变流水线的优化工作方式——要么增加它重新排序我们两个线程的概率,要么减少它。最简单的是强制执行强内存顺序,并保证攻击者将收到更少的乱序执行。

内存屏障

在x86指令集中,有特定的屏障指令,将阻止处理器重新排序STORE和LOAD的四种可能组合。我们感兴趣的是当处理器遇到带有STORE后跟LOAD的指令集时强制强顺序。

指令mfence正是这样做的。

通过让共谋进程在流水线中注入这些内存屏障,攻击者的指令将不会被重新排序,强制记录的平均值明显减少。在不同的时间范围内这样做允许我们发送二进制消息。

图5:mfence确保流水线上的强内存顺序

结语

关键是,即使虚拟化将你的虚拟机与数百个其他外部虚拟机分开,流水线也无法将你的进程指令与所有其他指令区分开来,我们可以利用这一点为我们带来优势。:0

如果你想了解更多关于这种侧信道技术,请阅读完整论文此处

参考文献:

如果你喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计