背景概念
代码注入(Code Injection)
在栈随机化和金丝雀保护禁用时,利用缓冲区溢出。攻击者用恶意代码地址覆盖返回地址。
金丝雀保护(Canary Protection)
系统使用段寄存器内存保护(%fs:0x28)检测溢出攻击。XOR操作在函数返回前验证金丝雀值。
ROP(Return-Oriented Programming)
当栈随机化启用时,攻击者无法可靠地注入代码。取而代之的是利用程序中已有的指令片段(gadget),通过返回地址将它们链接起来,无需注入新的可执行代码。
关键工具
- Objdump:反汇编二进制文件
- GCC:编译汇编代码
- GDB:调试可执行文件
- Hex2raw:将十六进制输入转换为原始字节
挑战关卡
Touch1
最简单的关卡:溢出缓冲区(0x38字节)并用 touch1 的地址(0x4017ac)覆盖返回地址。由于小端编码,地址在payload中需要反转。
Touch2
需要将cookie值作为第一个参数传递(rdi寄存器)。解决方案包括注入汇编代码:
- 将cookie移动到rdi
- 压入touch2地址
- 执行
ret跳转到touch2
Touch3
与touch2类似,但需要传递cookie的字符串表示。字符串必须以null结尾,并放置在注入代码可访问的内存中。
ROP 挑战
对于随机化栈,使用程序中找到的gadget(以 ret 结尾的短指令序列)。通过在栈上仔细放置返回地址将它们链接在一起。
关键发现
在测试中发现,包含 0x0a(换行符)的输入会在 Gets() 函数中提前终止。由于gadget地址随机包含该字节,解决方案是用大量填充填充栈区域,将执行转移到test函数的栈帧中,避免有问题的地址字节。
这种非常规的变通方法揭示了对攻击机制和内存布局的更深理解,尽管它需要在payload中进行大量填充。