[閒聊] 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