CPU Meltdown和Spectre漏洞分析

1、背景:

         1月4日,国外爆出了整个一代处理器都存在的灾难性漏洞:Meltdown和Spectre。git

几乎影响了全球20年内全部cpu处理器;这两个漏洞可使攻击者经过利用并行运行进程的方式来破坏处理器的特权内存,通俗的来讲:攻击者可以窃取系统中任何数据。github

         目前,全部安全厂商都对这两个漏洞详细信息以及攻击方式进行复现和验证,可是讲解的都很是专业,难懂。因此我从网上搜寻了多个分析文章,结合我的简单理解,提取了以下一些内容,简单介绍下此次的漏洞:数组

(因为本人对硬件技术了解有限以及目前爆出来的资料不是很全面,下面分析内容仅供参考)浏览器

2、简单易懂的描述下这一次的漏洞:

         首先此次的两个漏洞原理比较相似,通俗的比喻一下:缓存

         我想要知道我同事的昨天的行踪,那么我就试探的对同事说:我昨天看见了你和一个女生在一块儿逛街,大家是否是。。。? 虽然我昨天压根儿什么都没看到,可是我说完,他愣了一会(愣神比较久),回了一句:我凭什么要告诉你?!虽然他没有认可,可是显然我已经知道了答案。安全

         此次的漏洞也是同理,利用了CPU的两个特殊的机制:其中Meltdown利用了CPU的乱序执行,Spectre利用了CPU的预测执行。服务器

         Spectre预测执行:在整个OS系统中,某个应用程序(恶意软件)去询问操做系统:“用户刚才登陆的密码第一个数字是1吗?”操做系统回复:“不关你的事,你没有权限知道。”架构

这个过程自己是没有问题的,可是问题出在:操做系统虽然没有明确的回复,可是他内心想了一遍这个答案,尤为是当对方问到一个正确的数字时,他回答的稍微犹豫了几毫秒,这个事情被恶意软件注意到了,就能够经过反复的提问,最后猜到了密码是什么。函数

        Meltdown乱序执行:假设有abc三个地址,其中a地址没有访问的权限,可是b和c能够访问,此时执行下面这个条件表达式:性能

         x= a?b:c

         表面看来,因为a地址没法访问,因此系统会直接报错!但实际上,CPU为了加快执行速度,会采用多流水线做业方式。它会在检查a是否可访问的同时,预先就往下执行了。等到权限检查结果回来,已经根据a的结果完成了b或者c的加载,只是尚未赋给x而已。通过加载的b或者c会在缓存里。虽然报错了,但若是再次访问就会比较快。因而再次访问b和c,根据返回的时间快慢,就能够猜到a的内容!

3、Meltdown(熔断)和Spectre(幽灵)区别:

一、Meltdown依赖于Intel的CPU设计漏洞,在OOO时,忽略对memory权限的检查。

   Spectre则是更严重的漏洞,涉及到近20年的Intel, AMD, Qualcomm厂家和其它ARM的处理器,并且更难修复。

二、官方表述:

         1.Meltdown(熔毁)

         Meltdown破坏了位于用户和操做系统之间的基本隔离,容许恶意代码访问主机任意内存,从而窃取其余应用程序以及操做系统内核的敏感信息。这个漏洞“熔化”了由硬件来实现的安全边界。容许低权限用户级别的应用程序“越界”访问系统级的内存,从而形成数据泄露。

         2.Spectre(幽灵)

         Spectre则是破坏了不一样应用程序之间的隔离。问题的根源在于推测执行(speculative execution),这是一种优化技术,处理器会推测在将来可能执行的指令并预执行。这种技术的目的在于提早准备好计算结果,当这些数据被须要时可当即使用,以提高系统运行效率。内在的缘由是CPU的运行速度大大快于内存的读取速度。在此过程当中,英特尔等CPU没有很好地将低权限的应用程序与访问内核内存分开,这意味着攻击者可使用恶意应用程序来获取应该被隔离的用户级私有数据。

4、漏洞利用方式及影响:

利用方式:

一、云端主机(包括物理机和同机其余虚拟机)的相关敏感数据;对于云服务而言,攻击者会经过租用云服务、利用其自身脆弱性或安装恶意应用程序实施攻击,并可能获取到能够支持云内横向移动的关联数据。因为云服务基本都是在一台服务器上运行多个虚拟机,致使越界访问其余云主机的证书、密码、秘钥等

二、窃取桌面用户敏感信息。对于桌面用户而言,攻击者可从浏览器侧看成攻击入口。目前网上已经验证,经过一段JS代码能够在用户浏览器中成功利用此漏洞。

三、该漏洞对于专有设备的影响,目前还在分析评估中

