湖南大学计算机组成原理实验实验5buflab资料下载.pdf

上传人:wj 文档编号:5981831 上传时间:2023-05-05 格式:PDF 页数:31 大小:1.55MB
下载 相关 举报
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第1页
第1页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第2页
第2页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第3页
第3页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第4页
第4页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第5页
第5页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第6页
第6页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第7页
第7页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第8页
第8页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第9页
第9页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第10页
第10页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第11页
第11页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第12页
第12页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第13页
第13页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第14页
第14页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第15页
第15页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第16页
第16页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第17页
第17页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第18页
第18页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第19页
第19页 / 共31页
湖南大学计算机组成原理实验实验5buflab资料下载.pdf_第20页
第20页 / 共31页
亲,该文档总共31页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

湖南大学计算机组成原理实验实验5buflab资料下载.pdf

《湖南大学计算机组成原理实验实验5buflab资料下载.pdf》由会员分享,可在线阅读,更多相关《湖南大学计算机组成原理实验实验5buflab资料下载.pdf(31页珍藏版)》请在冰点文库上搜索。

湖南大学计算机组成原理实验实验5buflab资料下载.pdf

Gets函数和标准库函数内的gets类似,读取一串以n结尾的字符串,并将其存储于特定目标中,在getbuf函数中,这个目标地址是一个有32个字符型大小的数组。

然而这个Gets的缺点是不能判断buf是否足够存入所有的输入值,它只是简单地将整个字符串赋值,经常会超出分配的存储空间。

当错误信息出现时,缓冲区溢出导致程序被破坏,使存储器路径错误以下有几个控制语句:

-ucookie,使用这个语句是要确保不同的人使用不同的ID做题,并攻击不同的地址。

-h用于打印这几个操作的内容,-n用于Level4关卡,-s用于提交你的解决方案到服务器中。

我们可以把自己写好的exploit文件写成txt格式,并用以下方式应用到bufbomb中去:

另外,还有一些重要的注意事项:

Exploit文件中在任何位置都不能能包含0x0A,因为这是ASCII码的换行编码,如果写了这个语句,Gets会认为你想终止字符串HEX2RAW期望输入的是空格隔开的两位16进制数,如果你想创建一个值为0的,就要输入00,另外,注意小端法输入。

以上就是writeup文件针对这个实验的说明,读完大概明白了几个文件的意思,但是要去做还是一头雾水。

所以我决定继续跟着这个writeup的指导看下去。

Level0接下来就开始了Level0,说的是getbuf被bufbomb中的test功能调用,而这个test的c语言代码如下:

Getbuf函数如下:

Smoke函数如下:

题目要求为:

当test函数在调用getbuf函数时,本来这个程序会按照惯例返回test函数,但是我们要做的就是当getbuf函数执行结束时,返回到smoke函数中去。

几条建议为:

1反编译bufbomb,2小心字节顺序,3使用gdb确定自己做的对不对,4getbut在堆栈中的位置取决于gcc版本。

下面开始解题:

第一题很简单,应该是给大家入门的一个导引,大致的目的就是输入一个过长的字符串,把getbuf函数的返回地址覆盖掉,改成我们想要的smoke函数的地址,那么就可以在getbuf函数运行结束时返回到smoke函数中去。

下面根据反汇编的代码来看这个“过长的字符串”到底要写点什么。

在进行反汇编的时候可以使用objdump,但是我习惯使用gdb中的反汇编命令disassemble,虽然方法不一样但是都得到了反汇编代码:

考虑这个题目的要求,是在执行完getbuf之后返回到smoke函数中去,那么考虑getbuf的堆栈结构:

这里是把ebp-40的地址传给esp,所以针对调用的函数Gets,写数据的顺序就是从ebp-40开始向上写,而当前这个位置距离getbuf的返回地址有48字节,所以我们只要在前44个字节上随便写点什么,在原来的返回地址的那四个字节改写为smoke函数的入口地址即可。

下面反编译smoke函数寻找入口地址可以看到,smoke函数的入口地址为0x08048e0a,那么问题来了:

如果在这里输入0a,会被gets函数判断为换行符n,从而结束字符串输入,导致这个地址错误,所以肯定不能输入0a但是本着实验精神我还是做了一下尝试,编写level0.txt如下:

下面进行检测是否可以完成需求:

显然报错,说明不能写入末尾为0a的地址,那么怎么办呢?

我选择使用入口地址的下一行即mov%esp%ebp的地址0x08048e0b来代替,因为本来如果执行smoke函数,它会和getbuf函数一样重新建立一个栈,但是这里我们只需要去执行这个函数,并不管之后发生了什么事,况且这个push的ebp,是test函数的ebp,而这个ebp我们在上一步输入44字节的值时已经破坏掉了,所以也不会有什么影响。

这个思想在writeup中也有所体现:

Notethatyourexploitstringmayalsocorruptpartsofthestacknotdirectlyrelatedtothisstage,butthiswillnotcauseaproblem,sincesmokecausestheprogramtoexitdirectly.说的就是这个操作。

所以,这题的答案就是:

(前44字节的值随便填,只要不是0a就可以,后4字节为0b8e0408)这次通过了检测,成功返回到了smoke函数。

Levle1通过了上一题,大概明白了这次实验的概要,所以下面做起来也就得心应手了。

这个level1说的是:

bufbomb中也有一个函数叫fizz,代码如下:

类似于level0,我的任务就是让test函数返回到fizz,而不是test,然而,这次我们要传入自己的cookie作为参数。

建议:

要明白,程序不会真的调用fizz,而是仅仅执行它,这句话暗示了你在堆栈哪个地方要去放置自己的cookie。

先反编译fizz函数,现在回想一下怎么通过上一关的,上一关的过程是这样的:

Gets函数从距离返回地址48个字节处开始写数据,我先写了40个字节(这40个字节是随便的),再用4个字节覆盖了旧的ebp(即test函数中的ebp),再用4个字节的地址(即smoke函数的入口地址)覆盖了getbuf函数的返回地址,使test函数运行结束后,ret语句回到的不是本应的test函数,而是去到了smoke函数。

、下面仍为getbuf函数的堆栈结构下面再看看fizz函数的堆栈结构:

可以看到,fizz函数会去ebp+8的位置取参数,也就是我的cookie值,考虑和上一题相类似的做法,我们不是从头开始去调用fizz函数,而是仅仅执行它,这个想法给了我很大的灵感。

同level0类似,我们只需要在前44个字节(也就是包括ebp及其以下的内容)随便填,45-48字节(也就是返回地址)填写fizz函数的入口地址,再在49-52字节(也就是ebp+8,fizz函数的取参数处)写入自己的cookie,即可。

然而,根据以上的做法我却得到了错误的结果:

当前的原因是:

我成功进入了fizz函数,但是参数值却与我的cookie值不同。

百思不得其解,我在网上查了很多资料,下面是一个解析上图为test函数中调用getbuf函数的堆栈结构,使用fizz函数的入口地址替换返回地址后的堆栈如下图Getbuf函数执行完毕,执行leave语句后:

接着执行ret语句,popeip的地址为fizz函数的入口地址,即继续执行fizz函数。

然而,此时重点来了。

我们是直接进入函数,而不是调用这个函数,所以系统不会自动压入返回地址因此,进入到fizz函数中来,压入%ebp,为栈开辟了空间后:

由于要取的cookie值是在fizz的ebp+8处,此时我们把这个图和输入字符串攻击缓冲区时的作对比,终于发现了问题:

由于没有调用fizz函数,没有压入返回地址,fizz和getbuf的ebp位置不一样!

所以,可以看出应该在相对getbuf%ebp+8的位置随便填4个字节的内容,在%ebp+12处,填入我的cookie,才能成功解决问题。

如下:

这次应该不会出问题了,测试一下:

完美通过,这个实验也给了我很大启发:

另一种解决的方法,如果我像第一题一样,填入的不是push%ebp的地址,而是mov%esp%ebp这一句的地址呢?

如图,那么现在的ebp比调用getbuf的ebp偏移了8个字节,所以这个答案又有所不同:

也测试一下:

发现也是可以的,所以这道题不止一个答案。

