计系二实验四,缓冲区溢出攻击实验

一、实验内容

本实验设计为一个黑客利用缓冲区溢出技术进行攻击的游戏。我们仅给黑客(同学)提供一个二进制可执行文件bufbomb和部分函数的C代码,不提供每个关卡的源代码。程序运行中有3个关卡,每个关卡需要用户输入正确的缓冲区内容,否则无法通过关卡!

要求同学查看各关卡的要求,运用GDB调试工具和objdump反汇编工具,通过分析汇编代码和相应的栈帧结构,通过缓冲区溢出办法在执行了getbuf()函数返回时作攻击,使之返回到各关卡要求的指定函数中。第一关只需要返回到指定函数,第二关不仅返回到指定函数还需要为该指定函数准备好参数,最后一关要求在返回到指定函数之前执行一段汇编代码完成全局变量的修改。

实验代码bufbomb和相关工具(sendstring/makecookie)的更详细内容请参考“实验四 缓冲区溢出攻击实验.pptx”。

二、实验过程

因为本次实验用到的可执行文件是32位,而实验环境是64位的,需要先安装一个32位的库,在root权限下安装如下所示:
在这里插入图片描述
还需要安装sendmail
在这里插入图片描述

步骤1 返回到smoke()

首先我们需要先明确sendstring程序的作用,即我们将一些字符写入到文本文件后,这个程序会将这些文本转化为二进制数据,且是按照每两个字符表示的2位16进制数作为一个字节的数据进行转化的。

然后我们可以先使用指令:

objdump -d bufbomb > 1.asm

生成对应的反汇编代码,方便我们之后查看指令逻辑。

反汇编代码
在这里插入图片描述
根据前面的提示,我们可以先定位到getbuf函数的起始地址0x08048ad0,然后使用gdb调试程序,并在这个指令那里打下一个断点并运行。在这里插入图片描述
然后进行汇编指令级单步调试时可以发现,程序先把esp寄存器的值赋值给ebp,然后esp -= 0x28,即为函数getbuf生成其对应的栈空间。
在这里插入图片描述
然后我们可以打印得到分配新的栈空间后esp 的新值:

esp旧值
在这里插入图片描述
分配新的栈空间后esp 的新值
在这里插入图片描述
则getbuf函数相关的栈空间大概是这样的:
在这里插入图片描述
然后我们可以先打印出当前还未输入数据时栈帧的内容,然后与输入数据后栈帧的内容进行比对:

输入数据前:
在这里插入图片描述
输入数据后:
在这里插入图片描述
可以发现输入了字符串“123456789”后,内存 0xffffb290~0x0xffffb299 的内存空间的内容发生了变化,可见输入的字符串存储在了 buf 数组中,且 buf 数组的起始地址为 0xffffb290。

由于test()函数调用了getbuf()函数,故我们可以找到getbuf()函数的返回后的返回地址为0x8048db2:
在这里插入图片描述
对比上面的栈帧信息,可以发现0xfffb2ac地址中的内容为getbuf的返回地址,即上面栈帧信息中的最左下角的一项。

那么我们只需要输入7*8=56个随意的字符,然后后面拼接上smoke()函数的首地址即可在getbuf函数返回时跳转到smoke函数中了。

查看smoke函数地址:
在这里插入图片描述
即0x08048eb0,考虑到是小端存储,所以最后拼接的字符串为b08e0408,故总的答案为:

00000000000000000000000000000000000000000000000000000000b08e0408
(前面56个随意的字符都设为0)

修改exploit.txt中的内容为以上字符串:
在这里插入图片描述
最终结果截图
在这里插入图片描述

步骤2 返回到fizz()并准备相应参数

先查看fizz函数的逻辑:
在这里插入图片描述
可以看到这个函数先取了ebp+0x8地址中的值与0x804a1d4中的内容进行比较,如果不相同则失败,而如果相同则可以通关。

因此我们可以先运行程序先查看内存0x804a1d4中的值是什么:
在这里插入图片描述
可以看到这个内存空间的值与我名字对应的cookie值是对应的,而且变量名也叫cookie,所以我们需要为fizz函数准备的参数即为名字对应的cookie值。

所以为了使getbuf返回到fizz函数中,我们和第一题一样先准备56个随意字符(这样直接用0),然后拼接fizz函数的首地址,再添加8个0,最后添加cookie的小端表示的值。(还需添加8个0是因为在fizz函数中取的是ebp+0x8地址中的值,而每个字节需要使用两个字符填充)

所以最终的答案是:
00000000000000000000000000000000000000000000000000000000(56个零)
608e0408(fizz函数首地址小端表示)000000004d4cdf1d(cookie值小端表示)

即:
00000000000000000000000000000000000000000000000000000000608e0408000000004d4cdf1d

运行结果
在这里插入图片描述

步骤3 返回到bang()且修改global_value

首先,为了能精确地指定跳转地址,先在root权限下关闭Linux的内存地址随机化:
在这里插入图片描述
查看bang函数的反汇编代码:
在这里插入图片描述
可以看出bang函数在比较0x804a1c4和0x804a1d4两个内存空间中的内容,若相同则可通关。

使用gdb调试查看这两个空间中的内容:
在这里插入图片描述
可以发现这两个空间都代表一个全局变量,一个是global_value,而另一个则是和上一道题使用过的全局变量cookie,而且我们也已经知道,在程序运行时,这个cookie变量中的值会变化为我们所输入名字的cookie,所以若希望这两个内存空间的值相同,我们只需要将cookie 的值赋值给global_value即可。

而如何才能做到这一点呢,我们若要完成赋值的操作必须使程序能够运行我们所自定义的机器代码,而在这个实验中我们只能操作buf的缓冲区,那么我们只可能将这个赋值语句的代码写入到buf中,然后修改getbuf函数的返回地址为buf数组的首地址,这样就可以运行我们所插入的程序了。

先提前写好修改global_value的程序:
在这里插入图片描述
然后使用gcc将汇编代码编译为机器代码:
在这里插入图片描述
查看机器代码:
在这里插入图片描述
这样我们即可将这些机器代码作为输入先转化为二进制信息然后输入到buf中,最后为了能够执行我们的buf数组中的代码,需要将getbuf函数的返回地址修改为buf数组的首地址。而在解第一题中我们就已经得到了buf数组的首地址了,为:0xffffb290

所以我们可以拼接如下的字符串作为输入:
8b1425d4a10408891425c4a1040868108e0408c3(修改global_value的机器代码)0000000000000000(占位的随意字符)90b2ffff(buf数组的首地址的小端表示)

即:
8b1425d4a10408891425c4a1040868108e0408c3000000000000000090b2ffff

运行结果
在这里插入图片描述
至此,三道题解答完成!

(注意,完成这个实验时,这个程序会按照输入的名字来使用不同的地址的栈空间的【应该是根据名字对应的cookie进行生成】,所以如果使用了其他的名字字符串,解答所需要的输入也会随之变化)

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值