利用难度:

漏洞利用难度很低。相关漏洞已有成熟PoC代码流出

利用POC验证代码:

 

https://github.com/Eugnis/spectre-attack

 

https://github.com/feruxmax/meltdown

 

https://github.com/gkaindl/meltdown-poc

 

https://github.com/turbo/KPTI-PoC-Collection

漏洞影响:

Windows、Linux、macOS、亚马逊AWS、谷歌安卓均包含在内

Intel、ARM的Cortex-A架构和AMD处理器。Cortex-A目前普遍用于手机SoC平台,包括高通、联发科、三星等等。

漏洞危害:

相关漏洞自己只能读取数据,不能修改数据,但因为其获取的数据中有可能包括口令、证书和其余敏感数据,甚至可以完整copy内存镜像,意味着能够获取全部打开的文件和信息,所以这个漏洞比通常性的虚拟机对云的危害更大。这种攻击对云的安全监测机制几乎不受影响,所以其对云安全、包括私有云,危害极大。

5、漏洞修复:

目前Intel及其余芯片厂商还没有发布修补补丁

但大多数操做系统商(微软、CentOS)和云技术厂商已经发布了临时补丁,但对于系统性能会有影响,须要谨慎评估后再进行修复。

6、专业漏洞解读:

CPU乱序执行和预测执行致使的安全问题

乱序执行(Out-of-Order Execution) [1] 和预测执行(Speculative Execution) [2] 是现代CPU为了提升性能一般采用的优化方式。乱序就是指CPU不按照程序严格规定的前后顺序执行,预测就是CPU基于先有经验预先执行了后续可能执行的代码。传统观念认为,因为CPU在运行过程当中会丢弃乱序执行和预测执行所致使的不正确的运算结果,因此乱序执行和预测执行不会对程序的正确性和安全性形成任何影响。然而,最新的发现代表攻击者彻底能够利用这两种CPU特性进行侧信道攻击。目前已知的Meltdown攻击和Spectre攻击就是两个典型的攻击实例 [3]。

 

从本质上来说,这两种攻击都属于基于CPU缓存(cache)的侧信道攻击的范畴。这种侧信道攻击在最近十年国外的计算机安全研究领域很是流行。它们的基本假设是攻击者在目标主机上拥有必定的执行权限(好比操做系统的一个普通进程,云计算中的一个虚拟主机,或者浏览器中的一段Java代码),而后经过控制本身内存空间的数据(例如读取等等)来间接的控制CPU缓存。因为CPU缓存是攻击者和目标主机上的目标程序共享的,这种对缓存的间接控制能够被攻击者用来推测目标程序的行为。举个例子来讲,若是攻击者和目标程序共享物理内存(好比同一个操做系统的两个程序每每共享同一个动态连接库),攻击者能够反复的利用CPU指令把这块内存的某个地址清除出CPU缓存(Flush阶段),而后在必定的时间间隔后读取这个地址上的内存数据而且测量读取的时间(Reload阶段)。经过这种方式,攻击者能够清楚的知道该地址是否被目标程序读取过,由于一旦目标程序读取该地址,其对应的内存会被导入CPU缓存,从而使得攻击者本身对这个地址的访问变快(因为从缓存读取要远远快于内存)。这种攻击方式被称为Flush+Reload [6]攻击。此外CPU缓存侧信道还有Evict+Time [7], Prime+Probe [8] 等攻击方式。

 

然而,以往的侧信道攻击针对的目标是被攻击者内存读取的模式,例如某条指令是否被执行或者某个数据是否被访问,而不能直接读取被攻击者的内存。而Meltdown攻击[4] 和Spectre攻击[5] 的目标是越权的内存读取,好比读取(dump)整个内核的内存数据。这就使得这种侧信道攻击的后果更加严重。这也是为何这个CPU漏洞会被媒体大肆渲染。下面咱们就对这两种攻击的基本形式和本质作一下介绍。

 

Meltdown攻击

 

Meltdown攻击利用现代CPU中乱序执行 (out-of-order execution)的特性,完全攻破本来由硬件保证的内存隔离,使得一个仅仅具备普通进程权限的攻击者能够用简单的方法来读取内核内存。应该强调一点,Meltdown攻击不是针对KASLR[9]的攻击。攻击KALSR相对要简单不少,由于它的目标仅是获取内核内存的虚拟地址,而Meltdown的攻击目标是获取内核内存的内容。

 

