沈陽理工大學(xué)信息科學(xué)與工程學(xué)院 高 珊 李愛華 趙曉雯
緩沖區(qū)是程序運(yùn)行期間在內(nèi)存中分配的一個連續(xù)的區(qū)域。所謂緩沖區(qū)溢出,就是向固定長度的緩沖區(qū)中寫入超出其預(yù)告分配長度的內(nèi)容,從而覆蓋了緩沖區(qū)周圍的內(nèi)存空間。攻擊者要實現(xiàn)緩沖區(qū)溢出攻擊,一般都要完成下面三個步驟:
(1)構(gòu)造需要執(zhí)行的代碼shellcode(即緩沖區(qū)溢出攻擊中植入進(jìn)程的代碼,可用來實現(xiàn)特定攻擊或獲取權(quán)限),并將其放到目標(biāo)系統(tǒng)的內(nèi)存;
(2)獲得緩沖區(qū)的大小和定位溢出點(diǎn)ret的位置;
(3)控制程序跳轉(zhuǎn),改變程序流程。
對于緩沖區(qū)溢出攻擊來說,shellcode起到了至關(guān)重要的作用。然而在很多漏洞利用場景中,shellcode的內(nèi)容將會受到限制,通過對其編碼可以在一定程度上解決該問題。
要想突破重重防護(hù),把shellcode安全送入堆棧,不難想到的一個方法就是給shellcode喬裝打扮,讓它通過防守再采取行動。首先設(shè)計好shellcode,然后使用編碼技術(shù)對其進(jìn)行編碼,使它達(dá)到各種限制要求,最后構(gòu)造解碼程序,在真正的shellcode之前加上幾條解碼指令。當(dāng)exploit成功后,首先運(yùn)行頂端的解碼程序,這會將經(jīng)過編碼的shellcode還原成原來的樣子,然后再執(zhí)行。
最簡單的編碼方式莫過于異或運(yùn)算了,該方法所依據(jù)的原理是一個數(shù)與另一個數(shù)做兩次異或運(yùn)算,得到的還是它本身,即A xor B xor B=A??梢酝ㄟ^編程讓shellcode逐個字節(jié)地與某個特定數(shù)據(jù)(key)做異或運(yùn)算,使shellcode的內(nèi)容符合要求。
在編碼時需注意以下幾點(diǎn):
(1)在選取key時,不要選擇shellcode中已有的字節(jié),這樣會導(dǎo)致NULL字節(jié)的出現(xiàn);
(2)可以選擇多個key對shellcode的不同區(qū)域分別進(jìn)行編碼;
(3)可以對shellcode進(jìn)行多輪次的編碼。
有時shellcode或者解碼指令中只是有個別非法字符,那么可以采用微調(diào)法。它就是在不影響指令原本功能的情況下,對不符合要求的指令進(jìn)行等價替換。例如:攻擊IIS的shellcode里不能有0x20,如果想要實現(xiàn)將ebx的值減去0x20,可有兩種不同的表達(dá)方式,一種是直接表示成mov ebx 20h,另一種是采用微調(diào)法表示成mov ebx 32h;sub ebx 12h,這兩種不同的表達(dá)方式實現(xiàn)的功能是相同的,但是第二種方式避免了在代碼中出現(xiàn)0x20。
字符拆分法是把shellcode中的字符拆分成其他幾個符合要求的字符,然后在解碼的時候,再將字符合起來,恢復(fù)成原來的shellcode。
第一種拆分法是把shellcode中的字符拆分成若干個數(shù)字的和,這樣一來就會有很多種拆分方式,可以避免一些限制字符。例如:可將0x20拆分成0x03+0x05+0x06+0x06,解碼時從頭開始每4個字節(jié)一相加,這樣就又恢復(fù)為原來的shellcode。
第二種拆分法是乘積的拆分法,舉例來說就是在編碼時把0xAB拆分成0xA和0xB,解碼時通過0xA*0x10+0xB=0xAB來恢復(fù)。
以上介紹的幾種shellcode編碼方法各有所長,但在實際應(yīng)用中僅僅選擇其中某種編碼方法,很難達(dá)到要求。對此本文提出一種將異或法與微調(diào)法相結(jié)合的編碼方法。異或法最大的優(yōu)點(diǎn)就是編碼和解碼都比較簡單,可以有效的避開一些限制字符,但該方法有一定的適應(yīng)性,比如在經(jīng)過一次或幾次異或編碼之后可能仍存在非法字符,或者解碼指令decode本身就存在非法字符,這時再采取異或法改變key值是解決不了問題的,可以結(jié)合微調(diào)法對shellcode或解碼程序中僅有的幾個非法字符作調(diào)整以滿足要求。
以win2000中文版SP3下開DOS窗口的shellcode為例。由于shellcode中有”x00”,所以首先通過自己編寫的編碼器對shellcode進(jìn)行編碼,異或0x97,這樣得到的enshellcode中就不含有”x00”了,執(zhí)行效果如圖1所示。
圖1 獲得enshellcode結(jié)果圖
編碼之后還需要編寫一段解碼程序decode,其對應(yīng)的匯編代碼如下:
jmp decode_end //獲取enshellcode的地址
decode_start:
pop edx
dec edx
xor ecx,ecx
mov ecx,0x200 //enshellcode的長度0x200足夠
decode_loop:
xor byte ptr[edx+ecx],0x97 //解碼時的key也為0x97
loop decode_loop //循環(huán)實行解碼操作
jmp decode_ok //解碼完畢
decode_end:
call decode_start
decode_ok: //后面接enshellcode
然后可得到decode的機(jī)器碼為:“xEBx10x5Ax4Ax33xC9x66xB9x00x02x80x34x0Ax97xE2xFAxEBx05xE8xEBxFFxFFxFF"。此時,發(fā)現(xiàn)decode中有”x00”,但是再使用異或法改變key值是解決不了問題的。這種情況就需要結(jié)合其他的方法,可以選擇微調(diào)法。經(jīng)分析這是由于匯編代碼中有”0x200”,那么可將其改為”0x201”,就沒有”x00”了。
最后把decode和enshellcode一起送入裝載器測試,結(jié)果如圖2所示。
圖2 執(zhí)行結(jié)果圖
在上述的例子中,首先通過異或法對shellcode編碼起到了避免截斷的效果,之后卻發(fā)現(xiàn)解碼指令decode中還存在不合法字符,這種情況使用異或法改變key值是解決不了問題的,不僅會降低編碼效率,還會影響shellcode的執(zhí)行效果。這時結(jié)合微調(diào)法將decode稍作修改便符合要求了。結(jié)果表明這種經(jīng)過改進(jìn)的編碼方法能夠?qū)崿F(xiàn)shellcode的有效性,提高編碼效率。
基于緩沖區(qū)溢出攻擊研究了幾種shellcode的編碼方法,分析了異或法、微調(diào)法、字符拆分法各自的編碼特點(diǎn)。在此基礎(chǔ)上,提出了一種將異或法與微調(diào)法相結(jié)合的shellcode編碼方法以提高編碼效率。
給出改進(jìn)的shellcode編碼設(shè)計及實現(xiàn),并對測試結(jié)果進(jìn)行了分析,測試結(jié)果表明此shellcode編碼實現(xiàn)了植入代碼的準(zhǔn)確性及有效性,對緩沖區(qū)溢出攻擊的防御研究具有一定的參考價值。