3.3 緩沖區(qū)的組織
3.3.1 緩沖區(qū)的組成
如果選用jmp esp作為定位shellcode的跳板,那么在函數(shù)返回后要根據(jù)緩沖區(qū)大小、所需shellcode長(zhǎng)短等實(shí)際情況靈活地布置緩沖區(qū)。送入緩沖區(qū)的數(shù)據(jù)可以分為以下幾種。
(1)填充物:可以是任何值,但是一般用NOP指令對(duì)應(yīng)的0x90來(lái)填充緩沖區(qū),并把shellcode布置于其后。這樣即使不能準(zhǔn)確地跳轉(zhuǎn)到shellcode的開始,只要能跳進(jìn)填充區(qū),處理器最終也能順序執(zhí)行到shellcode。
(2)淹沒(méi)返回地址的數(shù)據(jù):可以是跳轉(zhuǎn)指令的地址、shellcode起始地址,甚至是一個(gè)近似的shellcode的地址。
(3)shellcode:可執(zhí)行的機(jī)器代碼。
在緩沖區(qū)中怎樣擺放shellcode對(duì)exploit的成功至關(guān)重要。回顧2.4節(jié)的實(shí)驗(yàn)和3.2節(jié)實(shí)驗(yàn)中緩沖區(qū)分布的不同,如圖3.3.1所示。
2.4節(jié)的exploit中,shellcode只有幾十個(gè)字節(jié),我們干脆把它直接放在緩沖區(qū)buffer[44]里,所以shellcode位于函數(shù)返回地址之前。
3.2節(jié)的exploit中,我們使用了跳轉(zhuǎn)指令jmp esp來(lái)定位shellcode,所以在溢出時(shí)我們比2.4節(jié)中多覆蓋了一片內(nèi)存空間,把shellcode恰好布置在函數(shù)返回地址之后。
您會(huì)在稍后發(fā)現(xiàn)把shellcode布置在函數(shù)返回地址之后的好處(不用擔(dān)心自身被壓棧數(shù)據(jù)破壞)。但是,超過(guò)函數(shù)返回地址以后將是前棧幀數(shù)據(jù)(棧的方向,內(nèi)存高址),而一個(gè)實(shí)用的shellcode往往需要幾百個(gè)字節(jié),這樣大范圍地破壞前棧幀數(shù)據(jù)有可能引發(fā)一些其他問(wèn)題。例如,若想在執(zhí)行完shellcode后通過(guò)修復(fù)寄存器的值,讓函數(shù)正常返回繼續(xù)執(zhí)行原程序,就不能隨意破壞前棧幀的數(shù)據(jù)。

圖3.3.1 不同緩沖區(qū)組織方式
當(dāng)緩沖區(qū)較大時(shí),我們傾向于像2.4節(jié)中那樣把shellcode布置在緩沖區(qū)內(nèi)。這樣做有以下好處。
(1)合理利用緩沖區(qū),使攻擊串的總長(zhǎng)度減小:對(duì)于遠(yuǎn)程攻擊,有時(shí)所有數(shù)據(jù)必須包含在一個(gè)數(shù)據(jù)包中!
(2)對(duì)程序破壞小,比較穩(wěn)定:溢出基本發(fā)生在當(dāng)前棧幀內(nèi),不會(huì)大范圍破壞前棧幀。
當(dāng)然,即便是使用跳轉(zhuǎn)指令來(lái)定位shellcode,我們也可以把緩沖區(qū)布置成類似2.4節(jié)中那樣。例如,圖3.3.1中的最后一種組織方式,在返回地址之后再多淹沒(méi)一點(diǎn),并在那里布置一個(gè)僅僅幾個(gè)字節(jié)的“shellcode header”,引導(dǎo)處理器跳轉(zhuǎn)到位于緩沖區(qū)中那一大片真正的shellcode中去。
3.3.2 抬高棧頂保護(hù)shellcode
將shellcode布置在緩沖區(qū)中雖然有不少好處,但是也會(huì)產(chǎn)生問(wèn)題。函數(shù)返回時(shí),當(dāng)前棧幀被彈出,這時(shí)緩沖區(qū)位于棧頂ESP之上的內(nèi)存區(qū)域。在彈出棧幀時(shí)只是改變了ESP寄存器中的值,邏輯上,ESP以上的內(nèi)存空間的數(shù)據(jù)已經(jīng)作廢;物理上,這些數(shù)據(jù)并沒(méi)有被銷毀。如果shellcode中沒(méi)有壓棧指令向棧中寫入數(shù)據(jù)還沒(méi)有太大影響;但如果使用push指令在棧中暫存數(shù)據(jù),壓棧數(shù)據(jù)很可能會(huì)破壞到shellcode本身。這個(gè)過(guò)程如圖3.3.2所示。
當(dāng)緩沖區(qū)相對(duì)shellcode較大時(shí),把shellcode布置在緩沖區(qū)的“前端”(內(nèi)存低址方向),這時(shí)shellcode離棧頂較遠(yuǎn),幾次壓棧可能只會(huì)破壞到一些填充值nop;但是,如果緩沖區(qū)已經(jīng)被shellcode占滿,則shellcode離棧頂比較近,這時(shí)的情況就比較危險(xiǎn)了。

