
一、windows操作系統(tǒng)中提供的主要幾種軟件漏洞利用的防范技術(shù)
1 ASLR
地址空間分布隨機(jī)化(addressspace layout randomization)是一項(xiàng)通過(guò)將系統(tǒng)關(guān)鍵地址隨機(jī)化,從而使攻擊者無(wú)法獲得需要跳轉(zhuǎn)的精確地址的技術(shù)。

使用ASLR技術(shù)的目的
使用ASLR技術(shù)的目的就是打亂系統(tǒng)中存在的固定地址,使攻擊者很難從進(jìn)程的內(nèi)存空間中找到穩(wěn)定的跳轉(zhuǎn)地址。
執(zhí)行時(shí)間
當(dāng)程序啟動(dòng)將執(zhí)行文件加載到內(nèi)存時(shí),操作系統(tǒng)通過(guò)內(nèi)核模塊提供的ASLR功能,在原來(lái)映像基址的基礎(chǔ)上加上一個(gè)隨機(jī)數(shù)作為新的映像基址。

2 GS stack protection
GS stack protection 技術(shù)是一項(xiàng)棧緩沖區(qū)溢出的檢測(cè)防護(hù)技術(shù)。編譯器會(huì)針對(duì)函數(shù)調(diào)用和返回時(shí)添加保護(hù)和檢測(cè)功能的代碼,在函數(shù)被調(diào)用時(shí),在緩沖區(qū)和函數(shù)返回地址增加一個(gè)32位的隨機(jī)數(shù)security_cookie(用來(lái)檢測(cè)是否發(fā)生的溢出),在函數(shù)返回時(shí),調(diào)用檢查函數(shù)檢查security_cookie的值是否有變換,如果發(fā)生了變換說(shuō)明產(chǎn)生了溢出,終止程序。

GS stack protect 針對(duì)棧溢出起到了很好地防范作用
3 DEP
數(shù)據(jù)執(zhí)行保護(hù)(data execute prevention)技術(shù)可以限制內(nèi)存堆棧區(qū)的代碼為不可執(zhí)行狀態(tài),從而防范溢出后代碼的執(zhí)行。

現(xiàn)在的攻擊主要考慮如何繞過(guò)DEP
DEP分為軟件DEP和硬件DEP,硬件DEP需要cpu的支持,需要CPU在頁(yè)表增加一個(gè)保護(hù)位NX(no excute)來(lái)控制頁(yè)面是否可執(zhí)行。現(xiàn)在的DEP保護(hù)機(jī)制一般都采用硬件DEP。

SafeSEH
用于異常處理的防護(hù)措施
SEH (structured exception handler)是windows異常處理機(jī)制所采用的重要數(shù)據(jù)結(jié)構(gòu)鏈表
發(fā)生異常時(shí),系統(tǒng)調(diào)用異常處理函數(shù),但是這個(gè)異常處理函數(shù)被惡意程序覆寫了。


當(dāng)PE文件被加載時(shí),系統(tǒng)讀出SEH函數(shù)表的地址,使用隨機(jī)數(shù)加密后,存儲(chǔ)在一個(gè)地方,當(dāng)PE文件執(zhí)行時(shí),解密SEH,從而獲得SEH函數(shù)表的地址,然后針對(duì)程序中每個(gè)異常處理函數(shù)檢查是否在合法的SEH函數(shù)表中,如果沒(méi)有則說(shuō)明非法。同時(shí)也要檢測(cè)異常處理函數(shù)是否在棧上,如果在棧上也將停止異常處理。(不能在堆棧中存放可執(zhí)行代碼)
SEHOP
SEH是window異常處理機(jī)制所采用的的重要數(shù)據(jù)鏈表,是一個(gè)SEH函數(shù)表(里面有各種異常處理函數(shù))。
SEH攻擊是通過(guò)棧溢出或者其他漏洞,使精心構(gòu)造的數(shù)據(jù)覆蓋SEH上面的某個(gè)函數(shù)或者多個(gè)函數(shù),從而控制EIP(控制程序執(zhí)行流程)

SEHOP的核心是檢測(cè)程序棧中所有SEH結(jié)構(gòu)鏈表的完整性


漏洞利用技術(shù)——地址利用技術(shù)
1 靜態(tài)shellcode地址的利用技術(shù) (可以準(zhǔn)確定位局部變量位置)
如果存在溢出漏洞的程序,是一個(gè)操作系統(tǒng)每次啟動(dòng)都要加載的程序,操作系統(tǒng)啟動(dòng)時(shí)為其分配的內(nèi)存地址一般是固定的,則函數(shù)調(diào)用時(shí)分配的棧幀地址也是固定的。
溢出后寫入棧幀的shellcode代碼其內(nèi)存地址也是靜態(tài)不變的,所以可以直接將shellcode代碼在棧幀中的靜態(tài)地址覆蓋原有返回地址。
總的來(lái)說(shuō)就是shellcode代碼寫入的地址是靜態(tài)不變的,可以準(zhǔn)確定位到該位置。


