处理器Meltdown(熔断)和Spectre(幽灵)漏洞分析

Meltdown

Meltdown攻击利用现代CPU中乱序执行 (out-of-order execution)的特性,乱序执行(out-of-order execution)是指CPU允许将多条指令不按程序规定的顺序分开发送给各CPU单元处理的技术,我们通过参考资料[2]中的示例代码来说明这一攻击的原理。

一个简化的Meltdown攻击指令序列:

1、rcx寄存器指向用户代码不可访问的内核地址

2、攻击者在指令4中访问内核内存地址,由于访问了内核地址,这一条指令将会触发异常,但由于指令4在CPU内部执行时并不受权限检测,所以读取到的内核数据被存放在了CPU缓存中

3、在等待CPU完成执行指令4的同时,后两条指令因为乱序执行机制实际上已经在CPU的内部执行单元中被执行

4、在CPU内部执行单元执行过的指令5将会把获取到的内核数据(1个字节)乘以4096,并在指令6中将其作为offset来对数组probe array进行访问

5、由于一个内存页的大小是4KB,不同的数据将会导致不同的内存页被访问并存放到CPU缓存中,所以,另一个攻击者进程(任务)就可以通过缓存侧信道攻击(已经被缓存的内存读取时间会更快),来了解哪个内存页被访问过了,从而推断出被访问的内核内存数据。

Spectre

Spectre攻击利用了现代CPU中推测执行(Speculative Execution)的机制来对系统进行攻击。推测执行(Speculative Execution)同样是一种CPU优化特性。在执行类似if () {}这类分支指令,并且在分支指令执行结束之前,CPU会预测哪一个分支会被运行,提取相应的指令代码并执行,以提高CPU指令执行的性能。当预测执行发现预测错误时,预测执行的结果将会被丢弃,CPU的状态会被重置。然而,与乱序执行类似,预测执行时CPU获取到的内存数据会被保留在CPU缓存中(包括越权获取的数据,虽然这些数据用户代码无权访问),我们通过参考资料[3]中的示例代码来说明这一攻击的原理。

1、首先申请一块内存,并写入如下数据

2、获取secret和array1的相对偏移量malicious_x

3、循环调用readMemoryByte函数,分别将malicious递增值作为其中一个参数

4、调用漏洞函数victim_function,利用CPU的预测执行机制将越权读取的数据cache到CPU缓存中

5、由于array2[array1[x]*512]的值被缓存,所以代码中通过rdtscp函数计算指令执行时间来判断哪个内存页被访问过(缓存的字节被当做另一系列被预测执行指令访问的数组下标,被访问的数组同样是在CPU中被预测读取),从而推断出被访问的secret内存数据

6、POC验证执行结果,读取进程内的机密数据

限制条件

本质上讲Meltdown和Spectra都是基于侧信道的攻击,主要用于信息泄露,并不能对目标内存地址进行任意修改,以下分别介绍两种攻击的限制条件。

Meltdown

Meltdown攻击目前仅限于在Intel系列的现代CPU中访问受限内存,包括内核的地址空间
由于Meltdown攻击所使用的特殊代码无法在浏览器JIT中生成,所以该攻击几乎只能在本地进行
Spectre

Spectre攻击需要目标程序具有特殊结构(比如浏览器JIT即时编译出的代码具有Spectra攻击所需要的特殊结构),所以受到目标软件的限制
Spectre攻击虽然适用于远程攻击,但是浏览器类JIT代码生成的Spectra攻击只能获取当前进程的内存数据,无法获取内核数据
Spectre攻击在Intel系列CPU上也可以读取目标内核内存数据
Meltdown和Spectre影响/防御对比

我们整理下两类攻击的影响范围和防御方式,如下:

Meltdown Spectre
读取系统内核层数据 是 是(测试Intel CPU)
通过KAISER/KTPI技术修复 是 否
读取任意用户层数据 是 是
远程攻击 极难 容易
主要影响范围 内核所有数据 浏览器进程数据
受影响CPU厂商 Intel Intel AMD ARM等
参考资料

[1] https://meltdownattack.com/meltdown.pdf

[2] https://spectreattack.com/spectre.pdf

[3] https://github.com/Pl4gue/spectre-attack-demo

发表评论

邮箱地址不会被公开。 必填项已用*标注