csapp buflab

实验题目:buflab
实验目的:搞懂缓冲区溢出原理,以及堆栈的过程,函数调用的实现过程。
实验环境:虚拟机下乌班图32位
实验内容及操作步骤:
首先,我们解压文件:tar xvf buflab-handout.tar.gz
在这里插入图片描述

解压以后在查看一下里面有些什么:通过ll看到里面的文件都是可执行的
在这里插入图片描述

这里可以看到解压以后里面一共就三个文件,结合实验指导书,这三个文件的作用是:
在这里插入图片描述

接下来首先先将bufbomb这个程序通过objdump进行反汇编,生成其汇编代码进行查看。
在这里插入图片描述

和前一个bomb实验一样,我们可以把bufbomb.s文件拖到windows中用notepad++以汇编语言的格式进行查看。
接下来根据自己的userid来生成一个cookie,因为每次运行bufbomb时要用到。
在这里插入图片描述

整个实验是针对getbuf具有的漏洞展开的,getbuf函数类似于gets函数,它是读入一段字符串,字符串以\n或者eof表示结束,并把存储起来。getbuf提供的缓冲区只有32个字符大小,但是getbuf本身又对输入的字符是否超过缓冲区大小进行安全检查,从而带来了缓冲区溢出漏洞。以下就是getbuf函数的代码:在这里插入图片描述

我们分别输入低于32个字符长度和高于32个字符长度。
在这里插入图片描述

可以看到超出的时候就会造成段错误,多出buf的部分就会导致程序的状态被重写,我们正好就可以利用这个漏洞,来编写我们的漏洞利用代码exploit string。

看一下bufbomb的不同的参数的含义。主要用到的就是-u,确保不同的userid用不同的cookie,然后就是-n是为了level4,栈基址随机化模式的时候使用的。-s是上传到服务器进行打分,这个部分是没有的。
在这里插入图片描述

然后我们可以把我们的exploit写到一个txt中,然后给出了几种将我们的txt执行的格式:
在这里插入图片描述

Cat主要是多次提交我们的txt,主要是在level4中会用到,因为level4要求你连续输入5次你的string。然后是一些比较重要的提示事项:
在这里插入图片描述
一个是getbuf遇到换行就会认为输入停止,而换行\n的对应的ASCII值是0x0a,所以不可以输入的字符串中含有0x0a另一个就是说,格式转换要注意每次输入的都是两个数字,比如你要输入0,就要输入00。还有要注意小端格式的输入。
首先,我们进入关卡:
Level 0:
在这里插入图片描述
在这里插入图片描述

通过观察函数,我们发现test函数中对getbuf函数进行了调用。我们要做的就是在调用getbuf函数的时候,我们输入exploit 后,返回的是我们想要调用的smoke函数,而不是test函数的返回值。
这里的实现,我们只需要输入超出缓冲区大小的字符串覆盖getbuf的返回地址的那块地方,并将多余的返回地址用smoke函数的入口地址代替。
在这里插入图片描述
在这里插入图片描述

Getbuf的esp中开辟了0x28的字节,而push ebp占用了四个字节,故getbuf的栈空间总计44个字节。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

我们输入如下指令:./hex2raw <level0.txt |./bufbomb -u syq 可以看出验证成功。

LEVEL1
Level1是和level0一样调用完getbuf以后我们不返回getbuf的调用者test而是去执行fizz函数,区别就是这个fizz函数要求我们传入参数,而且传入的参数必须是我们的cookie。

我们首先找到fizz的函数入口地址:
在这里插入图片描述

此地址为:0x08048daf
根据接下来的两行可以知道:
在这里插入图片描述

传入的参数,存在了ebp+8的位置。这样执行fizz时传入的就是

在这里插入图片描述

如图所示:
在这里插入图片描述

LEVEL 2
任务:这一关是要执行栈中你的指定的特殊指令,设置一个全局变量为我
bufbomb在getbuf()函数返回会执行bang()函数。但是在执行bang()函数之前我们需要设计全局变量global_value为我们自己userid的cookie。
同样地:先得到bang函数的入口地址为:0x08048d52、
因为全局变量要去内存地址中修改了,但是又不能调用个一个可以修改全局变量的函数,这里就只能利用我们的exploit代码了。
接着,我们观察bang的反汇编代码。
在这里插入图片描述

