前言
这一章节的实验主要是rop和缓冲区溢出漏洞,这个实验做好了将会帮助你彻底理解函数调用栈和ROP这一天才构想。在课程上,老师说过自己到目前为止也没有找到对抗ROP的办法。
这里我将手把手一步一步教你搞定这个实验,BombLab其实我也做了,但是太烂了,不想整理笔记,哈哈哈哈哈。毕竟我是网安的,这个实验我就好好写了。
Part 1:Code Injection Lab
level 1
下面是各个文件的介绍
(英语看不懂就自己查,这里不想翻译了)
首先,反汇编ctarget得到汇编代码
objdump -d ctarget > ctarget.txt
简单来说就是函数调用完毕执行回退时候,返回去执行touch1,2,3这三个函数。
Gets(buf)类似于c语言中的gets函数,他没法检查缓冲区是否big enough to store string u typed。这就是缓冲区溢出漏洞的原理。
test调用getbuf函数,然后我们希望getbuf执行完毕后去执行touchX(1,2,3)函数
00000000004017a8 <getbuf>:
4017a8: 48 83 ec 28 sub $0x28,%rsp //stack frame开辟
//40个字节的空间
4017ac: 48 89 e7 mov %rsp,%rdi
4017af: e8 8c 02 00 00 callq 401a40 <Gets>
4017b4: b8 01 00 00 00 mov $0x1,%eax
4017b9: 48 83 c4 28 add $0x28,%rsp
4017bd: c3 retq
4017be: 90 nop
4017bf: 90 nop
所以让我们输入以下这样的字符串
输入命令
./hex2raw < level1.txt | ./ctarget -q
-q 是为了不连接CMU的服务器
攻击成功,是不是很简单。
level 2
下面是touch2函数的源代码
要求
他的意思就是还需要传递正确的参数——cookie,cookie在他给的文件里面
这里面要运用 jmp rsp的知识了
插一嘴
为了对抗jmp esp,栈不可执行技术应运而生
查看传参数的寄存器
所以我们只需要讲rdi里面设置成Cookie,然后将 touch2的地址存入栈中,然后ret
ret 等价于 pop eip 将栈顶的地址传入eip中,rip就是计算机下一步要执行的地址
touch2的地址是 0x4017ec,写一段汇编代码
现在我们只要找到rsp地址就行了
gdb狠狠地调试!
断点的选取看汇编代码
找到RSP的地址
开始构建
开始攻击
成功!
level 3
touch3里面还调用了别的函数,传的arg是字符串的地址
流程:
为什么要将RSP+8的位置设成字符串的首地址
我们可以通过制造缓冲区溢出,只要精心设计我们的填充内容,我们就可以在返回地址之上的内容修改成我们的参数,这也是为了保证我们的参数内容不会被篡改,同时可以根据rsp方便计算。
现在的rsp:
0x5561dc78+0x28(减去的地址)+0x8即为参数的地址
同level2实验编写汇编代码
设置填充内容
查表计算cookie的16进制形式
Part2: ROP
rop的难度比注入代码要难很多,但是也是很难防御的,thwart。
简单理解就是用正常的代码做一个缝合怪。
按照文档中的示例举例子
The byte sequence 48 89 c7 encodes the instruction movq %rax, %rdi.
英语不难,不想翻译了。
The function starts at address 0x400f15, and the sequence starts on the fourth byte of the function. Thus, this code contains a gadget, having a starting address of 0x400f18, that will copy the 64-bit value in register %rax to register %rdi.
我们要用的都来自提供的farm.c,自己不要去手动自己创建自己想要的代码
要求
1、只能使用前八个x86-64寄存器 %rax-%rdi ;
2、只能使用 movq, popq, ret, nop的 gadget;
3、只能使用两个 gadget完成攻击;
level2 on Rtarget
首先编译farm.c代码
5f c3=pop rdi 把参数传进rdi中
蓝狗了都是一样的原理
后面也是一样同理,累了不想写了,润。