这篇文章单独记录 Attack Lab。目标是理解栈溢出、返回地址、代码注入和 ROP,不把它和 Bomb Lab 混在一起。
0. 实验对象
Attack Lab 常见文件:
1 | cookie.txt |
含义:
ctarget:用于代码注入攻击rtarget:用于返回导向编程,也就是 ROPcookie.txt:验证用的十六进制数字farm.c:ROP 可以利用的 gadget 来源hex2raw:把十六进制文本转成真实字节输入
1. 最小工作流
1 | ./hex2raw < exploit.txt > exploit.raw |
或者:
1 | ./hex2raw < exploit.txt | ./ctarget -q |
含义:
exploit.txt:手写的十六进制攻击字符串hex2raw:把文本转成原始字节ctarget/rtarget:读取攻击输入
2. Level 1:覆盖返回地址
核心目标:
1 | 让 getbuf 返回时不要回到原来的位置,而是跳到 touch1 |
关键观察:
1 | getbuf: |
0x28 是 40 字节。也就是说,输入超过 40 字节后,就会覆盖返回地址。
栈的大致形状:
1 | 高地址 |
如果把返回地址覆盖成 touch1 的地址,ret 就会跳到 touch1。
3. Level 2:传 cookie 给 touch2
touch2 需要一个参数:
1 | void touch2(unsigned val) |
x86-64 Linux 里,第 1 个参数放在 %rdi。
所以攻击目标变成:
1 | 先把 cookie 放进 %rdi |
典型注入代码:
1 | movq $cookie, %rdi |
ret 的本质:
1 | 从栈顶弹出 8 字节 |
4. ROP 入门
ROP 是 Return-oriented Programming。
核心思想:
1 | 不注入新代码,而是利用程序里已有的小片段代码。 |
这些小片段叫 gadget,通常以 ret 结尾。
例如某段字节中可以截出:
1 | movq %rax, %rdi |
就可以用它把 %rax 的值转移到 %rdi,再继续跳到下一个 gadget。
5. 复盘重点
Attack Lab 真正要训练的是:
- 栈向低地址增长
ret如何改变控制流- 返回地址为什么能被覆盖
- 参数为什么要放进
%rdi - 小端序如何影响地址写法
- 代码注入和 ROP 的区别