Meltdown攻击的本质是利用CPU进行的安全检查和乱序执行之间的race condition,给攻击者创造一个很短的攻击窗口。乱序执行是指当CPU中的某些指令须要等待某些资源,好比内存读取时,CPU不会在当前指令中止,而是利用空闲的计算能力继续执行后续的指令。这大大地增长了计算能力的利用率,从而提高了CPU性能。在支持乱序执行的CPU上,指令的执行并非顺序进行的。好比后面的指令可能在前面指令执行结束以前就开始执行。然而,为了保证程序的正确性,指令退休(retirement)必须是顺序进行的,而CPU的安全检查是在指令退休时才会进行。这样的结果是,在CPU对某一条指令进行安全检查以前,一部分在该指令后面的指令会因为CPU的乱序执行而被提早执行。例如,一条用户空间的指令访问内核内存会致使CPU抛出异常,然而该异常只有在这条指令退休的时候才会被CPU处理,而因为乱序执行而被提早执行的指令会被CPU丢弃。因为CPU保证程序的正确性,乱序执行本不会产生安全隐患。然而,因为乱序执行的指令对缓存的操做在这些指令被丢弃时不会被重置,攻击者就能够经过缓存侧信道的方式来获取这些乱序执行的信息,从而致使了Meltdown攻击。本质上,Spectre攻击的原理也是同样的。咱们会在后面介绍。

 

如下是一个简化的Meltdown攻击的基本指令:

 

1 ; rcx = kernel address2 ; rbx = probe array3 mov al, byte [rcx]4 shl rax, 0xc5 mov rbx, qword [rbx + rax]

 

首先,在指令3中一个具备用户级权限的攻击者访问目标内核内存地址(存储在寄存器rcx中)。因为访问了内核地址,这一条指令将会触发异常,使得它和它以后的指令对寄存器的修改将被所有丢弃。可是在等待CPU完成执行该指令的同时,后两条指令由于乱序执行实际上已经被执行过了,而且此时的计算是根据指令3所读取到的数据所进行,并不受CPU权限限制。指令4将会把这个数据乘以4096,并在指令5中将其做为offset来对数组probe array进行访问。因为一个内存页的大小是4KB,不一样的数据将会致使不一样的内存页被访问并存放到CPU缓存中。此后,另外一个攻击者进程就能够经过缓存侧信道攻击,来了解哪一个内存页被访问过了,从而推断出被访问的内核内存数据。

 

具体的缓存攻击方式有Flush+Reload [6],Evict+Time [7],或者Prime+Probe [8]。在Meltdown这个场景中(数组probe array是在攻击者本身的内存空间的),比较简单并且有效的攻击方法是Flush+Reload,前面已经描述过其基本思想。简单的讲,Flush+Reload攻击首先把probe array的相对应的内存用clflush指令清除出CPU缓存,而后在执行了上述攻击代码后再逐一访问probe array的各个内存页并记录访问时间。访问时间短说明上述代码执行过程当中CPU已经把对应的内存页加载到缓存中了,缘由是这个内存页对应的offset正好是内核空间中rcx指向的内存内容。

 

总的来讲,Meltdown攻击的指令由两部分组成:第一部分利用乱序执行来访问受限内存,第二部分根据所读取到的数值再编码到内存的访问,并经过缓存侧信道提取信息。攻击的关键在于,乱序执行的这两条指令必须在读取内核内存的指令退休以前,也就是权限审核以前,执行完毕。另外,因为访问受限内存会致使操做系统抛出异常,攻击者能够经过hardware transaction memory等方式抑制异常[11]或者用其余方式处理异常[4],从而反复不间断的对受限内存进行遍历访问。

 

Spectre攻击

 

Spectre攻击利用了CPU的预测执行对系统进行攻击。预测执行是另一种CPU优化特性。在分支指令执行时,因为分支指令执行可能须要内存读取(上百个CPU周期),在分支指令执行结束以前,CPU会预测哪个分支会被运行,提取相应的指令代码并执行,以提升CPU指令流水线的性能。CPU的预测执行是经过分支预测单元(BPU)进行的。简单的理解,BPU储存了某个分支指令最近执行过的分支跳转的结果。CPU的预测执行遇到分支指令时,会根据BPU的预测结果进行跳转。当预测执行发现预测错误时,预测执行的结果将会被丢弃,CPU的状态会被重置。然而,与乱序执行相似,预测执行对CPU缓存的影响会被保留。Spectre和Meltdown攻击在这一点上比较相似。

 

Spectre攻击主要分为三个阶段:

 

准备阶段: 在这一阶段,攻击者经过一些操做来训练CPU的BPU,以使其在运行目标代码时会进行特定的预测执行。同时,攻击者能够执行一些操做来提升预测执行发生的机率,好比把条件判断所需的数据挤出缓存,这样执行分支指令的时间会加长。另外,攻击者也能够在这一阶段作好侧信道的准备工做,好比Flush+Reload攻击中的Flush部分。

 

