Intel官方对5月15号曝出的CPU侧信道漏洞“ZombieLoad”的详细技术分析(上)

xiaohui 嘶吼专业版

背景了解

5月15号有媒体曝出,安全研究人员在在一个月之前在Intel 芯片中发现了一种被称为“ZombieLoad”的新漏洞,此漏洞可让攻击者获取当前处理器正在处理的敏感数据。

攻击者可以利用这个漏洞发起对Intel 芯片的侧信道攻击,这也是继此前Meltdown、Spectre与Foreshadow之后,最为严重的安全漏洞,研究员们在一个月之前向Intel 报告了这些漏洞。

“ZombieLoad”直接的理解就是“僵尸载荷”,即处理器无法理解或正确处理的大量数据,迫使处理器向处理器的微码请求帮助以防止崩溃。应用程序通常只能看到自己的数据,但是这个漏洞允许数据流过这些边界墙。研究人员表示,ZombieLoad将泄漏处理器内核当前加载的所有数据。这意味着,黑客利用的实际上是设计缺陷,而不是注入的恶意代码。

攻击方式

与此前三个侧信道攻击(Meltdown、Spectre与Foreshadow)方式类似,新的攻击方式也是利用处理器的推测执行过程中的漏洞。

此漏洞由此前参与Meltdown、Spectre漏洞研究的部分安全人员以及Bitdefender安全人员联合发现,其实际为微架构数据采样(MDS)攻击,可利用微体系结构中的推测执行操作推断出其他应用在处理器中处理的数据。

Intel 表示,ZombieLoad 包括 4 个漏洞。分别是针对存储缓冲区的攻击(CVE-2018-12126/Fallout)、加载缓冲区(CVE-2018-12127)、行填充缓冲区(CVE-2018-12130/Zombieload/RIDL)以及内存区(CVE-2019-11091)。其中Zombieload是严重性最高的,能够获取最大量且隐秘的数据。

影响范围

自2011年以来发布的所有Intel处理器很可能都会受到影响,尤其是云主机服务可能会受到较大的冲击。同时Intel也指出MDS攻击方式实际上利用难度较高,其实际影响不会有那么大。

漏洞修复

目前Intel已经发布了微代码更新,且新处理器不会受到影响。这其中包括英特尔至强、Broadwell、Sandy Bridge、Skylake 和 Haswell 等芯片型号。Kaby Lake、Coffee Lake、Whiskey Lake 和 Cascade Lake,以及所有的凌动和 Knights 处理器也都受到影响。

目前,苹果、微软和谷歌都已经分别发布补丁。

英特尔对微结构数据采样的分析

微架构数据采样(MDS)的工作原理

MDS可以允许可以在本地执行系统上的代码的恶意用户推断受架构机制保护的数据,虽然使用漏洞“ZombieLoad”在系统上定位特定数据可能很困难,但恶意攻击者可以通过收集和分析大量数据来查找受保护数据。具体过程请参阅《深潜中的MDS表:CPUID枚举和体系结构MSR》,通过这种办法以获取可能受MDS影响的处理器列表。MDS只涉及与一级数据缓存(L1D)以外的微体系结构结构相关的方法,因此不包括异常数据缓存加载(RDCL)或L1终端故障(L1TF)。

MDS推测执行侧通道方法可用来泄露以下微架构结构中的数据:

1.存储缓冲区:用于保存存储地址和数据的临时缓冲区;

2.填充缓冲区:CPU缓存之间的临时缓冲区;

3.加载端口:将数据加载到寄存器时使用的临时缓冲区;

这些结构比L1D小得多,因此可以保存更少的数据,并且更频繁地被覆盖。使用MDS方法来推断与特定内存地址相关的数据也更加困难,这可能需要恶意攻击者收集大量数据并进行分析来查找任何受保护的数据。

新的微代码更新(MCUs)正计划被发布,以帮助程序缓解这些漏洞。Intel建议在切换到以前的程序不可信的程序时更新微代码并清除微架构缓冲区。这些缓解措施将需要对操作系统、虚拟机管理程序和Intel ®程序保护扩展(Intel ®SGX)进行更改和更新。

本文档中的微体系结构详细信息只适用于受MDS技术影响的处理器,而不是所有Intel 处理器的通用处理器。有关受影响的处理器列表,请参阅CPUID枚举和体系结构MSR。

微架构存储缓冲区数据采样(MSBDS)CVE-2018-12126

执行存储操作时,处理器将数据写入称为存储缓冲区的临时微体系结构。这使得处理器能够在将数据写入高速缓存或主内存之前继续执行存储操作之后的指令。另外, I / O写入(例如,OUT)也保存在存储缓冲区中。

当加载操作从与早期存储操作相同的内存地址读取数据时,处理器可以直接从存储缓冲区将数据转发给加载操作,而不是等待从内存或缓存加载数据,这种优化过程就被称为存储库加载转发(store-to-load forwarding)。

