1. 解题思路概述
这道CTF题目属于典型的ret2libc题型,考察的是利用缓冲区溢出漏洞实现控制流劫持的技术。题目环境与32位版本的jarvisoj_level2类似,但架构换成了64位,因此在参数传递和栈帧结构上存在显著差异。
在32位架构中,函数参数通过栈传递,而64位架构的前6个参数通过寄存器传递(依次为rdi、rsi、rdx、rcx、r8、r9)。这种差异直接影响了我们的攻击payload构造方式。题目中已经提供了system函数和"/bin/sh"字符串的地址,这大大简化了我们的攻击流程。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞分析与利用准备
2.1 缓冲区溢出点定位
通过逆向分析可以确定,程序中存在一个缓冲区大小为128字节的漏洞点。在64位架构下,要覆盖到返回地址需要考虑以下因素:
- 缓冲区本身大小:128字节
- 栈帧对齐要求:64位架构通常需要8字节对齐
- 保存的基指针(RBP):额外占用8字节
因此,我们需要填充128(缓冲区) + 8(RBP) = 136字节的垃圾数据才能到达返回地址位置。这与32位架构下的140字节填充(128+4+8)形成对比。
2.2 关键地址获取
在本题中,我们需要的两个关键地址都可以直接从程序中获取:
- system函数地址:0x04004C0(通过objdump或gdb可以确认)
- "/bin/sh"字符串地址:0x0600A90(通过字符串搜索可以定位)
提示:在实际CTF比赛中,如果这些地址没有直接给出,可以通过以下方法获取:
- 使用
info functions查看函数地址- 使用
find &system,+9999999,"/bin/sh"搜索字符串- 通过libc基地址计算偏移量
3. 64位架构下的ROP链构造
3.1 参数传递机制差异
64位架构的参数传递规则是我们构造payload时需要特别注意的:
- 前6个参数通过寄存器传递
- 多余的参数才通过栈传递
- system函数只需要一个参数(命令字符串地址)
因此,我们需要将"/bin/sh"的地址放入rdi寄存器,而不是像32位那样通过栈传递。这就需要我们找到一个合适的gadget来实现这个操作。
3.2 关键gadget定位
在程序中我们
