今天介紹raw hammer攻擊的原理;此次有點「標題黨」了。事實上,raw hammer是基於DRAM內存的攻擊;因此理論上,只要是用了DRAM內存的設備,不管是什麼cpu(intel、amd,或則x8六、arm架構),也不管是什麼操做系統(windows、linux、ios、arm等),均可能受到攻擊;常見的raw hanmmer攻擊效果:linux
一、DRAM 原理ios
如右上圖:git
(1)內存最基本的存儲單元是cell。cell裏面最核心的兩個模塊:電容和晶體管;電容充滿電,cell就是1;電容放完電,cell就是0;晶體管用來控制電容充放電;DRAM的D表明dynamic,中文叫動態,說的就是這個;github
(2)DRAM的每一組存儲單元行與列組成的矩陣稱之爲bank,如圖中示例row 0 –row 4組成的矩陣爲一個bank;算法
(3)每個DRAM芯片都包含多個bank, 每個bank都有本身的一塊row-buffer,這個row-buffer實際上是一排靈敏放大器(Sense Amplifier)。在每次訪問內存時,一個存儲單元行會被激活,將整個row的數據保存在row-buffer之中,同時cell放電,而後將row-buffer的上下文寫入原來的存儲單元行之中,cell充電;即便是讀內存,也會致使cell充放電!編程
(4)每一個cell不停的充放電,組成010101的二進制串,這就是最底層數據存儲的基本原理;磁盤上的任何文件在內存都會被編碼成010101的二進制串;canvas
二、row hanmmer原理windows
(1) 近年來,消費者IT設備的要求愈來愈高;設備廠商在不改變內存電路板面積大小的前提下,爲了讓其可以存儲更多的數據,只能將cell的設計越作越多,排列愈來愈近,密度大幅度增長。雖然製做工藝有所提高,但仍是會存在一種假設,那就是相鄰的cell在運行中可能會受到干擾,若是頻繁「轟炸」某兩行(行話稱之爲row),就可能會形成中間一排腹背受敵、上下夾擊,從而出現比特位翻轉,也就是0變成1,1變成0..........緩存
業內把這種上下敲擊的瘋狂操做,稱爲double-sided Rowhammer test,而致使比特位翻轉的這個攻擊方式就叫作Rowhammer攻擊;Row是行,Hammer是反覆敲擊,如此簡潔明瞭,一針見血;以下圖:第一、3行是aggressor行,這兩行中間夾了victim行;兩行aggressor不停地充放電,中間victim行大機率會0~1反轉;安全
上面的圖再細化一下:好比下面9個cell,只有中間是0,周圍全是1,因爲cell之間間隔很小,中間的0大機率會反轉成1。若是周圍全是0,只有中間是1,那麼中間的1大機率會反轉成0;
爲了不這種反轉帶來的數據錯誤,x86計算機使用內存控制器按期刷新電容電量,即指定一個電量閾值0<X<1,對比當前電容量進行刷新操做;X>C時方點,cell=0;C>X時充電,cell=1;內存控制器的刷新時間通常爲64ms,因此基於rwo hammer的攻擊要求在內存刷新的64ms間隔內,加速內存cell的自放電效應,突破內存刷新的判斷閾值,翻轉內存cell的存儲bit,最終bit 1變爲0,bit 0變爲1;
(2) 知道了物理地址,怎麼確認該地址映射到那行row、哪列colume、哪一個bank了?
百度安全實驗室發明基於timing channel的方法(https://cloud.tencent.com/developer/article/1620354 ),大概的思路是:從物理地址高位開始,選擇某個bit不一樣的兩個地址分別讀取數據;若是這兩個地址屬於同一個bank、同一個row,那麼第一個地址在row buffer會有緩存,第二個地址讀的時間會較快,時間差別較大;若是在不一樣的bank,或在同一bank但不一樣row,那麼讀第二個物理地址數據的時候row buffer沒有,先後兩次讀取時間差距不大,由此確認該bit是不是row bit;用相似的思路進一步確認colume bit、bank bit,其最終測試結果以下:
Config表示以下參數:#channel,#DIMM/channel,#rank/DIMM,#bank/rank;
bank address function:好比No.8,bank 地址有4bit組成,一共有2^4=16個bank;每位是括號的這兩個bit異或獲得的,好比第1位就是物理地址中的6和13位異或的結果;
由上表可知:不一樣類型的cpu、不一樣內存大小都有各自的row bit、colume bit、bank bit,狀況比較複雜;官方暫未開放DRAMDig工具下載使用,也未開源,實際效果暫時沒法評測;
三、row hammer利用方法
在64ms的窗口期間,反覆讀取x、y兩行內存地址的數據到寄存器,而後經過cflush清空緩存(保證cpu下次從內存讀),再經過mfence指令保證cflush指令執行完畢;若是x、y兩行地址中間夾了一行V(X\Y\V必須在同一個bank中),那麼V的數據大機率會被反轉;試想:若是V中的某些位是權限控制位了?好比goole project zero自稱成功反轉了PTE的某一位,成功得到了內核權限;
code1a: mov (X), %eax // Read from address X mov (Y), %ebx // Read from address Y clflush (X) // Flush cache for address X clflush (Y) // Flush cache for address Y
mfence jmp code1a
上面的緩存刷新方法須要反覆調用cflush指令,若是把cflush禁止(好比google 沙箱)後該怎麼辦了?
先介紹一下L3 cache:L3 Cache又被稱爲Last Level Cache(LLC),L1是經過虛擬地址來索引的,而L3是經過物理地址進行索引的,下面以典型的Intel core i7 4790處理器爲例介紹L3的結構。i7 4790 L3 Cache由2048個cache set組成,每一個cache set又分爲4個slice(slice和cpu core數量相同,意義對應,好比這裏有4個slice,那麼cpu有4個core),每一個slice由16個cache line組成,所以緩存關聯度爲16(英語稱爲16 way associative);每一個cache line 有64byte,所以緩存總容量爲: 64×16×4×2048=8MiB;(https://bbs.pediy.com/thread-256190.htm 有詳細的介紹)
從物理地址映射關係來看,L3的基本存儲單元是64字節的緩存行,物理地址0~5表示cache line內偏移,6~16位表示set index,一共有2048個set,6~31位通過一個未公開的哈希函數被映射爲slice id,17~31位爲tag位用來標記slice裏面的緩存行;
slice和core的數量一一對應,但core可經過ring bus讀寫每一個slice;換句話說:slice並非某個core獨有的,是全部core共享的;若是core讀取的slice編號不一樣,須要經過ring bus傳輸(準從interl quickpath interconnect協議),耗時會增長1~2 hops;
詳細的物理地址cache mapping方式:(1)根據0~5bit定位到cache line內部的byte偏移,名爲offset; (2) 根據6~16(不一樣cpu的cache size、way等不一樣,這裏會有略微差別)定位cache set,名爲index;以本人intel core-i7 8750爲例, 用cpu-z查是coffee lake架構,L3=9M,12way, cahe line=64byte(0~5位是offset); cache line總數=9M/64byte=147456個;cache set數量=cache line總數/way = 12288,須要17bit, 因此物理地址的6~23bit是index(2)根據tag和set index定位slice id(index未公開hash算法);(4)根據tag定位cache sets裏面的某個cache line(遍歷某個set,取出每一個line的tag挨個對比,和物理地址的tag同樣就是cache hit);這個cache mapping的很重要,後續好多基於時間差的側信道攻擊(prime+probe、flush+reload、flush+flush、evict+reload等等)都要用到這個cache mapping的思路;
當L3 Cache發生cache miss時須要從內存中調取數據進入L3的某個slice,而此時若是slice已滿則會致使某個緩存被寫回(write back)內存,進而騰出空間給新進入的緩存行,這個替換策略就是緩存替換算法。Intel的第二代SandyBridge架構使用的是LRU替換策略,然而從第三代IvyBridge架構開始引入了自適應緩存替換策略(Adaptive Replacement Policies),該策略能夠動態調整緩存替換算法使得L3的動態負載性能最優化。 由以上分析可知,物理地址被映射到某個set的某個slice,若是可以找到其餘16個映射到相同slice的物理地址,使用適當的遍歷策略訪問這16個地址就能夠將這些物理地址驅逐出整個緩存,這種方法能夠達到與clflush指令的相同效果,咱們將這16個地址(一共64byte,恰好是一個cache line)組成的集合稱爲最小驅逐集(Eviction Set);由此引伸出了新的攻擊方法:cache eviction;https://github.com/IAIK/rowhammerjs 這裏有利用eviction的js代碼(相比 clflush 指令更具通常性,它適用於任意系統架構、編程語言及運行環境),感興趣的能夠自行嘗試;
物理內存老是有限的,不可能無限制分配和使用。爲了節約物理內存,操做系統會合並多個相同的物理頁,只保留一份,其他的刪除(32位的windows,每一個進程有4GB的虛擬地址空間,高2GB的內核空間在各個進程都是共享的。一旦修改內核數據,會先拷貝一份,而後修改拷貝的這個頁,這就是所謂的copy-on-write),以節約大量物理內存;該原理衍射了新的攻擊:flip fan shui — 利用內存重複數據刪除實施受控的row hammer攻擊;
以下圖,在雲主機中,通常會有多個虛擬機在同時運行。attacker僞造一個victim內存空間同樣的頁面,底層的操做系統會合並,那麼attacker和victim都指向了同一頁面;attacker再經過row hammer修改victim的內存數據;
以下:空白方格表明空閒頁面,灰色方格表明已分配給頁緩存的頁面,圖 5(a)表示剛開始內存的使用狀況,內存中還有部分空閒頁面,圖 5(b)將 全部的空閒頁面分配給頁緩存,同時將目標頁 B 從內存中驅逐出去,圖 5(c)是將目標頁 B 從新 加載到內存中,這時目標頁 B 會被加載到不一樣 位置的物理內存中,重複圖 5(b)和圖 5(c),直到目標頁B被加載到可以發生位反轉的物理內存位置 X 上;利用該技術,可實現雲端的DDoS 攻擊和本地的提權攻擊;
參考:https://cloud.tencent.com/developer/article/1620354 逆向DRAM地址映射
https://bbs.pediy.com/thread-256190.htm Intel處理器L3 Cache側信道分析研究
https://www.youtube.com/watch?v=rGaF15-ko5w Rowhammer attacks explained simply