圖3.3.2 棧中的shellcode被破壞
為了使shellcode具有較強(qiáng)的通用性,我們通常會(huì)在shellcode一開始就大范圍抬高棧頂,把shellcode“藏”在棧內(nèi),從而達(dá)到保護(hù)自身安全的目的。這個(gè)過(guò)程如圖3.3.3所示。
3.3.3 使用其他跳轉(zhuǎn)指令
使用jmp esp做“跳板”的方法是最簡(jiǎn)單,也是最常用的定位shellcode的方法。在實(shí)際的漏洞利用過(guò)程中,應(yīng)當(dāng)注意觀察漏洞函數(shù)返回時(shí)所有寄存器的值。往往除了ESP之外,EAX、EBX、ESI等寄存器也會(huì)指向棧頂附近,故在選擇跳轉(zhuǎn)指令地址時(shí)也可以靈活一些,除了jmp esp之外,mov eax、esp和jmp eax等指令序列也可以完成進(jìn)入棧區(qū)的功能。

圖3.3.3 抬高棧頂以保護(hù)shellcode
這里給出常用跳轉(zhuǎn)指令與機(jī)器碼的對(duì)應(yīng)關(guān)系,如表3-3-1所示。
表3-3-1 常用跳轉(zhuǎn)指令與機(jī)器碼的對(duì)應(yīng)關(guān)系
您可以在3.2節(jié)中給出的jmp esp指令地址搜索程序的基礎(chǔ)上稍加修改,方便地搜索出其他跳轉(zhuǎn)指令的地址。
3.3.4 不使用跳轉(zhuǎn)指令
個(gè)別有苛刻的限制條件的漏洞不允許我們使用跳轉(zhuǎn)指令精確定位shellcode,而使用shellcode的靜態(tài)地址來(lái)覆蓋又不夠準(zhǔn)確,這時(shí)我們可以做一個(gè)折中:如果能夠淹沒(méi)大片的內(nèi)存區(qū)域,可以將shellcode布置在一大段nop之后。這時(shí)定位shellcode時(shí),只要能跳進(jìn)這一大片nop中,shellcode就可以最終得到執(zhí)行,如圖3.3.4所示。這種方法好像蒙著眼睛射擊,如果靶子無(wú)比大,那么槍槍命中也不是沒(méi)有可能。
在瀏覽器漏洞利用時(shí),常常采取的Heap Spray技術(shù)用的就是上述的緩沖區(qū)分布思想。Heap Spary技術(shù)會(huì)在后續(xù)的章節(jié)及案例中詳細(xì)討論。
3.3.5 函數(shù)返回地址移位
在一些情況下,返回地址距離緩沖區(qū)的偏移量是不確定的,這時(shí)我們也可以采取前面介紹過(guò)的增加“靶子面積”的方法來(lái)提高exploit的成功率。
如果函數(shù)返回地址的偏移按雙字(DWORD)不定,可以用一片連續(xù)的跳轉(zhuǎn)指令的地址來(lái)覆蓋函數(shù)返回地址,只要其中有一個(gè)能夠成功覆蓋,shellcode就可以得到執(zhí)行。這個(gè)過(guò)程如圖3.3.5所示。

圖3.3.4 擴(kuò)大shellcode面積,提高命中概率

圖3.3.5 大面積“掃射”返回地址
還有一些情況會(huì)更加棘手。考慮由strcat產(chǎn)生的漏洞。
…… strcat(“程序安裝目錄”,輸入字符串); ……
而不同的主機(jī)可能會(huì)有不同的程序安裝目錄。例如:
c:\failwest\ c:\failwestq\ c:\failwestqq\ c:\failwestqqq\
這樣,函數(shù)返回地址距離我們輸入的字符串的偏移在不同的計(jì)算機(jī)上就有可能按照字節(jié)錯(cuò)位,如圖3.3.6所示。

圖3.3.6 按字節(jié)錯(cuò)位引起的定位失敗
圖3.3.6中本想把函數(shù)返回地址覆蓋為0x7C81CDDA處的跳轉(zhuǎn)地址,在本機(jī)調(diào)試通過(guò)后,有可能會(huì)由于其他計(jì)算機(jī)上作為字符串前半部分的程序安裝目錄不同,而使覆蓋的地址錯(cuò)位失效。這樣,我們精心設(shè)計(jì)的exploit在別的計(jì)算機(jī)上可能只有1/4的成功率,通用性大大降低。
解決這種尷尬情況的一個(gè)辦法是使用按字節(jié)相同的雙字跳轉(zhuǎn)地址,甚至可以使用堆中的地址,然后想辦法將shellcode用堆擴(kuò)展的辦法放置在相應(yīng)的區(qū)域。這種heap spray的辦法在IE漏洞的利用中經(jīng)常使用,如圖3.3.7所示。

圖3.3.7 用heap spray部署技術(shù)解決字節(jié)錯(cuò)位問(wèn)題
我們將在第27章中的IE漏洞利用實(shí)驗(yàn)中實(shí)踐這種方法。
- RESTful Java Web Services Security
- 腦洞大開:滲透測(cè)試另類實(shí)戰(zhàn)攻略
- 工業(yè)互聯(lián)網(wǎng)安全
- 等級(jí)保護(hù)測(cè)評(píng)理論及應(yīng)用
- Mastering Kali Linux for Advanced Penetration Testing
- INSTANT Windows PowerShell
- 計(jì)算機(jī)病毒原理與防范(第2版)
- 網(wǎng)絡(luò)安全技術(shù)及應(yīng)用(第3版)
- Testing and Securing Android Studio Applications
- Falco云原生安全:Falco原理、實(shí)踐與擴(kuò)展
- 計(jì)算機(jī)網(wǎng)絡(luò)安全基礎(chǔ)(第5版)
- 信息安全案例教程:技術(shù)與應(yīng)用(第2版)
- SQL Injection Strategies
- 網(wǎng)絡(luò)關(guān)鍵設(shè)備安全檢測(cè)實(shí)施指南
- Mastering Python for Networking and Security