这里我们看到,mov 应该就是把我们的0x804d10c中的全局变量取出来放入eax寄存器中,然后cmp一句可以看出来我们的全局变量与cookie进行比较。
那么我们就要来编写我们的漏洞利用代码了,首先把我们的cookie写到全局变量的地址中,然后在把bang的入口地址入栈,通过ret指令来执行bang函数,这里的push bang的入口地址。
在这里插入图片描述
在这里插入图片描述

查看code.d文件。
在这里插入图片描述

我们就要利用gdb调试找到我们的exploit的地址了,用我们的地址来覆盖返回地址,这样就像我们前面分析的就可以来执行我们的exploit代码了。首先在getbuf函数里面设置断点:
在这里插入图片描述

观察到eax = 0x55683248
于是我们就可以构造相应的level2.txt函数
在这里插入图片描述

执行完后,结果如下:
在这里插入图片描述

LEVEL 3
前面的几个实验都是不管是去执行别的函数比如bang还是去执行我们自己的exploit的函数,最后都没有返回就退出了,我们通过我们的漏洞利用代码可以修改内存(比如把全局变量修改为我们的cookie)修改寄存器中的值,比如当前的level3,我们都把原来的恢复现场需要用的返回地址和原test的ebp给破坏了,这一关中,我们将修复这些被我们破坏的栈状态信息,让最后还是回到test中,

我的基本思路:就是函数调用栈,函数调用结束以后,栈被释放,而返回结果会放在eax寄存器中,这样test这个调用者不需知道调用的getbuf是怎么执行的,只需要到eax寄存器中去取返回值就好了,那么我们就在getbuf执行完以后,再把eax寄存器中的值动手脚修改为我们的cookie就ok了。

同样的,我们先看getbuf函指令执行位置为:0x8049262
调用getbuf()会在栈中保存一个 old %ebp值, 这个值是test函数的%ebp值,这个值需要正确返回.
用GDB调试得到这个值old %ebp为0x55683480.
在这里插入图片描述
在这里插入图片描述

EBP:0x556832a0
然后eip的地址,就是返回地址,也就是test中在call getbuf函数的下一条指令的地址,可以看到call的下一条指令的地址是0x8048e50
因为我们要执行破坏一定会先破坏原栈状态,所以我们只需要在写入的漏洞代码中恢复即可。我在这里用的是覆盖掉原ebp的值不管别的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

至此,我们可以编出level3.txt文件

执行一下:
在这里插入图片描述

level4
任务
(1)确定buf的起始地址范围
(2)获取tesdn函数的正确%ebp指针内容。
(3)确定序列中填充的跳转地址
前面4关在调用getbuf函数时其栈的位置是不变的.这一关调用的是getbufn函数,其目的是为了随机化栈基址。首先来看一下getbufn函数的汇编代码:
在这里插入图片描述

可以看出buf的首地址为 -0x208为十进制520个字节的大小。

但是栈顶的esp是不变的
先通过调试来看一下getbuf里面保存的ebp的值的随机范围为多少。

我们在0x8049247处设置断点,注意与前面不同的是设置为-n模式,然后每次输入一次string来看一下ebp的值,然后continue,再次输入,一共输入5次。run -nu syq
在这里插入图片描述
接下来再来看一下testn的反汇编代码:
在这里插入图片描述

这里我们可以看到,call getbufn的下一条指令的地址为0x8048ce2

还可以看到,mov %esp,%ebp 此时esp和ebp相等

push %ebx 此时ebp=esp+0x4

sub $0x24,%esp 这个时候执行完后,ebp=esp+0x28,这就是esp和ebp每次的变化关系,通过esp来恢复我们的每次的ebp
因此,我们可以写出如下漏洞代码:
在这里插入图片描述
在这里插入图片描述

接下来构造我们的level4.txt exploit sting
Buf一共520个字节空间加上返回地址和ebp一共是528个。用buf的首地址覆盖返回地址。们随便算一个即可,在这里我选的是:0x556830e8
前505个字节都是90,即机器指令空操作nop。
部分截图如下:
在这里插入图片描述

执行一下:
在这里插入图片描述

与前面几关不同的是我们使用了如下的指令.
cat level4.txt | ./hex2raw -n | ./bufbomb -n -u syq
以保证input string 被复制五次每次以\n结尾以结束每次的gets()函数调用。

实验感悟:
通过本次实验,对栈帧结构有了进一步的认识,old ebp和esp是整个实验的关键点。除此之外,gdb的调试,设置断点,进一步熟练。同时,有认识到了一些新指令。实验过程总体上还是比较顺利的,可能因为第一次实验有了经验积累的缘故。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

savkACUNCB: IOnjn

欢迎来到我的世界

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值