保護與安全

位址空間配置隨機化(address-space layout randomization)

想像一個竊賊,已把一連串一模一樣的旅館的精確格局背得滾瓜爛熟——保險箱永遠在第三個抽屜、備用鑰匙永遠在第二盞燈下。這家旅館連鎖能用很便宜的方式破解他:把每間房的家具各自打亂擺放。如今竊賊背好的地圖派不上用場,只能摸黑亂找。位址空間配置隨機化,ASLR,在記憶體裡對攻擊者做的正是這件事:它在程式每次執行時打亂各部分被載入的位置,使攻擊者再也無法仰賴「知道固定位址」。

許多攻擊,特別是在緩衝區溢位之後,仰賴知道某樣東西的精確位址——攻擊者注入的程式碼坐在哪、或一個有用的程式庫函式要跳去的位址。如果每個程式總是把它的堆疊、堆積、程式庫與程式碼載入到相同、可預測的位址,攻擊者就能把那些數字硬寫進攻擊程式裡。ASLR 藉由在載入時為這些區域挑選隨機的基底偏移來破解這點,於是堆疊今天可能從這裡開始、明天從別處開始,而某個程式庫每次執行都落在無法預測的位址。當攻擊者的酬載猜某個位址時,它幾乎總是猜錯,於是程式當掉而非被挾持——一次被擋下的攻擊,而非一次成功的攻擊。隨機性來自位址裡多餘、未用的位元(即熵),這也是為什麼 ASLR 在「可隨機化的位元很多」的 64 位元系統上,遠比「位元很少」的舊 32 位元系統上強得多。

ASLR 是一種便宜、廣泛、且被大量部署的防禦——它在執行時幾乎不花成本,又能一舉挫敗一大類攻擊。但誠實地說它是個機率性的障礙,而非一堵牆,且有其極限。在 32 位元系統上,隨機位元太少,攻擊者有時能靠反覆嘗試暴力破解出佈局。一個揭露哪怕只是一個真實位址的資訊外洩臭蟲,就能讓攻擊者算出其餘所有位址(因為各區域是整塊一起位移的),使保護瓦解。而任何未以位置無關方式編譯、或被釘在固定位址的程式碼,都留下一座未隨機化的孤島供攻擊者瞄準。這正是為什麼 ASLR 應與不可執行記憶體、堆疊金絲雀並肩運作——縱深防禦——而非單打獨鬥。

某攻擊程式硬寫了一個跳轉,指向它預期位於位址 0x7ffff7a0d2c0 的程式庫函式。沒有 ASLR 時,那位址每次執行都一樣,攻擊就成功。有了 ASLR,程式庫每次執行都被載入到一個全新的隨機基底,於是那個硬寫的位址指向垃圾;程式跳到一個無效之處而當掉,而非執行攻擊者的計畫。

打亂的載入位址,把攻擊者硬寫的跳轉變成了一次當機。

ASLR 是機率性的,而非絕對的:在 32 位元上很弱(隨機位元太少,擋不住暴力破解),且會被「揭露一個真實位址」的資訊外洩擊破,因為各區域是整塊一起移動的。它被設計來與 NX 和金絲雀並用,而非單打獨鬥。

又称
ASLR位址隨機化