Levle2下面分析level2,以下是bufbomb内的一个bang函数的c代码类似于0和1关,你的任务是使bufbomb的执行过程中,执行bomb而非回到test,在这之前,你需要定义全局变量global_value为你的cookie值,你的操作代码应该完成以下操作:

在堆栈上压入bang的地址,执行ret操作跳转到bang函数。

一些建议为:

1可以使用gdb得到所需信息来组织你的代码,在getbuf中设置断点并运行,设置参数例如全局变量的地址和缓冲区的位置2用手写字节编码很复杂也容易带来错误,通过编写包含指令和数据的代码,你可以使用工具做所有的工作,我们可以使用objdump或者gcc将自己的代码生成可执行的机器码3注意cookie不要输错了4注意立即数和存储器的区别5不要用jmp或者call指令,可以使用ret指令读完还是感觉一头雾水,感觉大概的意思是要自己去写汇编代码,完成相应需求,再通过gcc转成机器语言作为密码,再看看文章最后给出的一个实例generatingbytecodes,明确一下汇编代码的使用要求。

文末的这个实例给出了一个汇编代码example.s,内容如下使用gcc汇编、反汇编生成如下机器码所以这个汇编代码的机器码就是这个机器码再通过hex2raw生成一个输入字符串传给bufbomb就可以完成任务。

读到这里我也就明白了,这次是要写个汇编代码,转成机器码之后写到txt里进行操作,这个汇编代码的内容就包括了修改变量值和调用bang函数。

下面是解题过程:

首先得找到全局变量global_value的内存地址,所以反编译bang函数:

和c语言代码比对,可以看到这个函数先把0x804d10c地址处的值传给eax寄存器,并和0x804d104处的值做比较,看一下后面的这个地址处的值这就是我的cookie,所以,前面的那个地址就是全局变量global_value所以现在就可以开始写汇编代码了,要完成的任务有两个,一是修改变量值,二是使用ret语句完成对bang函数的调用,前一个操作很简单,就是一个mov指令传值,后一个操作在课上也没有讲过用法,但是结合ret操作的作用(将栈顶单元出栈并赋给eip以实现转移),我需要先把bang函数的入口地址压栈,再ret,即可实现调用。

所以汇编代码如下:

然后就是照葫芦画瓢,学着writeup中的操作转换成机器码再打开这个level2.d所以这个汇编代码的机器码就是c7050cd104081ced262068528d0408c3下面问题来了,得到这个机器码之后怎么用呢?

从头开始考虑一下,这个机器码的作用是执行到它时,修改全局变量的值并进入bang函数,然而要怎么执行到这一步呢?

考虑执行getbuf函数的时候,将其返回地址改为这个函数的地址(也就是buf的首地址),使getbuf执行完毕后,继续执行这个函数,执行完这个函数就自动执行bang函数,完成了题目的要求。

所以,下一个问题在于,我们写的这个函数的地址在哪里?

使用gdb调试,在getbuf函数中设置断点,查询buf的首地址可以从getbuf的反汇编代码中看出,在callgets函数前,eax寄存器的值就是buf的首地址,即我写的函数的地址。

所以下面可以开始构造level2的exploit代码,如下:

测试一下:

完美通过测试。

Level3最复杂的缓冲区溢出攻击导致程序执行一些改变寄存器/存储器状态的代码,但是仍使程序返回到正常的调用处(在这个例子里,是test函数),你必须做的是:

1:

在堆栈上编写机器码,2:

在开始处设置返回指针,3:

撤销对堆栈状态的破坏这一关你的任务是输入一个执行字符串,使getbuf返回你的cookie值,而不是1,你可以看到在test中这样做会导致boom!

,你的代码应该设置你的cookie作为返回值,修复所有被破坏的状态,并将正确的返回地址压栈,并执行一个ret语句来真正的返回test中一些建议:

1使用gdb获得你需要构造的代码的信息,设置断点并运行,以确定参数如保存的返回地址。

2同level2,写汇编代码并转成机器码3注意cookie4你完成了这一关之后,停下来想想自己完成了什么,你使程序执行你自己设计的机器码,你悄悄完成了程序都意识不到的事情。

有了上一题的铺垫,这题感觉就很简单了。

