刷新并重新加载缓存侧通道攻击

Pro*_*mer 5 hardware security caching spectre side-channel-attacks

我试图了解刷新+重新加载缓存侧通道攻击。据我所知,攻击利用了非特权数据可以加载到缓存中的事实(当利用分支预测、推测执行等时)。然后,攻击者使用探针数组来访问内存,该内存被快速加载,假设位于高速缓存上(秘密数据的一部分)。

我发现不清楚的一件事是攻击者如何能够迭代非特权内存的虚拟内存?例如 - 迭代内核虚拟内存或其他进程的内存。

小智 5

  1. 有不同的缓存侧通道攻击。有很多变体,但似乎您混淆了两个:Prime + Probe 和 Flush + Reload。因为这是一个关于 Flush + Reload 的问题,所以我会坚持下去。

  2. Flush + Reload 的工作原理是滥用共享代码/数据以及 clflush(缓存刷新指令)的工作方式(至少在 x86 上)。还有其他架构的变体。受害者和攻击者必须物理共享至少一页数据。当攻击者使用 clflush 命令和指向此共享数据的地址时,它会从缓存层次结构中完全刷新。由于数据是共享的,因此攻击者可以攻击缓存中的数据。因此,攻击者反复刷新与受害者的共享数据,然后允许/等待受害者运行,然后重新加载数据。如果攻击者发生缓存未命中,则受害者不会访问数据(没有将其带回缓存)。如果它被击中了,那么受害者就击中了(至少有可能)。攻击者可以区分缓存命中和未命中,因为内存访问的时间非常不同。

  3. 如果攻击者和受害者是不同的进程,如何共享数据?您需要了解一些现代操作系统。通常,共享库仅在内存中物理加载一次。例如,标准 c 库仅加载一次,但不同的应用程序(物理上)访问相同的数据,因为它们的页表指向相同的物理地址,因为操作系统以这种方式设置它。

  4. 某些操作系统更加激进,会扫描物理内存以查找具有完全相同数据的页面。在这种情况下,它们通过更改页表来“合并”页面,以便使用该数据的所有进程都指向新的单个物理页,而不是拥有两个物理副本。不幸的是,即使在非共享库中,这也允许 Flush + Reload 发生 - 如果您知道受害者的代码,并且想要监视它,您只需将其加载到您的地址空间(mmap 它),操作系统就会很高兴地进行重复数据删除内存,使您可以访问其数据。只要你们都只是读取数据就可以了;如果您尝试写入数据,操作系统将被迫取消合并页面。然而,这对于 FLUSH + RELOAD 来说是没问题的:无论如何你只对阅读感兴趣!


b d*_*nan 3

首先,您应该看一下我对为什么查找表不能在恒定时间内运行的描述,因为我有缓存和标记如何工作​​的图片。

缓存位于MMU和 CPU 之间,MMU 负责创建虚拟内存;因此,缓存攻击实际上是虚拟内存的一个独立功能。它们是强制缓存刷新的功能,然后选择如何重新加载缓存,因为您正在寻找临时信息。缓存之间的外部获取是泄漏信息的原因。(注意,这基本上是一个 x86 问题,因为它不允许缓存锁定,这与 1990 年以来的大多数 CPU 不同。另一个警告是,我只为非 x86 架构制造硬件,所以如果我对缓存的理解有误,请告诉我锁定关键数据)。

作为一般示例,我们有 1k 字节的缓存,我们将使用 AES s-box 作为查找表,因此有 256 个条目。

  • 通过从内存中读取 2k 字节,通过不同的进程强制刷新缓存刷新。
  • AES进程开始运行,并通过总线获取代理将数据sbox数据放入缓存中
  • 然后,我们执行另一个进程,从内存中读取 1023 字节的不同数据,以覆盖除一个 AES 条目之外的所有条目,并查看该数据何时因总线读取而缓慢输出

现在我们讨论 MMU 版本中的虚拟内存。如果您查看我链接的答案,您会看到有缓存标签。现在让我们假设一个简单的示例,其中我有两个具有 20 位(1MiB 地址空间)的进程。MMU 使这两个进程具有相同的虚拟表(从 0xYYY00000 开始),其中 YYY 是内存中的实际前缀。如果我知道 MMU 如何映射数据,我就可以根据由于内存重叠而在缓存中创建的标记信息来创建结构化攻击。

Bernstein 的 AES 缓存定时攻击中提供了有关如何在软件方面构建这些攻击的更多详细信息 。