2018年1月5日 星期五

CPU 安全漏洞: Meltdown、Spectre Q&A








有在注意資安的人相信應該已經有看到最近的CPU安全漏洞新聞
一開始是The Register公開此訊息的
後來隨著Google Project Zero也跟著公開技術細節
現在已經隨手就能翻到一篇新聞

這裡列出大家可能會關心的問題和解答
供大家參考



只想知道對自己影響的人
想知道無技術細節內容的人
想知道技術細節的人

只想知道對自己影響的人


Q: 這次CPU事件我個人會受影響嗎?
A: 絕大多數會,除非你不用電腦不用手機

Q: 影響範圍大嗎?
A: 個人影響較輕微、影響最大的是伺服器/雲端廠商

Q: 這漏洞會對我造成什麼問題?
A: 惡意程式能無視你電腦系統的執行權限讀出你儲存的密碼或金鑰

Q: 我該怎麼辦?
A: 下載微軟和IntelPatch來安裝就可以了,Win10已經強制自動安裝
防毒軟體有可能要做相對應的相容性更新



想知道無技術細節內容的人

Q: 這漏洞對寫惡意程式的駭客有什麼幫助?
A: 駭客可以利用這漏洞無視你系統權限,讀取你運作中程式的記憶體資料,不管有沒有被系統保護

Q: 更新防毒軟體有用嗎
A: 問題來自底層的CPU,所以目前防毒軟體無法在這問題上使力
但還是需要更新防毒軟體以相容OS廠商所推出的更新
這裡有相對應的列表
可以檢視自己的防毒軟體需不需要下載相容性更新

Q: 影響了哪些作業系統?
A: Windows, Linux, macOS, AWS, Andriod都中招

Q: 影響哪些CPU?
A: 基本上1995年以後製造的CPU都中招、主要是IntelAMD部分受影響

Q: Windows的Patch要到哪裡下載?
A:

For Win10 版本 1709需要安裝KB4056892
https://support.microsoft.com/en-us/help/4056892/windows-10-update-kb4056892
For Windows 10 LTSB 2016需要安裝KB4056890
https://support.microsoft.com/en-us/help/4056890/windows-10-update-kb4056890
Win8.1是KB4056898
https://support.microsoft.com/en-us/help/4056898/windows-81-update-kb4056898
Win 7是KB4056897
https://support.microsoft.com/en-us/help/4056897/windows-7-update-kb4056897

Q:這Patch對我的系統做了什麼變更?
A:啟用了 Kernel Virtual Address Shadowing,即KPTI
詳細可見後面KPTI的技術原理說明

Q: 我要怎麼用方便的方法看我裝了Patch?
A: 用系統管理員權限啟動Powershell Command line
執行 Install-Module SpeculationControl
然後執行
Get-SpeculationControlSettings

下圖是執行結果


此圖和相關文章出處為
http://bbs.ngacn.cc/read.php?tid=13191483


Q: 聽說上Patch後會有效能上的影響?
A: 會影響、但主要影響較大的是Intel 1995~2013CPU、而且具體影響的是I/O相關的效能
   理論上個人電腦影響不大



想知道技術細節的人


Q: 這次的漏洞是怎麼發現的?
A: Google Project Zero團隊透過Security test發現的
漏洞代號:
CVE-2017-5753
CVE-2017-5715
CVE-2017-5754

Q: 漏洞原理是什麼?
A: 這次的漏洞是CPU架構的缺失加上作業系統未嚴格的隔開Kernel / User space造成的
可以分成以下三種:
Method 1: bounds check bypass (CVE-2017-5753)
Method 2: branch target injection (CVE-2017-5715)
Method 3: rogue data cache load (CVE-2017-5754)

其中 Method12被稱為 Spectre
Method 3被稱為Meltdown

Q: Meltdown的攻擊原理是什麼?
A: 他利用了Intel CPU design裡面out-of-order execution機制的執行漏洞
out-of-order execution是把一個長指令拆成多個短指令讓不同CPU執行以提高效能的方式

這裡用個簡單的例子說明他的漏洞:









這三個assembly指令的意義如下:

1.      把   Kernel space K 的記憶體內容存到 rax
2.      如果   rax 是偶數、把 rax 改成   0,反之則是1
3.      根據   rax 的內容、載入一個userspace的 address+1 或 +0 address 的內容到rbx

理論上來說  這三個指令不管照順序執行或不照順序執行
都會因為指令1access violation而中斷執行

但在多CPU的環境下,如果是某處的CPU先執行指令3?
這時有可能指令3先執行成功
而且根據CPU當時的執行環境
rax的值有可能是當時指向CPU L1 cache的位址
此時就會造成information leak
至於是什麼資訊、可能是瀏覽器的密碼或是你的金鑰
這已經由PoC證實
PoC可以直接讀取Firefox內存的密碼


如果在執行指令3時、CPU有針對該地址做權限檢查的話
此漏洞就不會發生
Intel CPU就是為了效能、沒有做這個檢查

AMD CPU因為架構的不同,沒有此問題

Q: 駭客會怎麼利用這漏洞進行攻擊?
A: 我們用另一段包含攻擊意圖的程式碼說明













rbx 是駭客特意安排的一個探測陣列 (probe array)
這段組合語言類似前面的例子
從第四行起
程式要求系統載入位於kernel space的 1 byte記憶體內容到 rax 的 al 暫存器
在這裡CPU經過權限檢查後會發現這裡的記憶體內容是kernel space
於是產生 exception
但其他CPU有可能已經執行第7行的指令內容
第7行的指令意義如下:

讀取 qword大小的 (rbx + rax)長度指向的地址的記憶體內容並存到 rbx

