专家解读系列 | 深入分析 Meltdown 安全漏洞(CVE-2017-5754)V01

783 阅读7分钟
原文链接: mp.weixin.qq.com

上图为 Google Search Meltdown 安全漏洞搜索结果

划重点

从今天起阿里系统软件技术将开辟新一期专题——专家解读系列,希望将最有价值的技术解读分享给社区,一起朝着技术让生活更美好努力。第一期嘉宾是来自阿里巴巴集团操作系统团队的技术专家乾越,他将用三期的内容从各个层面深入分析 Meltdown 安全漏洞,以及欢迎大家关注「阿里巴巴内核圈」微信公众号直接和作者取得联系

介绍

Meltdown安全漏洞允许以非特权用户身份运行的恶意代码“越界”访问系统内存从而造成敏感数据泄漏。该漏洞“熔化”了由硬件提供和设置的地址空间隔离与安全边界,Meltdown(熔断攻击)因此得名。

本质上,Meltdown利用了Intel处理器微架构层中的乱序执行的副作用来读取操作系统内核或PV Hypervisor中的任意敏感数据。因此,Meltdown独立于操作系统和软件环境,也不依赖于任何软件漏洞,纯粹地在利用处理器硬件自身的安全漏洞。

从危害性上讲,Meltdown破坏了用户态与内核态以及Guest OS与PV Hypervisor之间最基本的地址空间隔离机制,允许用户态或Guest OS中的恶意代码访问内核态或PV Hypervisor中的内存,这是一种典型的跨域攻击。

出于性能考量,绝大多数操作系统内核或PV Hypervisor都在内核态地址空间中实现了对物理内存的直接映射,因此利用Meltdown漏洞的恶意代码不仅可以窃取内核或PV Hypervisor自身的敏感数据,而且还可以通过物理内存直接映射窃取其他应用程序、容器或其他Guest OS中的敏感数据。

本文主要讲解针对Intel处理器上的Meltdown攻击的工作原理。

攻击路径

  • 由恶意代码控制的非特权进程可以利用Meltdown漏洞读取内核或其他进程中的敏感数据。

    • Host OS和HVM Guest OS中的内核空间均受到Meltdown的影响。

  • 由恶意代码控制的Guest OS可以利用Meltdown漏洞读取PV Hypervisor或其他Guest OS中的敏感数据。

为了叙述方便,将Meltdown攻击的对象 - Host OS和HVM Guest OS中的操作系统内核,以及PV Hypervisor统称为内核。

Meltdown原理分析

恶意代码的构成

发起Meltdown攻击的恶意代码包括以下3个基本构件:

  • 构造隐秘信道

  • 通过隐秘信道发送内核敏感数据

  • 从隐秘信道中接收并还原内核敏感数据

构造隐秘信道

利用Flush+Reload侧信道分析原语来构造一个低噪声且快速的隐秘信道。该信道由发送器和接收器两部分组成。发送器代码由前序指令序列和核心攻击代码序列组成,主要作用是发送内核敏感数据;接收器代码则用于从隐秘信道中接收来自发送器发送的内核敏感数据,并还原出原始的内核敏感数据的内容。

处理page fault异常

因为Meltdown漏洞的核心代码需要直接对内核敏感数据所在的地址发起越权访问,并因此触发page fault异常,同时内核会向引起page fault异常的进程发送SIGSEGV信号。如果没有事先注册过SIGSEGV信号处理函数的话,收到SIGSEGV信号的进程会被立刻杀死。为了确保恶意代码能够继续运行,就需要事先设置SIGSEGV信号处理函数以便在触发page fault异常时捕获该信号。

建立probe array

probe array是一个包含了256个4K页大小的数组。之所以选4K页大小是为了避免内存预读引入的额外的加载延迟。因为在每次访问内存的时候,根据局部性原理,硬件有可能将相邻的内存也读进来,而Intel的优化手册写明是不会发生跨页预读的。发送器和接收器都可以利用内核敏感数据作为probe array下标规则地访问probe array数组。

在准备阶段,需要按照Flush+Reload侧信道分析原语将probe array对应的256个cache line全部flush掉。

通过隐秘信道发送内核敏感数据

下面是隐秘信道发送器的代码:

.rept 300
add $0x141, %rax
.endr

movzx (%rcx), %rax
shl $12, %rax
movq (%rbx, %rax), %rbi

其中前面300条指令是通过汇编器宏构造的前序指令序列,作用是为了造成流水线阻塞(详见后文的分析)。后面3条指令是核心攻击代码序列,其中rcx寄存器包含的是一个有效的内核态虚拟地址;rbx寄存器代表的是恶意代码控制的probe array的基地址。

这段代码序列的功能非常简单。movzx读取内核敏感数据,然后shl指令将敏感数据转换为页偏移(每个页大小为4096字节),最后movq指令将页偏移作为probe array的下标,并将probe array中的数据加载到rbx寄存器中,同时也意味着以敏感数据作为下标的cache line被加载到了D-cache中。

在执行movzx指令时,由于访问的内核态虚拟地址对应的页表项已经事先被设置为特权级,因此该指令会触发处理器的page fault异常,page fault异常处理函数会检查引起page fault异常的地址的合法性。由于恶意代码是在用户态对内核态地址发起的越权访问,因此page fault异常处理函数向引起异常的进程发送SIGSEGV信号。

从处理器的架构层角度来看,上述行为完全遵循着硬件所设计的地址空间安全隔离机制的运作机理,而且也与我们在处理器架构层观察到的结果完全一致 - 即内核中的敏感数据是不可能被恶意代码直接读取到的。但实际上,在满足多个特定条件的前提下,内核中的敏感数据是可以被恶意代码间接读取到的,这正是Meltdown漏洞的危害所在 - 恶意代码无需特权,就可以访问到内核中的任意敏感数据。

从隐秘信道接收并还原内核敏感数据

发送器已经利用内核敏感数据作为probe array的下标并将对应的cache line加载到了D-cache中,因此接收器会尝试访问probe array包含的所有的256个cache line,同时对执行时间进行度量,利用统计学方法找出访问时间最短的cache line所对应的下标,而下标就是内核敏感数据的内容。这正是Flush+Reload侧信道分析法中Reload操作的精髓,本质上利用原本无法直接访问到的内核敏感数据来造成恶意代码可以观察到的影响,进而根据这种影响推导出内核敏感数据的内容。

下期预告

  • 核心攻击代码序列在微架构层中的运行过程详解

阿里系统软件技术

长按下方二维码关注我们

对计算机技术的追求

让我们永远年轻

点击阅读原文关注阿里巴巴内核圈