Attack Lab:Phase1~Phase5【缓冲区溢出实验】

注:本实验所用文件不是csapp官网给出的,是学校下发的。可以参考我的思路。

phase 1

本阶段目标是使getbuf调用结束后,控制权交给touch1函数。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第1张图片

则我们要知道两件事:一是缓冲区大小,二是touch1在虚拟内存中的位置。

用objdump -d ctarget > ctarget.s命令,反汇编ctarget代码。用本机安装的vs打开,方便阅读。

如下图,缓冲区大小为0x38字节,即56字节。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第2张图片

如下图,touch1的位置在0x4018a3.

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第3张图片

那么,就可以先输入56字节的任意数据,将getbuf的缓冲区填满,然后溢出8个字节这8个字节原本的内容是test调用getbuf后的返回地址。将这个返回地址用touch1的地址(0x4018a3)覆盖,这样在getbuf函数执行retq指令后,程序就会返回到touch1函数,执行touch1函数

新建一个名为e1.txt文件,输入以下内容。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第4张图片

这个e1.txt文件中的内容就是在getbuf中,用户要输入的内容。但是不能直接定向输入到ctarget中,而是要将数据通过hex2raw程序转化后输入ctarget程序

hex2raw的使用方法如下图。

所以,如下图,用hex2raw小工具得到真正的二进制代码,带参数运行。本阶段完成。(个人信息部分已隐藏)

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第5张图片

phase 2

本阶段目标是调用touch2,并且传递一个正确的参数。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第6张图片

其中cookie是0x2486651c

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第7张图片

我们注入的代码的要做的事情:

将cookie的值(0x2486651c) mov到第一个参数(寄存器rdx)

把touch2位置压入栈中

返回

如下图,其中touch2的位置为4018d7。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第8张图片翻译为汇编代码:

movl $0x2486651c, %rdi

push $0x4018d7

ret

将以上汇编代码用gcc编译为机器代码,再反汇编得到:

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第9张图片

至此得到了应注入的机器代码。不要忘记,溢出区的地方写栈顶地址,以便在buf函数调用结束后rip跳到我们注入的代码的地址。栈顶地址可以通过gdb调试时的rsp值得到,为0x55631238。新建一个名为e2.txt文件,输入以下内容:

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第10张图片

用hex2raw小工具得到真正的二进制代码,带参数运行。本阶段完成。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第11张图片

phase 3

本阶段的目标是调用touch3,调用时向touch3传递一个参数,是字符串,字符串的内容是cookie,即sval=“2486651c\0”.并且要特别注意字符串的存放位置,不能存在buf的栈帧(即大小为0x38字节的缓冲区)中,不然调用其他函数时马上会被覆盖,按地址读出的就不是我们写入的sval字符串了。所以将其存在溢出后的位置,即text函数的栈帧中。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第12张图片我们注入的代码的要做的事情:

将存放字符串的地址mov到rdx

touch3函数首地址压栈

返回

如下图,touch3的地址为0x4019f0

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第13张图片翻译为汇编代码:

movq $0x55631278, %rdi

push $0x4019f0

ret

将以上汇编代码用gcc编译为机器代码,再反汇编得到:

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第14张图片

至此得到了应注入的机器代码。不要忘记,溢出区的地方写栈顶地址(与阶段二的地址一样,是0x55631238,无需再次用gdb调试),以便在buf函数调用结束后rip跳到我们注入的代码的地址。接下来还要写入“2486651c\0”字符串。这个字符串转为ascii码为:32 34 38 36 36 35 31 63 00.

新建一个名为e2.txt文件,输入以下内容:

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第15张图片

用hex2raw小工具得到真正的二进制代码,带参数运行。本阶段完成。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第16张图片

phase 4

接下来的两个阶段用到rtarget和farm.c

objdump -d rtarget > rtarget.s

用vs打开rtarget.s

本阶段的目标是用面向返回攻击的办法,使得touch2被成功调用。但是由于采用了栈随机化,即段程序分配的栈的位置在每次运行时都是随机的,这就使我们无法确定在哪里插入代码限制可执行代码区域,而且它限制栈上存放的代码是不可执行的且还有一个限制:最多用2段farm.c中的小工具。

所有可能会用到的机器指令如下图

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第17张图片

不能注入自己写的代码,则缓冲区的0x38字节都不用,以56个00填充缓冲区。我们要用到的是溢出的部分。如同phase2的解决方法类似,把0x2486651c放到rdi寄存器中,返回。

所以溢出区的内容是

使用能从栈中pop的小工具

0x2486651c

touch2的地址

想把0x2486651c直接pop到%rdi中对应的机器指令为5f。

但小工具中没有5f,而有58。

于是想到movl %eax, %edi。恰好,小工具中有movl %eax, %edi对应的机器代码(89 c7)。

新建一个名为e4.txt文件,输入以下内容。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第18张图片

用hex2raw小工具得到真正的二进制代码,带参数运行。本阶段完成。

phase 5

本阶段的目标是用面向返回注入的办法调用touch3,并且最多用8段farm.c中的小工具。

用到的小工具如下面所示

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第19张图片

根据在farm.c中找到的所有小工具,对应的指令顺序应该是下面这样的(顺序为从上到下)

movq %rsp, %rax

movl %eax, %edi

popq %ax

movl %ax, %cx

movl %cx, %dx

movl %dx, %si

R[ax] = R[si] + R[di]

movl %eax, %edi

对应的机器代码:

401ad9

89 c7

58

89 c1

89 ca

89 c6

48 8d 04 37

89 c7

各个小工具对应的地址为:

401ad9

401a9e

401a97

401b6f

401b32

401b97

401ad3

401a9e

栈中完整的内容如下(为了清晰的看出每句话的功能,写代码地址的地方替换为了汇编代码):

movq %rsp, %rax

movl %eax, %edi

popq %ax

0x48(偏移值)

movl %ax, %cx

movl %cx, %dx

movl %dx, %si

R[ax] = R[si] + R[di]

movl %eax, %edi

touch3的地址

cookie字符串

综上分析,新建一个名为e5.txt文件,输入以下内容。

Attack Lab:Phase1~Phase5【缓冲区溢出实验】_第20张图片

用hex2raw小工具得到真正的二进制代码,带参数运行。本阶段完成。

你可能感兴趣的:(《CS:APP》的实验,缓冲区溢出,csapp,attack,lab,汇编)