在out-of-order execution情況下,假設第7行已經先被執行
就算CPU偵測到權限問題而flush registry
CPU也已經讀取了kernel space的記憶體到L1 cache中
只要攻擊者能在CPU raise excpetion並Flush register之前先行轉移L1 cache的話
就能讀取kernel space的記憶體資料並實行成功的攻擊

第5行指令的意思是把 rax shift 0xc bit
駭客需要用這指令把rax的大小擴展 4KB,剛好是一個Page大小
目的在於避免CPU去讀取鄰近位址的Cache
而達不到駭客想要的讀取L1 Cache的效果
他的概念可以如下圖所示








在確定能夠從probe array拿到kernel space的記憶體內容後
攻擊者可以用目前已知的 Flush+Reload 來攻擊Cache來取得位於kernel space的指定內容
至於Flush+Reload的攻擊法可以見此論文


而 retry label在這裡的意義是避免雜訊干擾以增進效能
因為讀取kernel space的動作很可能需要重讀取以確認是否讀到L1 Cache了
在執行到第6行時
CPU會拿EIP的值來檢查 Zero Flag 是否為1,是的話就跳回 retry label指向的位置
之所以要看EIP,是因為 Zero Flag 在這情況下可以用來判斷 CPU 是否真的有去存資料到L1 Cache

在這裡總結下駭客可能的攻擊方式:

1. 駭客用上述指令串讀取到對他而言原本無法讀取到的記憶體內容
2. 根據暫存器指向的位址合法讀取256 = 2^8 = 32Kb大小的L1 Cache
3. 用 Flush+Reload 決定要讀取的Cache Line把記憶體內容讀取出來

只要不斷重複上述動作,駭客可以無視系統權限
把你所有記憶體的內容都 Dump 回去

Q: Spectre 的攻擊原理是什麼?
A: 他的原理非常深入、我這裡只簡單說明概念
所有的CPU都有所謂   Branch Prediction 機制
他的基本原理是同樣執行多次同樣的分支跳轉時
CPU會預期下一次的跳轉並預先執行該跳轉的CPU指令

用一段source code做說明這漏洞的概念



Intel CPUL1 Cache效能手冊我們可以知道
程式在讀取 arr1->length時,如果這值尚未被cache
CPU會投機的先去讀取 arr1->data[untrusted_offset_from_caller]
這時就有可能造成out of bounds read
但因為untrusted_offset_from_caller照條件判斷會小於arr1->length時才進入branch
所以平常不會有影響

可是在下面這情況就會有影響了




如果 arr1->lengtharr2->data[0x200]arr2->data[0x300]都沒被Cached
但其他資料有被Cache而且Branch predictionTrue
這時候CPU會因為投機存取而在arr1->length 未確定前先執行判斷條件為True的以下操作:

1.      arr1->data[untrusted_offset_from_caller]存到value
2.      根據OffsetL1 Cache讀取arr2->data的資料

此時CPU會發現untrusted_offset_from_caller 大於arr1->lengthBranch Prediction不成立
但此時arr2->data[0x200] arr2->data[0x300]都已經被讀入L1 Cache且沒有清除
所以attacker可以根據 index2assign結果從Cache來讀取 arr2->data[0x200]arr2->data[0x300]的資料

因為Branch Prediction各家CPU均有採用且是成熟技術
所以此漏洞影響範圍廣大、Intel AMDARM均被波及
AMD只有在使用者自己打開Linux kernel eBPFJIT才會中招



Q: 要如何修正Meltdown的漏洞?
A: 分成Intel CPUOS廠商兩部分

Intel CPU主要需修正out-of-order execution時對指令權限的檢查
但會喪失一點效能、根據不同的CPU會有5%~40%的效能損失

OS廠商的部分則使用KAISER (kernel address isolation to have side-channels efficiently removed)
後稱做KPTI (Kernel page-table isolation) 來完整隔開Kernal spaceuser space的存取


Q: KPTI的原理是什麼?
A: 具體的做法是在每個process裡多設一個page table,稱為Shadow Pages





其中一個page table、他包含kerneluser spaceaddress
但他只用在進入kernel space時使用
第二個page table就是shadow page,他包含所有user spacemapping address,對於kernel space
他只保留system callcontext switching需要的address tableIDT和部分的kernel trampoline stack

Process在啟動時,shadow page會被active
這時process完全無法讀取kernel space的資料,以此杜絕CPU上的缺陷

Q: 那要如何修正Spectre的漏洞?
A: Spectre的CPU漏洞可說是整個Branch Prediction上的缺陷
要完整修正非常困難,目前廠商仍然在研究解法
但仍能從OS層用 KPTI 加以防堵

Q: Patch後效能損耗的原理是什麼?
A: 從上面KPTI的原理我們可以知道你每次產生interruptsyscallcontext
CR3 register必定需要做多餘的操作
效能的損失便從此而來
受到影響最大的是   context switch 非常頻繁的VM
因此 VM 用量大的雲端廠商很可能受創最深

Q: 已經有人寫出惡意程式攻擊了嗎?
A: 目前除了研究人員的PoC外
尚未有可應用的PoC出現
但隨著大家越來越了解攻擊原理
之後肯定會有人寫出可以實際應用的惡意程式

Q: 有這些漏洞說明的技術文章嗎? 我還想知道更多!
A:
Meltdown:

Spectre:

KPTI:

這些Q&A隨著時間的推移可能會需要更新
如有錯誤或需要更新的地方也請不吝指出,感謝

勘誤: 我發布文章後才發現我 link 的名字meldtown是錯的
請大家別被link名字給誤導了
正確的名字是 meltdown才對
因為沒辦法改了,所以在這裡提醒大家以免混淆