深入理解计算机系统AttackLab实验
AttackLab实验
实验目的与要求
- 强化机器级表示、汇编语言、调试器和逆向工程等方面基础知识,并结合栈帧工作原理实现简单的栈溢出攻击,掌握其攻击的基本方式和原理,进一步为编程过程中应对栈溢出攻击打下一定的基础。
- 理解缓冲区的工作原理和字符填充过程及其特点。对于无边界检测的语言及其工作方式所造成的缓冲区漏洞加深理解。
- 通过字符串填充的方式,完成5个阶段的缓冲区攻击。分别基于基本返回地址填充、攻击代码填充、ROP等实现这5个难度递增的阶段的缓冲区溢出攻击。
实验原理与内容
“AttackLab”是一个Linux下的可执行C程序,包含了5个阶段(phase1~phase5)的不同内容。程序运行过程中,要求学生能够根据缓冲区的工作方式和程序的反汇编代码来确定攻击字符串长度和字符串中的关键内容。每次成功实现缓冲区溢出攻击时都会有提示相应内容,如果攻击失败则单纯的提示segmentation fault相关信息。
要求攻击字符串的执行不许绕开代码中的validate函数,缓冲区溢出之后对应ret的返回地址可以是以下类型:
1.函数touch1、touch2、touch3的首地址;
2.自行注入的攻击的首地址;
3.在后两个阶段中(ROP攻击),与farm.c的对应的可利用的gadget的起始地址,farm.c对应的机器码已经包含在可执行文件中。可以使用的gadget首地址需处于start_farm和end_farm之间的部分。
注意:前三个阶段使用ctarget作为攻击目标文件,后两个阶段中使用rtarget作为攻击目标文件。
每个阶段考察一个缓冲区溢出方式,难度逐级递增:
阶段1:使用非ROP方式对ctarget进行攻击,调用touch1,且成功输出Touch1!: You called touch1。若不完全满足题目要求,则会提示“Misfire”和FAIL相关字段。
阶段2:使用非ROP方式对ctarget进行攻击,调用touch2,且成功输出Touch2!: You called touch2。攻击过程中需要改写cookie变量的值。若不完全满足题目要求,则会提示“Misfire” 和FAIL相关字段。
阶段3:使用非ROP方式对ctarget进行攻击,调用touch3,且成功输出Touch3!: You called touch3。攻击过程中需要使hexmatch的返回值能够正确引导validate函数。若不完全满足题目要求,则会提示“Misfire” 和FAIL相关字段。
阶段4:使用ROP方式对rtarget进行攻击,调用touch2,且成功输出Touch2!: You called touch2。若不完全满足题目要求,则会提示“Misfire” 和FAIL相关字段。
阶段5:使用ROP方式对rtarget进行攻击,调用touch3,且成功输出Touch3!: You called touch3。若不完全满足题目要求,则会提示“Misfire” 和FAIL相关字段。
ctarget和rtarget都从standard input读入数据,可以以重定向文件的形式进行输入。实验利用getbuf函数中的缓冲区。getbuf函数的结构如下:
unsigned getbuf()
{
char buf[BUFFER_SIZE];
Gets(buf);
return 1;
}
函数中的Gets函数与标准库中的gets函数类似,它从standard input中读取字符(以\n或者EOF结尾)并将它们添加字符串结尾符\0后存入缓冲区中。学生需要根据ctarget和rtarget文件及其反汇编代码来确定缓冲区位置及大小,并想办法构建出攻击字符串。
实验过程与结果
实验过程与结果(可贴图)
阶段1:
(1).用objdump工具反汇编查看其代码,并存入文件中方便查看。命令为:
objdump -d ctarget > ctarget.txt
(2). 利用gdb 调试ctarget找到我们需要的信息
(3). 反汇编getbuf函数,找到实际在栈上分配了多少字节
从第一行sub $0x28, %rsp中显示,在栈上为buf提供了0x18也就是24个字节的空间
(4). 反汇编touch1函数,找到touch1函数的起始地址
从第一行中看出,touch1的返回地址是0x00000000004018a7。
以上,我们已经到了我们需要的所有关键信息,现在构建我们输入字符,首先填充栈,可以使用任意字符,这里创建了一个文件输入16进制的0x00填充,然后填充touch1地址(通过在getbuf阶段输入特定的字符串,拦截程序流,跳转到touch1)。注意字节序的问题,大部分电脑应该都是little-endian字节序,即低位在低地址,高位在高地址。
(5).使用如下命令进行结果验证:
cat phase1.txt | ./hex2raw | ./ctarget -q
(hex2row 将16进制数转化为攻击字符,因为有些字符在屏幕上面无法输入,所以输入该字符的16进制数,自动转化为该字符; | 管道符号)
阶段2:
(1).查看touch2函数
(2).这段程序就是验证传进来的参数val是否和cookie中值相等。本文中我的cookie值为:0x4cc8ffdc
.建立inject.s文档,输入注入代码(第一个立即数是我的cookie,第二个是touch2的地址)
(3). 利用gcc和objdump命令得到机器代码: ump命令得到机器代码:
可以得到这三条指令序列如下:
48 c7 c7 dc ff c8 4c 68 d5 18 40 00 c3
(4). 接下来就是寻找%rsp的地址,利用gdb进行调试,获取我们需要的信息:
地址为0x5561f558,如上所示,我们获取到了%rsp的地址,结合上文所讲,可以构造出如下字符串,在栈的开始位置为注入代码的指令序列,然后填充满至40个字节,在接下来的8个字节,也就是原来的返回地址,填充成注入代码的起始地址,也就是%rsp的地址,可以得到如下字符串:
(5).验证通过
阶段3:
(1).首先找到touch3的反汇编代码
(2).参数是一个指针变量(即为内存地址),使用gdb调式得到这个地址量,具体操作如下所示。
(3).见info frame含义解释。可知函数test输入参数所在的内存地址为0x5561f578
touch3起始地址为0x4019ec,模仿第二关的操作,先写出攻击代码的汇编:
(4).ump命令得到机器代码:
可以得到这三条指令序列如下:
48 c7 c7 78 f5 61 55 68 ec 19 40 00 c3
本文中cookie的值是0x5561f578,所以我们传进去的参数应该是"0x4cc8ffdc",(即 34 63 63 38 66 66 64 63 00)
找到%rsp地址
(5).得%rsp地址为0x5561f558
所以得到字符串如下
文章来源:https://www.toymoban.com/news/detail-760524.html
(6).实验验证:
文章来源地址https://www.toymoban.com/news/detail-760524.html
到了这里,关于深入理解计算机系统AttackLab实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!