2 動(dòng)態(tài)變化的shellcode地址的利用技術(shù) (可以利用esp準(zhǔn)確定位返回地址下面的地址)
某些軟件的漏洞存在于某些動(dòng)態(tài)鏈接庫(kù)中,這些動(dòng)態(tài)鏈接庫(kù)在進(jìn)程運(yùn)行時(shí)被動(dòng)態(tài)加載,因而在下一次這些動(dòng)態(tài)鏈接庫(kù)被重新裝載到內(nèi)存中,其在內(nèi)存中的棧幀地址是動(dòng)態(tài)變化的,則植入的shellcode代碼在內(nèi)存中的起始地址也是變化的。

通過(guò)ESP寄存器的特性來(lái)實(shí)現(xiàn)。ESP寄存器中的棧頂指針總是指向返回地址在內(nèi)存高地址方向的相鄰位置,從而可以實(shí)現(xiàn)準(zhǔn)確定位到返回地址,在與返回地址相鄰的高地址位置寫入shellcode代碼,這樣就能通過(guò)ESP寄存器來(lái)實(shí)現(xiàn)定位shellcode代碼地址
具體實(shí)現(xiàn)步驟:
- 第一步,找到內(nèi)存中任意一條匯編指令jmp esp的地址
- 第二步,設(shè)計(jì)好輸入數(shù)據(jù),使緩沖區(qū)溢出后,前面的內(nèi)容為任意數(shù)據(jù),覆蓋返回地址的是jump esp指令的地址,緊接著覆蓋返回地址下面的地址并寫入shellcode代碼。(之前是在上面寫shellcode代碼,但現(xiàn)在上面的局部變量難以定位)
-
第三位,函數(shù)調(diào)用完成后函數(shù)返回,根據(jù)返回地址中的地址去執(zhí)行jump esp指令,而此時(shí)esp指向的是返回地址相鄰的高地址位置,在這個(gè)位置中保存著shellcode代碼
image.png
image.png
總的來(lái)說(shuō)就是當(dāng)局部變量的局部地址難以定位時(shí),可以利用函數(shù)執(zhí)行完后esp指向返回地址下面的地址的特性來(lái)作為跳板實(shí)現(xiàn)shellcode的準(zhǔn)確定位。


3 堆噴灑技術(shù)heap spray
當(dāng)準(zhǔn)確定位shellcode的地址難以實(shí)現(xiàn)時(shí),可以采用堆噴灑技術(shù)。
heap spary堆噴灑技術(shù),是在shellcode前面加上大量的滑板指令slide code,組成一個(gè)非常長(zhǎng)的注入代碼段。然后向系統(tǒng)申請(qǐng)大量?jī)?nèi)存,并且反復(fù)用這個(gè)注入代碼段來(lái)填充。這樣就使得內(nèi)存空間被大量的注入代碼段所占據(jù)
這樣當(dāng)程序跳轉(zhuǎn)到堆中被填充了注入代碼段的任一地址,程序指令就會(huì)順序滑板指令最終執(zhí)行到shellcode代碼

通過(guò)反反復(fù)復(fù)填充,當(dāng)程序落到滑板指令上時(shí),就會(huì)執(zhí)行shellcode
滑板指令(slide code)是由大量的NOP(no-operation)空指令組成的指令序列,cpu遇到滑板指令會(huì)一直執(zhí)行下去,中間不作任何操作。

網(wǎng)頁(yè)木馬通常使用堆噴灑技術(shù)來(lái)實(shí)現(xiàn)


漏洞利用技術(shù)——繞過(guò)DEP

返回導(dǎo)向編程ROP
利用現(xiàn)成的可執(zhí)行的代碼區(qū)域的指令片段來(lái)組成惡意代碼。

找一些已經(jīng)存在的并且以retn結(jié)尾的代碼塊,把這些代碼塊布置在堆棧上,當(dāng)控制EIP并返回時(shí),程序就會(huì)跳轉(zhuǎn)去執(zhí)行這些代碼塊
換言之,ROP允許攻擊者從已有的庫(kù)或可執(zhí)行文件中提取指令片段,構(gòu)建惡意代碼。


- ROP是通過(guò)ROP鏈(retn)來(lái)實(shí)現(xiàn)有序匯編指令的執(zhí)行
- ROP鏈?zhǔn)怯梢粋€(gè)個(gè)ROP小配件組成
-
ROP小配件是由 “目的執(zhí)行指令+retn指令組成”
retn指令相當(dāng)于 pop EIP EIP指向新的配件的地址
image.png
image.png
ROP技術(shù)成功的關(guān)鍵是從未啟用ASLR的模塊去尋找這些小的配件。




