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

问题描述

我正在尝试了解“刷新+重新加载”缓存侧通道攻击。 据我所知,这种攻击利用了非特权数据可以加载到缓存的事实(在利用分支预测,推测执行等时)。然后,攻击者使用探针阵列访问内存,该内存被快速加载并假定位于高速缓存(机密数据的一部分)上。

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

解决方法

首先,您应该查看我对lookup tables don't run in constant time的描述,因为我有关于缓存和标记工作原理的图片。

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

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

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

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

Bernstein's Cache-timing attacks on AES的软件方面,有关于如何构造这些攻击的更多详细信息。

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

  2. Flush + Reload至少在x86上通过滥用共享代码/数据以及clflush(缓存刷新指令)的工作原理来工作。还有其他体系结构的变体。受害者和攻击者必须物理共享至少一页数据。当攻击者使用clflush命令以及指向此共享数据的地址时,它会从缓存层次结构中完全清除。因为数据是共享的,所以攻击者可以攻击缓存中的该数据。因此,攻击者反复刷新与受害者的共享数据,然后允许/等待受害者运行,然后重新加载数据。如果攻击者有缓存未命中,则受害者不会访问数据(不会将其带回缓存)。如果受到打击,受害者确实做到了(至少可能如此)。攻击者可以区分未命中的缓存命中,因为内存访问的时间有很大的不同。

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

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