buflab实验

一:准备工作

1,三个二进制文件

bufbomb:一个有缓冲区溢出漏洞的程序。

makecookie:可以根据用户不同的userid生成的唯一的cookie,userid不同,cookie不同,所要解决的方法就不同。

hex2raw:使编写的缓冲区利用代码的转换为一个字符串的格式,只有经过转换以后才可以输入到getbuf中。

2,生成cookie的方法

3,bufbomb函数原型及介绍

getbuf函数类似于gets函数,它是读入一段字符串,字符串以\n或者eof表示结束,并把存储起来,但是getbuf提供的缓冲区只有32个字符大小,但是getbuf本身又对输入的字符是否超过缓冲区大小进行安全检查,从而带来了缓冲区溢出漏洞。

使用方法:

参数:

-u,确保不同的userid用不同的cookie。

-n,为了level4,栈基址随机化模式的时候使用。

-s,上传到服务器进行打分。

4,提交方式

5,提示

二:实验

Level 0:

实验描述:

test函数调用getbuf函数,调用完以后还返回test函数,现在我们要做的是调用getbuf函数后,通过输入我们的exploit,使得调用完以后不返回test函数了而是执行smoke函数。

test函数:

解决方法:

反汇编:

在反汇编结果中找到getbuf函数,smoke函数:

Getbuf函数:

画出test函数调用getbuf函数的栈帧结构:

由反汇编结果可知,给输入的字符串分配的空间是从%ebp-0x28开始的,换为10进制就是40个字节,而返回地址是在%ebp+0x4处,push %ebp本身又占了四个字节,所以结构为:


返回地址

4字节


Getbuf的,从%ebp到输入字符串的空间为44个字节

Smoke函数:

由反汇编可得smoke函数的入口地址为0x08048e0a

综上,我们需要做的就是把上面的44个字节随意填满(不要填换行),然后把原来的返回地址改为smoke函数的入口地址。0x0a是换行\n的ASCII值,所以不可以输入,那么我们就输入0x8048e0b来代替。

Level1:

实验描述:

test函数调用getbuf函数,调用完getbuf以后不返回getbuf的调用者test而是去执行fizz函数。fizz函数要求传入参数,参数必须是cookie。

fizz函数:

解决方法:

反汇编bufbomb找到fizz函数:

和level0类似,通过上一题已经知道了栈帧结构,所以我们需要做的还是把那44个字节填满,然后再填写fizz函数的入口地址(0x08048daf)用来覆盖原来的返回地址。

关键:找到fizz函数的参数从栈中的什么地方传入的,然后我们把我们的cookie写进这个fizz会获取参数的地方。实参只在主调函数中有效,形参只在被调函数中有效,我们要做的就是修改实参,它的位置就是在返回地址的上面4个单位。而返回地址已经被我们破坏,会默认它上面四个字节为返回地址,然后再向上4个字节来取参数。

执行leave后

所以答案如下:

Level2:

实验描述:

执行完getbuf()后,不返回到test,而是去执行函数bang,但是区别是bang也要传入参数,且参数是是一个全局变量。

bang函数:

解决方法:

反汇编:

看bang函数的反汇编代码

可以看到,bang、函数的入口地址为0x08048d52.

接下来要做的就是改变全局变量global_value的值,使他的值为cookie

由汇编代码,第四行 mov 0x804d10c,%eax 可以知道,global_value存放的位置是0x804d10c

由此写下汇编代码:

首先把我们的cookie写到全局变量的地址中,然后在把bang的入口地址入栈,通过ret指令来执行bang函数

然后把.s文件变成字节码:

利用gdb调试找到我们的exploit的地址了,用我们的地址来覆盖返回地址,从而执行我们的代码。

所以答案如下:

Level3:

修改getbuf()函数的返回值(正常状态为0x1)为你的cookie值,然后让函数正常返回到test.

解决方法:

函数调用栈,函数调用结束以后,栈被释放,而返回结果会放在eax寄存器中。test不需知道调用的getbuf是怎么执行的,只需要到eax寄存器中去取返回值,所以可以在getbuf执行完以后,再把eax寄存器中的值动手脚修改为cookie。

