云环境中的硬件侧信道攻击:超越缓存的新威胁

本文深入探讨云计算中基于CPU流水线的硬件侧信道攻击技术,详细分析攻击原理、四种实际攻击场景(密钥窃取、进程监控等),并介绍利用内存屏障指令构建隐蔽通信通道的创新方法。

硬件侧信道在云环境中的应用 - Trail of Bits博客

Sophia D’Antoine
2015年7月21日
会议, 密码学, 漏洞利用

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

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

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

图1:物理资源的虚拟化

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

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

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

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

图2:侧信道模型

攻击示例

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

1. 加密密钥窃取

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

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

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

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

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

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

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

缓存容易,流水线更难

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

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

乱序执行(流水线的痕迹)

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

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

强内存排序

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

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

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

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

  • 输入指令顺序
  • 返回值

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

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

发送消息

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

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

内存屏障

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

指令mfence正是这样做的。

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

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

结语

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

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

https://eprint.iacr.org/2013/448.pdf
http://www.ieee-security.org/TC/SP2011/PAPERS/2011/paper020.pdf
https://www.cs.unc.edu/~reiter/papers/2014/CCS1.pdf
http://preshing.com/20120930/weak-vs-strong-memory-models/

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

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