在某些条件下,来自存储操作的数据可以从存储缓冲区推测性地转发到针对不同内存地址的故障或辅助加载操作。由于存储的大小小于存储缓冲区宽度,或者尚未执行存储的数据部分,因此存储可能不会覆盖存储缓冲区内的整个数据字段。这些情况可能导致转发的数据包含来自以前存储的数据。由于加载操作将导一个fault/assist1并且其结果也将被丢弃,因此转发的数据不会导致漏洞的程序执行或架构状态更改。但是,恶意攻击者可能能够将这种仅用于推测的数据转发给一个开源的gadget框架(disclosure gadget ),从而允许他们推断出这个值。

MSBDS的跨线程影响

对于受MSBDS影响的处理器,物理内核上的存储数据缓冲区将在该内核上的活动线程上进行静态分区。这意味着具有两个活动线程的内核将有一半的存储缓冲区条目仅用于线程1,一半仅用于另一个线程。当线程进入休眠状态时,其存储缓冲区条目可能会被其他活动线程使用。这会导致以前用于进入睡眠状态的线程(并且可能包含过期数据)的存储缓冲区条目由其他(活动)线程重用。当线程从休眠状态被唤醒时,存储缓冲区将重新被分区。这会导致存储缓冲区将存储缓冲区条目从已经处于活动状态的线程传输到刚刚被唤醒的线程。

微架构填充缓冲数据采样(MFBDS)CVE-2018-12130

填充缓冲区是一个内部结构,用于收集第一级数据缓存丢失的数据。当内存请求丢失L1数据缓存时,处理器会分配一个填充缓冲区来管理对数据高速缓存行的请求。另外,填充缓冲区还会临时管理响应内存或由I / O操作返回或发送的数据。填充缓冲区可以将数据转发到加载操作,也可以将数据写入数据缓存。一旦来自填充缓冲区的数据被写入高速缓存,处理器就会释放填充缓冲区,从而允许在未来的内存操作中重用该条目。

填充缓冲区可能会保留以前内存请求中的过期数据,直到新的内存请求覆盖填充缓冲区。在某些条件下,填充缓冲区可以推测性地将数据(包括过期数据)转发到将导致故障的加载操作。不过,这不会导致程序执行漏洞,因为故障加载永远不会停止,因此不会修改架构状态。然而,开源的 gadget框架可能能够通过侧信道时序分析来推断转发的填充缓冲器条目中的数据。

MFBDS的跨线程影响

填充缓冲区在同一物理内核上的线程之间共享,无需任何分区。因为填充缓冲区是在兄弟线程

线程之间动态分配的,所以填充缓冲区中的过期数据可能属于另一个线程所进行的内存访问。例如,在兄弟线程(sibling thread)上执行不同应用程序的情况下,如果其中一个应用程序处于恶意攻击者的控制之下,则可能在特定条件下使用MFBDS来推断受害者的某些数据通过填充缓冲区的值。

微架构加载端口数据采样(MLPDS)CVE-2018-12127 处理器使用称为加载端口的微架构结构来从内存或I / O执行加载操作,在加载操作期间,加载端口从内存或I / O系统接收数据,然后将该数据提供给寄存器文件和更新的相关操作。在一些实现中,每个加载端口内的回写数据总线可以保留来自以前加载操作的数据值,直到较新的加载操作覆盖该数据为止。

在这些情况下,微架构加载端口数据采样(MLPDS)可以向恶意攻击者显示过期的加载端口数据:

  1. 一个大于64位的故障或辅助(faulting/assisting)向量(SSE/Intel®AVX/Intel®AVX-512);

2.一个跨64字节边界的故障或辅助加载;

在这些情况下,故障/辅助加载操作推测性地提供从内部数据结构到较新的依赖操作的过期数据值。故障/辅助加载操作永远不会停止,因此不会修改架构状态。然而,接收过期数据的新依赖操作可以是开源的 gadget框架的一部分,该开源的 gadget框架可以向恶意攻击者泄露过期的数据。

MLPDS的跨线程影响 加载端口在同一物理内核上的线程之间共享,因为加载端口是在线程之间动态分配的,所以加载端口中的过期数据可能属于另一个线程进行的内存访问。例如,在兄弟线程上执行不同应用程序的情况下,如果其中一个应用程序受恶意攻击者控制,则可能在特定条件下使用MLPDS推断受害者的某些数据通过装载端口的值。

微架构数据采样不可缓存内存(MDSUM)CVE-2019-11091 使用不可缓存(uncacheable ,UC)内存类型的数据访问不会将新行填充到处理器高速缓存中,在受微架构数据采样不可访问内存(MDSUM)影响的处理器上,对不可访问内存进行故障或辅助的加载操作仍然可能从这些内核或数据访问中推测出数据。因为不可缓存的内存访问仍然通过存储缓冲区、填充缓冲区和加载端口移动数据,并且这些数据值可能在故障或辅助加载时被推测性地返回。因此,恶意攻击者可以通过上面讨论的MSBDS,MFBDS和MLPDS机制推测出这些数据值。