有关栈的恢复:需要两个部分,一个是ebp一个是eip的地址,一个是恢复pop出test的原ebp,所以在破坏之前,用gdb调试出来test的原ebp是多少记录下来,恢复的时候在赋值给它。

用gdb来调试得到ebp的值:

原test的ebp是0x556839f0

eip的地址,就是返回地址,也就是test中在callgetbuf函数的下一条指令的地址:

call的下一条指令的地址是0x8048e50

所以.s代码:

%eax的值改为cookie

%ebp的恢复,改成0x556839f0

把下一条指令地址0x8048e50压入

返回

将.s文件变成字节码:

所以答案是:

第一句 第三句 ret

填充0

%ebp恢复

自己的返回地址

Level4:

调用getbufn函数,

其缓冲区大小为512个字节, 且每次栈的位置都会变化

nop只是执行eip自加1不进行其他的操作。在无法猜测的时候,只需要找到最大的地址。

解决方法:

反汇编,查看getbufn反汇编结果。

buf的首地址为-0x208(%ebp)为十进制520个字节大小。

每次运行testn的ebp都不同,所以每次getbufn里面保存的test的ebp也是随机的,但是栈顶的esp是不变的,我们就要找到每次随机的ebp与esp之间的关系来恢复ebp。我们先通过调试来看一下getbuf里面保存的ebp的值的随机范围为多少。

ebp的值              减去0x208为buf的首地址

0x556839c0             0x556837b8

0x556839f0             0x556837e8

0x55683970             0x55683768

0x556839f0             0x556837e8

0x55683950             0x55683748

看testn的反汇编代码:

call getbufn的下一条指令的地址为0x8048ce2

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

push  %ebx  此时ebp=esp+0x4

sub   $0x24,%esp 这个时候执行完后,ebp=esp+0x28,这就是esp和ebp每次的变化关系,通过esp来恢复我们的每次的ebp

由此写出以下汇编代码:

将.s文件变成字节码:

509个nop

15个字节码,覆盖篡改保存ebp

Buf首地址覆盖返回地址,是可能的最大的首地址

三:总结

要想做明白这个实验,就需要弄懂缓冲区溢出原理,以及堆栈的过程,函数调用的实现过程,函数传参的底层实现等问题。并且,光理解原理也还远远不够,还需要会应用。本次实验的几个level是逐步跟进的,一点一点的深入。Level0只需要理解原理,进行覆盖地址,level1是修改参数,level2是修改全局变量,level3是恢复栈结构,level4是在level3第基础上实现随机化。在实验的过程中还需要注意避免输入换行对应的数字码等等。

另外,在做本次实验的过程中还遇到一个比较特别的问题,这个问题很隐蔽,难以发现,花费了很久才找到。在将自己写的code4.s汇编的过程中,出现了机器码生成错误的问题,mov指令对应的机器码应该是b8,而在我的机器中,level4,却生成了a1,至今还不知道为什么会出现这个问题。在与其他同学交流的过程中,发现其他同学也有过这种情况,是push指令对应的机器码发生了错误。

截图如下:

时间: 2024-08-22 20:17:27

buflab实验的相关文章

CSAPP缓冲区溢出实验记录(二)