攻击阶段:攻击者利用CPU的预测执行把目标的机密数据转移到微架构侧信道中。具体的攻击方法咱们下面详细描述。

 

机密数据提取阶段: 经过测量Flush+Reload或其余缓存攻击的方法中Reload内存时间,攻击者能够从缓存侧信道中提取出目标机密数据。这一点跟Meltdown攻击十分类似。

 

在攻击阶段,攻击者利用CPU的预测执行把目标的机密数据转移到微架构侧信道中。常见的分支指令包括条件分支指令和间接分支指令。因此相对的Spectre攻击也有两种不一样的方式。其主要的思想是,攻击者经过控制目标程序的某个变量或者寄存器,使其读取攻击者指定的内存地址。这里攻击者指定的内存地址的内容就是攻击者试图获取的机密数据(好比用户密码)。若是目标程序中含有将这个机密数据做为内存访问的指针或者数组offset,那么攻击者就能够利用缓存侧信道来提取被访问的内存地址,进而提取目标机密数据。

 

攻击的危害

 

本质上讲Meltdown和Spectra都是基于侧信道的攻击,主要用于信息泄露,并不能对目标内存地址进行任意修改。Meltdown攻击每每用于攻击者代码因为权限的限制而不能任意读取其所在的内存地址空间的状况。好比在操做系统中内核内存会被映射到全部普通进程的地址空间,尽管普通进程能够经过虚拟地址访问全部受限内存,包括内核的地址空间,直接访问内核地址会抛出异常而终止。而Meltdown攻击能够帮助攻击者完成这样的操做。在云计算的虚拟机架构上也有相似的问题,使得虚拟机能够经过Meltdown攻击任意读取云服务器宿主机(host)虚拟机管理程序(VMM)的内存地址。而Spectra攻击则利用目标程序的特殊结构,经过系统调用或者函数调用的方式控制其中的某个变量来达到泄漏目标程序(或内核)地址空间中内存内容的目的。好比文献[5]提出了Java代码访问整个浏览器进程内存的方法。而文献[10]提出了利用内核即时编译(Just-in-time compilation)的特性进行提权攻击,正是因为即时编译出得代码具备Spectra攻击所须要的特殊结构。

 

Meltdown攻击所攻击的并非软件漏洞,而是CPU设计自己的安全缺陷。因此Meltdown攻击适用普遍,后果严重。它已经被证实在2010年后发布的Intel桌面及服务器CPU架构上所有可行。实验证实我的计算机和云服务器全都会受到影响,而被成功攻破的操做系统包括Linux,MS Windows,以及包含Docker,LXC,和OpenVZ在内的container。在ARM和AMD处理器上,尽管Meltdown攻击所依赖的硬件漏洞一样被证明存在,目前尚无完整的攻击。可能的缘由包括指令执行过慢,CPU的流水线(Pipeline)太短等等。相比之下,Spectre攻击须要目标程序具备特殊结构,因此受到目标软件的限制。若是目标程序不具备该特殊结构,那么Spectre攻击就很难进行。可是相对于Meltdown攻击目前仅限于Intel处理器上,Spectre攻击适用于Intel,AMD,ARM等众多处理器上。

 

漏洞的防护

 

虽然Meltdown和Spectre是CPU漏洞,短期内很难经过CPU升级来修补漏洞。目前对Meltdown的主要防护手段是以软件彻底隔离用户态和内核态来实现,虽然有分析称这样程序的性能可能会大幅降低。而Spectra的防护就更加困难,借助编译器作程序分析,添加顺序执行指令(好比lfence,cpuid)是一种可能的方案。咱们也会继续跟踪重要厂商对漏洞的修补,并对这些修补方式进行测试。咱们实验室也会研究和开发其余安全技术对这些攻击进行防范。

 

对于通常用户,只要不被执行恶意代码,好比不去访问恶意网站,就不会有不可信代码进入内存执行,就不会被Spectra和Meltdown攻击。因此我的用户仍是能够利用已有的防护手段(好比恶意网站拦截)对本身进行保护。同时也应该及时关注系统软件厂商,好比操做系统厂商和浏览器厂商的补丁而且随时更新。

 

对于在云端,因为攻击者能够租借虚拟环境来执行攻击者想执行的任何代码,因此攻击者能够利用它们去从虚拟机用户态读宿主机的内核态以及虚拟态的关键数据,从而能够攻击其余虚拟机。因此云厂商有责任在第一时间对这些CPU漏洞进行软件修补。企业用户应该采起积极的态度配合或者推进漏洞的控制。

相关文章
相关标签/搜索