先来看一看test函数的bomb是发生在什么时候:

一开始我对这个题目的理解不太对,还以为出现boom就是爆炸,实验失败,后来想想感觉不对,只要修改了getbuf的返回值,这里必定出现boom,所以这个boom只是用来检验你做的对不对的。

所以这样一来就轻松了许多。

以下为解题思路。

解题思路:

要求1:

修改返回值函数的返回值是存在eax寄存器中的,如果想修改返回值,只要把eax修改了即可要求2:

不破坏函数结构,并将正确的地址压栈这个要求2实际上有两方面的要求:

一是保证旧的ebp不被改写,能够将旧ebp保护下来并继续执行下去,二是保证返回地址不出错,即执行完getbuf后继续执行test函数里的下面几句。

先看旧ebp,反汇编getbuf看一下:

在push%ebp这一句设置断点,并查看ebp的值可以看到这个ebp的值是0x55683990而对于返回地址,这个很简单,就相当于上一题我们是跳转到bang函数,在这一题里,把执行完getbuf的下一句的地址压栈再ret,就完成了要求。

先反汇编test看一下getbuf的下一句可以看到,getbuf执行完下一句地址是0x08048e50综上所述,编写汇编代码如下,有两种写法,只要在其中一个地方修复ebp即可第一种是在这个代码里不对ebp作操作,而在我们最后填入getbuf的字符串中修改ebp第二种是在这个代码里把ebp改为原ebp,在我们最后填入getbuf的字符串中随意填ebp下面分别演示:

第一种:

汇编代码:

转成机器码:

所以这个代码的机器码为:

b81ced262068508e0408c3构造exploit如下(在这里要覆盖ebp为原ebp):

测试结果:

第二种:

所以这个汇编的机器码为:

b81ced2620bd9039685568508e0408c3构造exploit测试结果:

测试结果表明两种方式均可。

Levle4终于来到了最后一关,老规矩先翻译题目。

来到这一关,你需要用-n指令来过关。

对于不同的用户,实际堆栈的位置千变万化,原因之一就是程序执行时,环境变量被安放在栈底。

环境变量作为字符串存储,并根据值的不同,需要不同大量的存储空间。

在gdb调试中,堆栈位置也会有差异,因为gdb需要堆栈空间来存储它自己的状态。

Getbuf函数调用过程中,我们安放了使堆栈稳定的因素,因此getbuf堆栈框架在运行中趋于稳定,这使得你有机会写攻击代码来通晓buf的始地址,如果你试着在一个普通的程序中使用这个攻击代码,你会发现它有时能用,但其他情况下会出现分裂错误。

因此,“甘油炸药”一个诺贝尔发明的爆炸性的物质,包含了稳定物质而使其趋于意想不到的爆炸。

这一关里,我们要与原来背向而行,使堆栈的位置比平时更加不稳定。

当你使用-n运行bufbomb时,它就会进入“硝基模式”,程序不调用getbuf,而是调用getbufn这个函数和getbuf类似,但是它限制了缓冲区大小为512个字符,你将会需要这个额外空间来创建可信的攻击程序,调用getbufn的代码第一次在堆栈上分配一个随机大小的存储空间,所以如果你在getbufn两次连续调用过程中对ebp采样的话,你会发现他们相差240另外,在硝基模式下运行时,bufbomb要求你提供你的字符串共5次,而且他也会执行5次,每次都有不同的堆栈偏移,你的exploit必须使它每次都返回你的cookie。

你的任务和硝基炸弹的任务相同,再次地,你的任务是提供一个攻击程序,让他导致getbufn返回你的cookie到test中,而不是1。

你可以在test函数中看到,这会导致程序出现kaboom!

你的攻击代码应该把你的cookie作为返回值,保存任何的破坏状态,把正确的堆栈位置压栈,并且执行ret操作来真正的返回testn一些建议:

1你可以使用HEX2RAW程序来发送多个攻击程序的拷贝,如果你在exploit文件中只有一个拷贝,你可以使用如下操作:

unixcatexploit.txt|./hex2raw-n|./bufbomb-n-ubovik你必须使用同一个攻击程序执行getbufn5次,否则在我们的服务器上会将你的代码评为失败。