Level 2: firecracker(30分) bufbomb中存在一个bang函数, int global_value = 0; void bang(int val) {     if (global_value == cookie) {         printf("Bang!: You set global_value to 0x%x\n", global_value);         validate(2); } else     printf("Misfir

CSAPP缓冲区溢出实验记录(一)

题目说明: 开启漏洞之旅,从基础做起.近日,下载了CMU为<深入理解计算机系统>(CSAPP)一书教学配合的缓冲区溢出实验Buffer Bomb,重温了栈溢出的原理. 题目提供了一个有漏洞溢出的程序bufbomb,包括五个Level,在每个Level中要求返回指定的函数.修改全局变量.执行Shellcode等,难度逐渐递增.为保证实验者作业的唯一性,实验提供了程序makecookie,生成指定用户名的cookie,在实验中将会用到这个cookie值.在我的机器上, [email protect

CSAPP缓冲区溢出实验记录(三)

Level 5 Nitroglycerin (10 分) 题目说明:这一关是一道加分题.在bufbomb程序中还有一个'-n'的选项,使用这个选项时,bufbomb会运行Nitro模式,此时程序不会调用getbuf,而是调用getbufn: int getbufn() {     char buf[512];     Gets(buf);     return 1; } 这个函数与getbuf所不同的是,分配了512字节的字符数组,而调用getbufn的函数会在栈中随机分配一段存储区,这导致ge

如何使用GNS3和Cisco IOU搭建路由交换实验-IOU篇

前面介绍了GNS3的概念,安装,配置和使用,本篇将介绍怎么利用GNS3配置IOU从而实现使用GNS3和Cisco IOU搭建路由交换实验. 由于本篇篇幅较长,所以先过一下大纲: 1. IOU模拟环境介绍 2. IOU软件环境的准备 3. VMware虚拟机的安装.导入和配置 4. IOU镜像的上传 5. GNS3的配置 6. IOU模拟环境的实现 IOU模拟环境介绍 IOU即IOS running in Unix,最初是由思科内部人员开发来测试IOS的平台,后来流传到互联网经网友改进有了后来的W

广外第二周的实验报告来这里分享一下

虽然有很多还不知道怎么改,可能也有很多测试不到的地方,但是通过这个星期我好歹了解了好多东西啊 实验报告 通过本次学习,能了解到VC6.0.是用于将已生成的C++语言源程序代码转换为计算机能读懂的目标代码,计算机用的均是二进制代码.编辑完成后它首先生成扩展名为obj的文件(程序编译后的二进制文件),若想进行之后的链接.运行过程,必须不断修改源程序文件至完全正确. 在文件→新建→源代码这里可以新建源代码:新建→打开项目或文件中可以打开以前写过的源代码或者程序:运行→编译中即把所打源文件转换为二进制代

webservice实验一

实验目的:安装jdk1.6_21以后的版本,利用JAX-WS API自己发布webservice并调用,以及用wsimport生成webservice客户端代码调用一个免费的web服务(如webxml.com.cn上的获取手机归属地的服务). 一.webservice原理了解 webservice是一种通用的跨语言跨平台的数据交互方式,之所以能够做到这一点,是因为它的底层实现机制是依赖于HTTP协议以及XML格式这些开发的标准.webservice使用SOAP(simple object acc

Cisco ISE + Windows Server 2008 实验

实验说明:此实验参考生产环境中某部分环境搭建而成,此环境Windows Server 2008用于登录用户.MAC等账号的认证,Cisco ISE用于认证授权等,无线部分利用VMWLC + Cisco 1702AP测试测试.因为为实验环境,整体网络架构所有节点为单点:Cisco ISE部分功能没有应用上,如测试PC端的补丁.防毒补丁.设备认证等(此部分在生产环境上实施),下图为此实验的网络架构图. Windows AD:  172.16.1.199 Cisco VMISE: 172.16.1.1

CentOS系统启动及内核大破坏模拟实验

讲过了centos的启动流程,此时是不是想来点破坏呢?那就尽情的玩耍吧,记得在实验之前拍个快照,万一哪个环节错误恢复不回来了呢,毕竟数据无价,话不多说,开始. 一.删除伪系统根.(ramdisk文件) (1)模拟误操作删除ramdisk文件. ①模拟误删除initramfs-3.10.0-514.el7.x86_64.img文件. ②为当前正在使用的内核重新制作ramdisk文件 格式为:mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) (

PCB实验与检修杂记

2017-08-24 有ABCD四个焊点,diagram上A与B相连,C与D相连,B与C属于同一组引脚.现根据实验要求将B.C短接,结果测得,B与C导通而A与C不导通,这与常识违背. 经过逐步缩小范围发现,C点上方留出的测量点和焊台的测量结果有所不同,经过分析,可知C点焊脚与焊台虚焊,测量时再表笔的压力下两者导通:而表笔一但离开C点,则两者不导通.即测量引入了误差. 对于此问题解决的思路: 1.稳扎稳打,逻辑分析,逐步缩小范围.2.测量引脚上方留出的点比直接测量引脚更可靠.