堆溢出利用的精髓是DWORD SHOOT的利用,精准是DWORD SHOOT的优点,但是“火力不足”
常用的狙击目标(XP SP1之前)
- 
内存变量(比如改了后就可以绕过身份验证) 
- 
代码逻辑(分支处的判断逻辑,将身份验证函数的调用修改为nop) 
- 
函数的返回地址(栈上的地址可能不同,这个有一定局限性) 
- 
攻击异常处理机制 
- 
函数指针 
- 
PEB线程同步函数的入口地址 
狙击PRB中的RtlEnterCritical-Section()的函数指针
当进程退出时,ExitProcess要做很多善后工作,必须用到临界区函数
RtlEnterCriticalSection和RtlLeaceCriticalSection来同步线程防止“脏数据”的产生
据说win2000调用临界区函数是peb+0x20的函数指针间接完成的
具体就是0x7ffdf020存着指向RtlEnterCriticalSection的指针
0x7ffdf024存放着指向RtlLeaceCriticalSection的指针
看作者的代码:
#include <windows.h>
char shellcode[]=
"\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\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"
"\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\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"
"\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\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";//200 bytes 0x90
main()
{
HLOCAL h1 = 0, h2 = 0;
HANDLE hp;
hp = HeapCreate(0,0x1000,0x10000);
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,200);
//__asm int 3 //used to break the process
//memcpy(h1,shellcode,200); //normal cpy, used to watch the heap
memcpy(h1,shellcode,0x200); //overflow,0x200=512
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
return 0;
}
首先申请200字节,将0x200(这里作者故意写错,0x200=512)写进去,h1指向的地址处,造成溢出了
超过200字节后的数据将覆盖尾块的块首
用伪造的指针覆盖块首的空表指针,当h2分配的时候造成DWORD SHOOT
DWORD SHOOT目标是修改0x7ffdf020的RtlEnterCriticalSection为shellcode的地址
DWORD SHOOT完毕,对溢出导致异常,调用ExitProcess,
最终指向shellcode
下面的运行结果将上面的0x200改为200,不然200个90后的数据会改变

接下来这样

更改了块首和两个空表指针,当然我们那个要根据自己的电脑来修改,比如我实验就是0x003A000000的堆区的

可以看到修改成功了

继续,还有有点用,但这里的代码有点奇怪, 这里看着是比较块首的大小与0x0114比较

实验失败,哎

