[闲聊] Spectre & Meltdown漏洞概论(翻译)

楼主: b0920075 (Void)   2018-01-05 18:07:31
这是我在推特上看到很多人分享的一串贴文,内容主要是大略讲解Spectre和Meltdown
漏洞利用原理和手法,看下来发现作者讲的通俗易懂,只要学过计算机组织应该都能懂
所以翻译后放在这边让大家快速阅览
原文地址:https://twitter.com/gsuberland/status/948907452786933762
可以朝圣一下XDD
这是我第一次写英文翻译,希望我没翻错然后大家看得懂QQ,有翻错或是语意不明的还请
海涵并告知
有些单字我习惯用英文讲,翻不太出来的也用英文
正文:
学过计算机组织的话就知道当现代处理器遇到conditional branch的时候会先预测branch
怎么走然后先执行,这种特性称为"speculative execution" (投机预测 or 推论预测)
概念是:如果预测正确则此时处理器已经执行下一个指令,会很节省时间。猜错的话就退
回去执行正确的指令
但这个预测不是掷杯一样随机,他必须要有个根据来进行预测,处理器会利用一种叫Bra-
nch History Buffer的空间储存之前这个branch执行的结果。
假设之前遇到这个branch是执行A路径,则下次遇到该branch也会先猜是要执行A路径,不
会跑去执行B路径。
(我印象中计组上课的时候讲的预测算法更复杂一点,不过概念差不多)
有趣的点在于branch后的指令会在判断的statement时就先"spectulatively execute",
这对于安全性来说是至关重要的,所幸大多处理器够聪明,猜错时能消除掉猜错的副作用
并倒带回去执行正确的指令。
但有两个东西不会消除掉:cache和branch prediction history。为什么不跟着消除咧?
原因是speculative execution是提升效能的特性,如果因为消除cache和branch predic-
tion history而降低效能会本末倒置,达不到提升效能的目的
对于这种行为,有三种漏洞利用方法,前两种spectre paper有介绍并可以造成以下效果
1. kernel memory disclosure from userspace on bare metal
这边不是很确定,不过根据我google的结果似乎是说在userspace不借助OS而执
行的程式可以泄漏出kernel memory address
2. kernel memory disclosure of the VM host/hypervisor from kernel space
in a VM
可以在VM的kernel space中泄漏出VM host的Kernel 内存地址
第一种漏洞利用是让kernel去执行使用者精心设计好的code,这段code会包
含阵列边界检查,然后执行阵列读取,当然读取的index是被攻击者所操控。
在linux上有个extended Berkley Packet Filter (eBPF)允许使用者在user mode下实作
一个socket filter,然后经过kernel just-in-time compiled来提升socket在filter
packet上的效率。细节不重要,重点是他透过kernel执行该code
这个漏洞利用写了eBPF的code并且编译后会有以下步骤:
1. allocate两个固定大小的array1、array2
2. 检查由使用者提供的index
3. 检查成功,从该index读取array1
4. 经过运算得到一个bit,根据此bit计算出index2
5. 由index2对array2进行读取
我知道这样有点难懂,所以抄了一段paper后面附的code,希望有好懂些:
unsigned int array1_size = 16;
// step 1
uint8_t array1[160] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
uint8_t array2[256 * 512];
uint8_t temp = 0;
vode victim_function(size_t x)
{
if(x < array1_size) // step 2
temp &= array2[array1[x] * 512]; // step 3 4 5
}
这段code很不完整,不过上面几个步骤都在function里面,对比一下或许比较清楚
严格来说step 5前还有个array2的边界检查,不过这边不打算进行越界读取所以就不多写
就真正执行而言,应该是到step 2的时候超过边界时就不会继续执行下去,但是因为bra-
nch predictor会猜测检查会通过(合理,因为之前检查都是通过的),所以会""spectula-
tively execute"下去执行越界读取然后一直到step 5
精妙的地方来了!step 4时我们经由越界读取得到一个值,这个值经过运算会得到一个bit
,根据这个bit会决定读取哪个地址,比如说如果得到的bit为0就读取0x200的值,如果是1
就读取0x300的值
(这个bit怎么出来的,要看paper,我只看了大概没看很仔细,我猜只是慢慢取最后的bit)
这样确保了0x200或0x300的值已经被存在cache里面(要看得到的bit为0还是1),这时候处
理器也会察觉到自己猜错了,开始倒带并清空副作用......当然前面说过不会把cache和
BHB清掉,所以刚刚读进来的值还是在cache里面!
这时候我们再去读取0x200和0x300的值看看究竟是谁的值保存在cache里面,方法是透过
读取的速度来判定,因为如果值存在cache里面hit到,想必速度会快上很多,有此可知是
谁的值存在cache里,借此判断说刚刚的bit是1还是0,然后慢慢泄漏出整个memory
当然这很简略,还有部分细节如攻击前如何填cache之类,不过这方法可以靠loop慢慢从未
提权的user mode下dump出kernel memory
第二种攻击方式也写在spectre paper里,大概是说用poisoning the branch prediction
history去骗处理器在攻击者设计好的地址上进行"speculative execution"造成上面的攻
击效果
透过谨慎的摆放间接跳转地址,攻击者可以用某种方法填满branch prediction history,
让攻击者进行跳转的时候可以决定哪个branch进行"speculative execution"
(说实话,这有点模糊,我想像起来有点困难......)
This is powerful!如果我知道kernel space有段地址行为跟我们之前提过的eBPF很类似
且我知道该段指令地址的话,就可以间接跳转到那些指令上然后处理器进行"speculative
execution"
对binary exploitation有点概念的话,会觉得这种手法跟ROP很像:寻找kernel space某
段code地址,这些指令的排列刚好可以泄漏出内存地址
不过要注意的是这些execution都是"speculative execution",处理器最后还是会察觉我
没有权限去执行code然后抛出exception,所以我们还是得用之前提过的cache side-chan-
nel来泄漏出kernel data
有经验的人会问说,前面有个前提是要知道指令地址,但是在KASLR(kernel地址随机化)的
保护下很难知道kernel指令地址,对此google project zero写了一篇writeup讲述如何利
用branch prediction和cache side-channel attck来绕过kaslr,所以不讲
传送门:https://goo.gl/SVhWzB
强大的不只这些,这种方法能跨越VM界线!与传统间接跳转(e.g. jmp eax)不一样的是我
可以在vm host kernel用vmcall指令进行speculatively execute
最后还有第三种方法,这种方法涉及flush和reload cache attack来对抗kernel memory
,跟第一种方法很像但不同的地方在于他不用执行kernel code,他完全可以在usermode下
完成
概念大概是:试着用mov instruction读取kernel space的memory,然后把读取的值当成
地址进行第二次读取。如果你觉得第一个mov就会失败因为在user mode下不能读取kernel
mode的data,你是对的!
这边的trick在于,mov在微架构下的实作包含了对memory page的权限level做检查......
没错!这也是个branch指令!处理器也可以进行speculatively execute
所以假设你能逃脱interrupt,你就可以speculatively execute其他指令像read把kernel
data load进cache,然后就像前面提过的攻击手法一样啦~~
想知道更详细更原汁原味的细节请参阅两篇paper:
1. https://meltdownattack.com/meltdown.pdf
2. https://spectreattack.com/spectre.pdf
<完>
我对这些漏洞原理和手法基本上都来自这边,如果要我做更深入介绍恐怕是介绍不出来的
希望之后能拨空把这两篇和blog看懂QQ
大guy4john
作者: airbone0407 (杨区长)   2018-01-06 11:21:00
作者: supermario85 (mario大叔)   2018-01-06 13:05:00
作者: hms5232 (未)   2018-01-06 22:42:00
推个 感谢翻译~电虾板也有很多文章 如果这边看不太懂的人可以去那边爬个有不少简单白话的举例应该可以让没相关背景的人也大致懂
作者: Debian (Debian)   2018-01-07 00:32:00
推荐文章。
作者: kingofage111 (鸵鸟)   2018-01-07 03:04:00
作者: ym7834 (zero0)   2018-01-08 08:55:00
推,谢谢分享~~~

Links booklink

Contact Us: admin [ a t ] ucptt.com