第一个缓冲区溢出的全过程实践

前言

这是8月处写的,缓冲区溢出大家估计听了不少了,但是实践过就更好了

为什么会出现缓存区溢出呢?(这里主要针对栈)

简单来说,首先局部变量,返回地址都是储存在栈上的,当我们的输入很长的一串字符,而且程序不检查长度就直接copy到局部变量上,那么局部变量就可以覆盖返回地址,控制漏洞函数的返回地址,从而控制程序的执行(具体实践实例)。

实例实践与分析

首先编译下面的代码,编译用debug版吧

#include <stdio.h>
#include <windows.h>
int overflow_here(char *key){
char buffer[66];
strcpy(buffer, key);
return 0;
}
int main(){
char  key[666];
FILE *fp;
LoadLibrary("user32.dll");
if (!(fp = fopen("key.txt", "rw+"))){
exit(0);
}
fscanf(fp, "%s", key);
overflow_here(key);
printf("come on, overflow me!");
return 0;
}

可以看到漏洞函数overflow_here,直接将我们输入的key copy到buffer那,又没有对长度进行检查

解析一下代码

1.LoadLibrary("user32.dll");  这动态链接库是为我们等一下运行弹框提供支持

2.还有为什么要从文件读取呢,因为我们覆盖返回地址的话,基本都要输入一些不可见字符,在文件中可以用十六进制编辑器区输入

当然还可以用python,perl脚本给程序传递不可见字符

如:

python -c 'print "\x99\x34\x56\x78"' | ./test

当然还可以从网络接收不可见字符

我们开始实验吧

创建一个key.txt,放在exe的同一个目录,我们先在文件中写66A吧,

断在strcpy

我们看到bufferebp-0x44的地方,即ebp-68

我们有两种基本的方法看看要多少个才覆盖,方法一就是根据局部变量的地址算出来,方法二就是看od的栈视图

先看看方法1

那么栈的结构如下

那么我们搞68+4 = 72 A就覆盖到返回值前面,返回地址覆盖成jmp esp的地址,后面就是我们的shellcode

 

方法二:利用od就更加直观啦

接下来寻找jmp esp的地址

若将jmp esp的地址放到返回地址,放到返回地址,那么漏洞函数返回的时候,就返回执行jmp esp,而此时esp指向返回地址的下一个,或者下面几个,看它是retn 4还是retn 8, retn C咯,反正在返回地址后填充多几个nop就肯定行,之后的地址就布置shellcode

插件找jmp esp

我这里利用之前学习写的immunity Debugger的python插件来找jmp esphttp://blog.csdn.net/u012763794/article/details/52174275#t39

用第一个吧

0x77562fbd

手动找jmp esp

或者手动找一波,去dll那里找

blob.png 

blob.png

blob.png 

制作我们的弹框shellcode

在代码中写个MessageBox函数

vc++6.0的调试功能,当然vs2005-2016也是可以的,查看到本机的MessageBox的地址

那就可以在od编写我们的shellcode啦,右边已写注释

选中后二进制复制

一粘贴就是下面的效果

33 DB 53 68 6E 63 68 21 68 74 62 72 61 68 67 69 61 6E 8B C4 53 50 50 53 B8 D6 FC C0 76 FF D0

 

最后用16进制工具编辑成这样(注意我们输入的地址要小端模式哦,即返回地址是字节逆序),那个messageBox代码(即shellcode)就不用逆序了,如果在你电脑上就要看看messageBox的地址是不是我这个了,不是就要改了[我的环境是win 7 64]

od调试看看,可以看到返回地址被我们覆盖了

F9直接让od运行吧,成功弹窗实验成功

 

参考

《0day安全》

打赏
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

第一个缓冲区溢出的全过程实践》上有8条评论

  1. 喻凡

    您好,我按照上面的程序在od中看到66个A填充在返回地址的下方,返回地址上方还是cccc填充,请问是什么原因?

    回复
  2. richard1230

    博主也是搞二进制安全的啊,有机会多跟您交流学习,哈哈

    回复
    1. giantbranch 文章作者

      是的,主要关注二进制,逆向方面的

      回复
  3. Rin

    问一下博主,最近在学0day2,看到第二章第二个修改返回地址的溢出,我是在win7 x86,dev c++下实验的,按书上来说,返回地址上面应该是BP,然后是int变量(4字节),然后是数组(8字节),可是我自己实验后,发现BP上面还有两个不知道是什么的东西,按书上说输入19个字符,把BP和返回地址覆盖,会出现错误,但是我这里不覆盖返回地址,只覆盖BP,也会出现错误,也就是说我即使修改了返回地址,也执行不了,更别提接下来的实验了,请问必须是vc 6.0和xp才能实现吗?还是说有些其它的错误?

    回复
    1. giantbranch 文章作者

      有可能你的编译器默认开启了保护——Canary,覆盖了它就会报错啦

      回复

发表评论