目录
实验目的与要求
实验原理与内容
实验设备与软件环境
实验过程与结果(可贴图)
实验总结
实验目的与要求
1. 强化机器级表示、汇编语言、调试器和逆向工程等方面基础知识,并结合栈帧工作原理实现简单的栈溢出攻击,掌握其基本攻击基本方式和原理,进一步为编程过程中应对栈溢出攻击打下一定的基础。
2. 理解缓冲区的工作原理和字符填充过程及其特点。对于无边界检测的语言及其工作方式所造成的缓冲区漏洞加深理解。
3. 通过字符串填充的方式,完成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.Linux操作系统—64位Ubuntu 18.04
2. gdb调试器和objdump反汇编指令
3. 笔记本
实验过程与结果(可贴图)
大致浏览一下整个lab的目录,一共6个文件:
cookie.txt 一个8为16进行数,作为攻击的特殊标志符
farm.c 在ROP攻击中作为gadgets的产生源
ctarget 代码注入攻击的目标文件
rtarget ROP攻击的目标文件
hex2row 将16进制数转化为攻击字符,因为有些字符在屏幕上面无法输入,所以输入该字符的16进制数,自动转化为该字符
level 1
这一关我们要做的是改变返回test的地址,让touch1的地址覆盖在test的地址上,使得程序返回touch1的地址,达到这个条件,就可以通关
利用gdb 调试ctarget找到我们需要的信息
linux> gdb ctarget
反汇编getbuf函数,找到实际在栈上分配了多少字节
0x28,16进制也就是40字节
反汇编touch1函数,找到touch1函数的起始地址
我们可以看到这两个函数加起来总共是48个字节
也就是说我们只要前面40个字节随机填充,后面8个字节改为touch1的地址
就可以让ctarget返回touch1的地址了
大部分电脑应该都是little-endian字节序,即低位在低地址,高位在高地址。
我们将要填充的字符写入ctargetl1.txt(名字可以自己取)
然后执行 ./hex2raw -i ctarget.txt | ./ctarget -q 命令验证
显示called touch1字样
代表我们已经通过了第一关
Level2
Cookie地址
Touch2地址
创建inject.s文件
将touch2地址填入
查看rsp地址
将rsp地址填入末八位
验证一下
./hex2raw -i ctargetl2.txt | ./ctarget -q
Level3
查看touch3地址
查看rsp地址
因为存在栈中的话,地址会被随机修改
所以这里我们加48字节
使它到父栈帧里面
0x5563c9d8
查看cookie对应的十六进制ascll码值
0x109899ba
这个可以在网上直接找到转换的网站
31 30 39 38 39 39 62 61
将值写入文本文件
转换的值会放入rsp进行修改
验证一下
./hex2raw -i ctargetl3.txt | ./ctarget -q
这里就是本菜鸟以上3关的通关过程了。
之后我们将每关的答案保存好,然后压缩提交即可。
实验总结
通过这次实验,不仅强化了我对机器级表示、汇编语言、调试器和逆向工程等基础知识的理解,而且通过实践,我深入了解了栈溢出攻击的基本原理和应对策略。我深刻理解了栈溢出攻击的基本原理和实施过程。我明白了为什么某些特定的输入会导致程序崩溃或执行非预期的代码。同时,我也学会了如何利用调试器和逆向工程工具来分析程序的执行流程,从而更好地理解和防御这种攻击。学会了如何利用栈帧的信息进行攻击,如修改返回地址、设置全局变量等,以达到控制程序执行流程的目的。
很多事情都是熟能生巧的,底层的东西更应该一步一个脚印,希望看完这篇文章能够给到你一些启发,加油!