测试成功。
Level2:
bufbomb函数中有一个函数bang,其c语言代码如下:
根据bufbomb.pdf文件,本关任务是调用getbuf函数后不返回到test,而是执行bang函数,但是之前要修改global_value的值为cookie值。
而global_value是一个全局变量,全局变量没有存储在栈里面,在程序运行期间要修改全局变量的值,我们只能通过执行赋值指令方式改变global_value的值。
由以上代码可以知道如果我们想要得到正确的输出,我们就要执行global_value==cookie分支,global_value是一个全局变量,初始值为0,我们需要将它的值改为cookie值才能得到正确结果。
修改全局变量:
1.首先要我们要查到全局变量的地址:
我们需要写一个代码将全局变量赋值,然后将指令对应的字号作为我们输入的字符。
然后在命令之后的返回地址我们设置为bang的入口地址,然后填充无用字符,将最终的返回地址设为输入字符串的起始地址
运用dgb查看bang函数,其首地址为0x0804d10c
通过上面汇编代码知道global_value的地址为0x0804d10c,开始时对于0x0804d10c这个地址所存是否为global_value不确定,通过查看地址所存内容确定。
建立level2.S文件进行汇编。
将cookie值存入eax寄存器,再将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运行时首地址为0x556839f8。
建立level2.txt文档输入:
B85f156941690cd104088901c3
00000000000000000000
00000000000000000000
00000000000000000000
005f156941//cookie的值
528d0408首地址
前13个字节是level2-lijia.s文件生成的汇编代码,后面的31个是无关内容的,最后的8个字节分别是cookie的值h和bang首地址,运用小端法输入
运行结果如下:
测试成功。
Level3;
返回到test,改变返回值为cookie的值.
这个实验要求程序要正常返回到test执行,并且改变返回值为cookie的值,且不能破坏test函数的栈状态。
我们在执行时要把破坏的栈恢复过来,并直接返回到test。
在getbuf返回地址中填充buf的首地址,当getbuf函数碰到返回指令ret时,将跳转到buf处执行,此时esp寄存器指向getbuf返回地址的高一个字节。
通过最后一条语句可知getbuf调用后一条指令的地址为8048e50
编写level3_lijia.s文档
movl$0x4169155f,%eax//将getbuf返回值置为cookie值
pushl$0x8048e50//将返回地址置为正确返回地址0x08048e50
ret
接下来的操作与Level2一致然后通过反编译level3_lijia.s,然后通过反汇编得到汇编代码level3_lijia.d
查看level3_lijia.d文件
查找%ebp的值
然后设值断点进行查找
可以看到%ebp的值为0x55683a50
将赋值代码的字号和找到的%ebp的值写到攻击文件相应的位置
字符串初始地址为0x556839f8)
b85f156941//mov$0x4174d6a6,%eax
68508e0408//push$0x8048e50
c3//ret
3030303030
3030303030
3030303030
3030303030
3030303030
30303030
503a6855//%ebp的值
f8396855//字符串初始地址
测试成功
Level4
本次实验中,我们给bufbomb加-n选项,main中调用testn而不是test,在testn在调用getbufn,这时栈底是不固定的,会在一定范围内变化,完成上一个实验相同的任务,但是这个实验中会调用testn五次,每次调用时栈指针都不同。
函数testn中调用getbufn时前的代码
返回地址指向testn中的getbufn调用后一条指令8048ce2.。
保存的ebp的值就是testn函数中值,当执行完ret后,通过执行 lea0x28(%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地址0x55683888作为跳转地址,将有效机器代码置于跳转地址之前,并将其它所有字符都用作nop指令,此时所有五个buf地址的写入都能满足跳转到地址0x55683920后顺利到达有效机器代码。
(这部分内容来源于http:
//blog.youlingman.info/csapp-bufbomb-lab-solve/)”
新建文件level4.txt:
90共505个字节,即机器指令空操作nop,紧跟着15字节指令,4字节填充,也可以直接在前面用509个空指令,15字节指令后移4字节,然后是指向buf中某个字节的地址,要保证总是指向buf到15字节之间(包括边界),第520~524置为任意字符,最后为buf最大的那个地址0x55683888
(小端法输入)
输入命令catlevel4–lijia..txt|./hex2raw–n|./bufbomb–n–ulijia
测试正确。
收获与体会:
本次实验在读懂题意和操作过程中都有很大难度。
弄懂题主要是通过网上查找和询问同学,在操作过程很容易出现错误。
我是在一边做一边建立文档,但是建立完成后却无法打开。
在重新ls一次buflab-handout之后便可以找到新建文档。
如果删除这个文档之后,再建一个同名文档的时候,必须要删干净,回收站中也要删去。
还有注意新建文档的格式,必须加后缀名。
在.txt中输入文档的时候,经常马虎输入错误,导致实验花费了很多不必要的时间。
这次实验也加深了自己对栈的理解与掌握。
实
验成绩