2秘诀在于巧妙使用nop指令,它是用0x90编码的单字节指令,读CSAPP262页上的nopsleds会有所帮助。

读完了要求,感觉大概就是这次的攻击是针对栈基址随机化的攻击,但是要连续攻击5次,也不知道有什么意义不过还是先看一下书上nop雪橇是怎么用的吧。

书上对这部分的解释为:

一种常见的把戏就是在实际的攻击代码中插入一段很长的nop指令,只要攻击者能猜中这段程序中的某个地址,程序就会经过这个序列,到达攻击代码,这个序列的术语就是“空操作雪橇”。

我的理解为:

在不清楚有效机器代码的入口地址时,可以在有效机器代码前以大量的NOP指令填充,只要跳转地址处于这些nop上就能依次滑下去,最终到达有效的机器代码。

而针对这个函数getbufn,在调用这个函数时会随机在栈中分配一段存储地址,这导致了getbufn的基址ebp随机变化,针对这个栈上地址不固定,但要求我们写的跳转地址是固定的,所以可以在尽量大的范围内都写上nop代码,而在较大范围内的指令都是nop指令,即这段地址内的代码都会滑到这段nop之后的攻击代码上。

由于栈上的机器代码是按地址由低向高顺序执行,要保证五次运行都能顺利执行有效机器代码,需要满足:

跳转地址位于有效机器代码入口地址之前的nop机器指令填充区。

这要求尽可能增大nop填充区,尽可能使有效机器代码段往后挪。

先反汇编getbufn函数看一下:

可以看到,这个函数中buf的首地址为ebp-0x208,所以这个buf一共的大小为2*16*16+8=520字节,考虑这个函数中,testn的ebp随每次输入都随机变化,但是栈顶esp的位置却不变,所以我们可以通过esp和ebp的关系来找出这个关系,从而进行攻击。

首先在sub$0x218,esp这一句设置断点,并使用-n模式运行程序,并查看ebp的值第2次:

第3次:

第4次:

第5次:

可以看到,有两次的ebp是相同的,但是这并不影响,可以认为这两次堆栈结构相同,而我们要做的是找出最大的ebp值0x556839d0,再减去0x208,即为最高的buf的始地址为:

0x556837c8如果将有效机器代码置于跳转地址之前,并将其它所有字符都用作nop指令,此时所有五个buf地址的写入都能满足跳转到地址0x556837c8后顺利到达有效机器代码。

可以看出,在testn中,esp+0x24+0x4是ebp的真值,而由于esp是不变的,所以可以通过esp+0x28来修改正确的ebp值,同时,可以看出得到getbufn的返回地址为0x08048ce2所以构造攻击汇编代码如下:

第一句用于修改返回值为cookie,第二句修改ebp为正确的ebp,第三句修改正确的返回地址。

反汇编转成机器码:

故攻击代码的机器码为b81ced26208d6c242868e28c0408c3所以,可以构造填入getbufn的字符串为:

构造的方法:

考虑buf部分共有520+4(旧ebp)+4(返回地址)共528个字节,我们这个代码里要做的就是在这些范围内填入三部分:

nop操作、攻击代码、和跳转地址。

先考虑后面的部分,在原函数的返回地址处我们肯定要用buf的最大始地址代替,是最后4字节,然后紧跟着它之前的是我们的攻击代码,共15字节,剩下的528-4-15=509字节全用nop填满。

结果很完美:

另外,在攻击代码部分,修改ebp和修改eax顺序可以颠倒,故本题有两组答案,另一种略去不表。

实验结果及分析:

以上是通关的截图,都是以我的IDMrspot完成的。

收获与体会:

个人感觉这次实验比bomblab要难,不过因为有一个11页的pdf,加上网络上的攻略也很多,除了第四关自己不太理解以外,其他问题都自己独立解决了。

这门课给我的感觉就是理论课很乏味,但是实验都非常有意思,做了几个实验,最有意思的就是buflab和bomblab,都是能让我边做边感叹美国人真牛。

网上也能下载到CSAPP的共10个实验,这学期因为快期末考了应该也没什么时间做,但是以后有空还是会仔细看看。

实验成绩

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2