基于缓冲区溢出的攻击_第1页
基于缓冲区溢出的攻击_第2页
基于缓冲区溢出的攻击_第3页
基于缓冲区溢出的攻击_第4页
基于缓冲区溢出的攻击_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验题目:基于缓冲区溢出的攻击实验目的:1.掌握缓冲区溢出的原理;2. 理解汇编语言,通过汇编语言防范缓冲区溢出的漏洞。实验环境:个人电脑、linux发行版本、ubuntu环境实验内容及操作步骤:1 开始时对于本次实验的内容并不清楚,通过查找资料了解,这个实验主要是模拟缓冲区溢出。实验中涉及到3个可执行的二进制文件bufbomb,hex2raw,makecookie。bufbomb是进行缓冲区实验的目标程序,既然是缓冲区溢出实验,肯定得有一个导致缓冲区溢出的条件,这个实验是通过类似于c语言中的gets函数的Gets读取一行数据到固定大小的缓冲区,而当我们的输入超过了缓冲区的大小时,Gets没有

2、任何的边界检查,超过缓冲区的数据就会覆盖内存中用作其它用途的数据,从而改变程序的行为,而如果gets从终端读取时,无法输入一些不可打印的数据,比如想输入控制字符0x09,于是就有了hex2raw这个程序,这个程序将16进制表示的字节转换成二进制字节数据。makecookie主要是为了防止学生直接copy别人答案用的,每个学生有一个唯一的提交作业的userid,makecookie为不同的userid计算出不同的cookie值。userid要通过命令行参数传给bufbomb,实验中我们在内存某个区域中用自己的cookie值覆盖原来的数据,bufbomb中会有一个validate函数的调用来比对传

3、入的cookie值与命令行传入的userid计算得出的cookie是否相等,如果相等,作业是有效的,否则作业是无效的。 (参考资料:2 因为对缓冲区溢出不了解上网查找资料。首先要介绍函数调用过程及栈的相关操作。我们称调用其他函数的函数为Caller,被调用的函数为Callee。图中紫色部分为Caller的栈区,浅蓝色部分为Callee的栈区。A和B两个函数,A调用B,那么A就是Caller,B就是Callee。图中紫色部分即为A的栈区, A在调用B之前,需要将参数和返回地址压栈,图中“Arguments”对应的就是2(因为i=2);“Return address”是函数B运

4、行之后的返回地址,即调用函数B后执行的下一条指令,这里应当是printf("this is func a.n")这条指令的地址。浅蓝色部分是B的栈区,字符串s就在“Local variables”中维护,因为s是函数B的局部变量。缓冲区溢出就是说输入的s过长,长度超出了s本身的容量,覆盖掉了“Return address”,导致程序不能正常执行,甚至转为执行其他命令。3 通过函数名以及阅读buflab.pdf文件,此次试验过程类似于LAB3的拆弹过程。在命令终端窗口查看汇编代码并进行输入等处理不方便,使用objdump d bufbomb > 2.txt将汇编代码输出

5、到当前文件夹中一个自动生成的2.txt的文件中。(此方法借鉴了LAB3中的方法)4 开始“拆弹”:(根据buflab.pdf文件提示和网上资料 Level0:Level0是要让getbuf函数完成后直接进入smoke函数,而由实验原理可知我们只要输入44字节的无用字符再在最后输入smoke的入口地址就可以了,运用gdb反汇编查看编代码,我们可以看到smoke的入口地址为0x08048e0a(由于服务器系统是小端规则我们输入的顺序为0b 8e 04 08)注:0a是回车,我们输入这个字符不会得到正确的结果)建立文档lijia.txt,所以输入的字符串是: 00 00 00 00 00 00 00

6、 00 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 0b 8e 04 08 输入命令./hex2raw <lijia.txt | ./bufbomb u lijia结果如图:测试通过!在这一关中if (val = cookie)的语句在调用getbuf函数的后面,因此实际上没有用到我们的userid来计算cookie比对。Level1:本关要求我们进入函数fizz。通过makecookie计算出userid的cookie值.

7、cookie值为4169155f 。查看fizz的代码在这一关中通过getbuf函数输入参数val,参数val应当与cookie相同,然后 传递给fizz函数。由fizz的汇编代码可得,push%ebp 之后,%esp与%ebp指向同一个位置,而此时用%ebp+8表示输入的参数。 而我们由上面fizz函数的代码可得,要使cookie值等于参数值。在调用fizz函数后,开辟一个新的栈,此时参数位置距离fizz函数首地址 还有一个空,需要用00 00 00 00来覆盖,将cookie值付给参数。除了要将这个值用相同的方式输入到getbuf函数中返回地址处外,还应将cookie值0x1005b2b7

8、输入到在fizz函数中fizz函数返回地址的上一个4字节处即第一个参数处。getbuf函数输入时fizz函数的地址值和cookie值是不变的,(不能输入0a) ,共需要输入56(0x28+0x4+0x4+0x4+0x4)个字节,其中前44个可以任意输入.getbuf返回地址处输入应为0x08048daf(小端法:af 8d 04 08)fizz返回地址处可以随意,故输入00 00 00 00第1个参数处为cookie值0x4169155f(小端法:5f 15 69 41)。所以,新建文本文档level1.txt输入以下内容:输入命令./hex2raw < level1.txt | ./b

9、ufbomb u lijia测试成功。Level2:bufbomb函数中有一个函数bang,其c语言代码如下: 根据bufbomb.pdf文件,本关任务是调用getbuf函数后不返回到test,而是执行bang函数,但是之前要修改global_value的值为cookie值。而global_value是一个全局变量,全局变量没有存储在栈里面,在程序运行期间要修改全局变量的值,我们只能通过执行赋值指令方式改变global_value的值。由以上代码可以知道如果我们想要得到正确的输出,我们就要执行global_value = cookie分支,global_value 是一个全局变量,初始值为0,

10、我们需要将它的值改为cookie值才能得到正确结果。修改全局变量:1. 首先要我们要查到全局变量的地址:我们需要写一个代码将全局变量赋值,然后将指令对应的字号作为我们输入的字符。然后在命令之后的返回地址我们设置为bang的入口地址,然后填充无用字符,将最终的返回地址设为输入字符串的起始地址运用dgb 查看bang函数 ,其首地址为0x08 04d10c 通过上面汇编代码知道global_value的地址为0x0804d10c,开始时对于0x0804d10c这个地址所存是否为global_value不确定,通过查看地址所存内容确定。建立level2.S文件进行汇编。将cookie值存入eax寄存

11、器,再将global_value的地址存入ecx寄存器,cookie值存到了global_value中,通过ret调用改变eip转到bang函数中。编译level2_lijia.s,然后通过反汇编得到汇编代码查看level2_lijia.d文件中的汇编代码,如下: getbuf函数执行完后的返回地址改成buf的首地址,上一个栈的4字节改成bang函数的地址,这样当在getbuf中调用ret返回时程序会跳转到buf处报告上面的指令,出现ret时会跳转到bang函数中执行。 getbuf中的buf位于栈中,我们通过gdb来查看buf的地址值,利用gdb设置断点调试:由此可得buf运行时首地址为0x

12、556839f8。建立level2.txt文档输入:B8 5f 15 69 41 69 0c d1 04 08 89 01 c300 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00 0000 5f 15 69 41/cookie的值52 8d 04 08 首地址前13个字节是level2-lijia.s文件生成的汇编代码,后面的31个是无关内容的,最后的8个字节分别是cookie的值h和bang 首地址,运用小端法输入运行结果如下:测试成功。Level3;返回到test, 改变返

13、回值为cookie的值.这个实验要求程序要正常返回到test执行,并且改变返回值为cookie的值,且不能破坏test函数的栈状态。我们在执行时要把破坏的栈恢复过来,并直接返回到test。在getbuf返回地址中填充buf的首地址,当getbuf函数碰到返回指令ret时,将跳转到buf处执行,此时esp寄存器指向getbuf返回地址的高一个字节。通过最后一条语句可知getbuf调用后一条指令的地址为8048e50编写level3_lijia.s文档movl $0x4169155f,%eax/将getbuf返回值置为cookie值pushl $0x8048e50 /将返回地址置为正确返回地址0x

14、08048e50ret接下来的操作与Level2一致然后通过反编译level3_lijia.s,然后通过反汇编得到汇编代码level3_lijia.d查看level3_lijia.d文件查找%ebp的值然后设值断点进行查找可以看到%ebp的值为0x55683a50将赋值代码的字号和找到的%ebp的值写到攻击文件相应的位置字符串初始地址为0x556839f8) b8 5f 15 69 41 /mov $0x4174d6a6,%eax 68 50 8e 04 08 /push $0x8048e50 c3 /ret 30 30 30 30 30 30 30 30 30 30 30 30 30 30

