Attack Lab
Last updated on February 8, 2024
Code Injection
利用缓冲区溢出,攻击 ctarget
。
1
思路:找到 touch1
的起始地址,使得从 getbuf
返回时会将控制转移到 touch1
。
disas getbuf
1 |
|
发现分配了 40 个字节的栈帧
只需要输入 48 个字符,前 40 个字节将 getbuf
的栈空间填满,后 8 个字节将返回值覆盖为 touch1
的地址。这样,在 getbuf
执行 retq
指令时,程序就会跳转执行 touch1
函数。
disas touch1
查到 touch1
代码地址为:0x4016ef
写输入文件时,注意字节序为小端。
1 |
|
执行:
1 |
|
2
第二关中,不仅需要修改返回地址,利用 ret
指令将控制转移到 touch2
,还需要传入一个参数,要求与 cookie 的值相同。
思路:在攻击字符串中注入少量代码。通过两次 ret
,先返回到注入的攻击代码处,再返回 touch2
。
查看 getbuf
分配栈帧后,%rsp 指向 0x55622bd8,第一次应返回此处。
注入代码应:
- 将 cookie 的值存入第一个参数寄存器 %rdi
- 将
touch2
的地址压栈 - ret
查看 cookie 值为:0x704163d2
disas touch2
查到 touch2
代码地址为:0x40171b
1 |
|
1 |
|
1 |
|
3
第三关中,要传递字符串作为参数。
调用 touch3
和 hexmatch
函数时,会将数据压入栈中,覆盖 getbuf
使用的缓冲区内存。为了避免被覆盖,应该把 cookie 字符串数据存在 test
的栈上。
查看 test
分配栈帧后,%rsp 指向 0x55622c08。
(或者不用查看,根据 2 直接算:0x55622c08 = 0x55622bd8 + 0x28 + 0x8)
这就是字符串要存放的地址,也是调用 touch3
时传入的参数。
disas touch3
查到 touch3
代码地址为:0x4017ef
1 |
|
输入 56 个字节。开头 40 个字节放注入代码的字节表示,中间 8 个字节放注入代码的地址用来覆盖返回地址,最后 8 个字节放 cookie 的 ASCII 码。
最终栈结构:
cookie 值 0x704163d2 转 ASCII 为:37 30 34 31 36 33 64 32 00
1 |
|
Return-Oriented Programming
攻击 rtarget
:栈随机化 + 栈上代码不可执行,现在怎么办?
在已经存在的程序中找到特定的以 ret
结尾的指令序列为我们所用,把要用到部分的地址压入栈中,每次 ret
后又会取出下一个 gadget。这样就能形成一个程序链,实现攻击。
需要从 gadget farm 中,找出有用的 gadget,执行类似于上面第 2 关和第 3 关的攻击。
4
重复 2 的攻击,也就是需要拼出下面的代码:
1 |
|
将 cookie 放在栈上,再借助 gadget 里的 pop 指令,将存入的 cookie 弹出。
1 |
|
但是,farm 中找不到 5f
于是只能曲线救国,使用两个 gadget:
1 |
|
反汇编 rtarget
1 |
|
查找 58:
地址 401885
查找 48 89 c7:
地址 4018a6
最终栈结构:
写入:
1 |
|
5
重复 3 的攻击,即要求:最终,%rdi 存 cookie 地址,然后返回 touch3
。
区别在于,由于栈随机化,不再能像 3 中一样直接获取 cookie 字符串的地址。
解决方案:在代码中获取 %rsp 的地址,然后加上偏移量来确定 cookie 的地址。
怎么加?发现有一个 add 的 gadget。
地址 4018b6
查找 mov %rax, %rdi -48 89 c7 :
地址 4018a6
此前,需要把基址 %rsp 移到 %rdi,偏移量移到 %rsi。
查找 mov %rsp , %___ - 48 89 e_:
48 89 e0 - mov %rsp, %rax
地址 4018bd
查找 mov %rax, %rdi
- 48 89 c7:
同 4,地址 4018a6
现在已经有了基址,偏移量还需要从栈上弹出,然后一顿倒寄存器。
查找 popq %rax
- 58:
同 4,地址 401885
逆序查找,偏移量需要从 %rax 最终移到 %rsi。但是,farm 中并没有以 %rsi 为目标的 mov 指令。
于是只能改用低字节的 movl。
查找 movl %___ , %esi:
89 d6 - movl %edx, %esi
地址 401988
查找 movl %___ , %edx:
这里,84 c0 是 testb,对结果没有影响
89 ca - movl %ecx, %edx
地址 4018ca
查找 movl %___ , %ecx:
这里,84 d2 是 testb,对结果没有影响
89 c1 - movl %eax, %ecx
地址 4018c4
最终栈结构:
偏移量 8 * 10 - 8 = 72 = 0x48 (从 getbuf 返回时,%rsp 往上挪了一格)
写入:
1 |
|