微架构数据采样漏洞的缓解措施 硬件缓解

有关受影响的处理器的完整列表,请参阅《深潜中的MDS表:CPUID枚举和体系结构MSR》。

以下MSR枚举使程序能够检查处理器是否受MDS方法的影响:

值为1表示处理器不受RDCL或L1TF的影响。此外,值为1表示处理器不受MFBDS的影响。

· IA32_ARCH_CAPABILTIES [0]:RDCL_NO

· IA32_ARCH_CAPABILITIES [5]:MDS_NO

值为1时表示处理器不受MFBDS / MSBDS / MLPDS / MDSUM的影响。

请注意,如果设置了RDCL_NO或MDS_NO位(或两者都设置了),则可以缓解MFBDS。一些现有处理器也可能仅在加载微代码更新后枚举RDCL_NO或MDS_NO。

受影响的处理器的缓解措施

对于微体系结构数据采样漏洞的缓解措施包括在转换到可能权限较少的执行实体之前,例如,在操作系统(OS)执行IRET或SYSRET指令返回应用程序之前,清除存储缓冲区、填充缓冲区和加载端口。

有两种方法可以覆盖受MDS影响的微体系结构缓冲区:MD_CLEAR功能和程序序列。

处理器支持缓冲区覆盖(MD_CLEAR) Intel 将发布微码更新和枚举MD_CLEAR功能的新处理器。在枚举MD_CLEAR的处理器上,应使用VERW指令或L1D_FLUSH命令使处理器覆盖受MDS影响的缓冲区值,因为这些指令优先于程序序列。

VERW指令和L1D_FLUSH命令将覆盖受MSBDS影响的处理器上当前逻辑处理器的存储缓冲区值,对于受MFBDS影响的处理器,这些指令将覆盖物理内核上所有逻辑处理器的填充缓冲区。对于受MLPDS影响的处理器,这些指令将覆盖物理内核上所有逻辑处理器的加载端口写回总线。受MDSUM影响的处理器也受MFBDS,MSBDS或MLPDS中的一个或多个影响。因此,如上所述覆盖缓冲区也将覆盖包含不可缓存数据的任何缓冲区条目。

VERW缓冲区覆盖细节 VERW指令已经定义为返回一个段是否可以从当前权限级别写入,MD_CLEAR枚举VERW的内存操作数变体(例如,VERW m16)已扩展到覆盖受MDS影响的缓冲区。

VERW的寄存器操作数变体不保证具有这种缓冲区覆盖功能,无论VERW权限检查的结果如何,以及当选择器为空或导致描述符加载段违例时,都会发生缓冲区覆盖。但是,对于最低延迟,Intel建议使用指示有效可写数据段的选择器。

示例用法:


MDS_buff_overwrite():
sub $8, %rsp
mov %ds, (%rsp)
verw (%rsp)
add $8, %rsp
ret

请注意,VERW指令更新EFLAGS寄存器中的ZF位,因此在现有代码中使用上述序列时请务必谨慎。还要注意,VERW指令不能在实际模式或虚拟8086模式下执行。

不管在同一物理内核上的另一个逻辑处理器上执行的是什么,添加到VERW的微代码将正确地覆盖逻辑处理器的所有相关微体系结构缓冲区。

设置推测障碍 一些枚举MD_CLEAR支持的处理器可以在VERW之后立即推测性地执行指令,这种推测性执行可能在VERW缓冲区覆盖功能清除推测指令线程之前发生。

由于这种可能性,应该在调用VERW和执行不能通过MDS观察受保护数据的代码之间设置一种推测障碍。

为了说明这种可能性,请考虑以下指令序列:

1.代码区域A;

  1. VERW m16;

3.代码区域B;

4.推测障碍(例如,LFENCE);

5.代码区域C;

假设可以通过代码区域A中的指令访问受保护的数据,VERW指令覆盖代码区域A中的指令位于受MDS影响的缓冲区中的任何数据。然而,代码区域B中的指令可以在缓冲区覆盖发生之前推测性地执行。因为代码区域C中的加载是在推测障碍之后执行,所以它们将不会通过代码区域A观察位于缓冲区中的受保护数据。

当与VERW一起使用时,以下是在受影响的处理器上为VERW设置合适的推测障碍的示例:

1.LFENCE;

2.当前权限级别的任何更改(例如SYSRET从管理器返回到用户模式);

3.VM的进入或退出;

4.成功进入睡眠状态的MWAIT;

5.WRPKRU指令;

6.在体系结构上序列化指令或事件;

例如,如果OS在从 ring 0转换到 ring 3之前使用VERW,则ring 转换本身就是合适的推测障碍。如果在进程内的安全子域之间使用VERW,则合适的推测障碍可能是VERW; LFENCE序列。

由于篇幅过长,译者将本文差分为两个部分,第二部分敬请期待!