15、30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 50 3a 68 55 /%ebp的值f8 39 68 55 /字符串初始地址测试成功Level4本次实验中,我们给bufbomb加-n选项,main中调用testn而不是test,在testn在调用getbufn,这时栈底是不固定的,会在一定范围内变化,完成上一个实验相同的任务,但是这个实验中会调用testn五次,每次调用时栈指针都不同。函数testn中调用getbufn时前的代码返回地址指向testn中的getbufn调用后一条指令8048ce2.。保存的ebp的值就是testn函数中值,当执行完re

16、t后,通过执行 lea 0x28(%esp), %ebp 恢复ebp内容 :建立level4_lijia.o文件编译level2_lijia.s,然后通过反汇编得,得到可执行文件和level4_lijia.s的汇编代码,如下:由于栈空间的地址是随机分配的所以每次调用getbufn都会有一个不同的buf地址。通过gdb工具来查看每次的buf地址可以看到5次的buf地址分别为0x55683188, 0x556837a8 ,0x55683888 ,0x55683808 ,0x556837f8尽可能增大nop填充区,尽可能使有效机器代码段往后挪。考虑将最高的buf地址 0

17、x55683888 作为跳转地址,将有效机器代码置于跳转地址之前,并将其它所有字符都用作nop指令,此时所有五个buf地址的写入都能满足跳转到地址0x55683920后顺利到达有效机器代码。(这部分内容来源于/csapp-bufbomb-lab-solve/)”新建文件level4.txt:90共505个字节,即机器指令空操作nop,紧跟着15字节指令,4字节填充,也可以直接在前面用509个空指令,15字节指令后移4字节,然后是指向buf中某个字节的地址,要保证总是指向buf到15字节之间(包括边界),第520524置为任意字符,最后为buf最大的那个地址 0x55683888(小端法输入)输入命令 cat level4 lijia.txt | ./hex2r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论