CTF Pwn新手必看:用ROPgadget快速搞定64位程序传参gadget搜索(附常见命令清单)

张开发
2026/5/30 8:31:05 15 分钟阅读
CTF Pwn新手必看:用ROPgadget快速搞定64位程序传参gadget搜索(附常见命令清单)
CTF Pwn实战指南ROPgadget在64位程序中的高效应用第一次接触CTF Pwn题目时面对那些需要构造ROP链的64位程序很多新手都会感到无从下手。特别是在题目没有直接给出system函数和/bin/sh字符串的情况下如何快速找到关键的gadget地址成为解题的关键。本文将带你深入理解x64架构下的参数传递规则并手把手教你使用ROPgadget工具构建完整的ROP利用链。1. 理解x64架构下的参数传递机制在32位系统中函数参数通常通过栈来传递。但在64位系统中这一规则发生了根本性变化。理解这些变化是成功构造ROP链的前提。x64架构下前六个参数按照以下顺序传递第一个参数RDI寄存器第二个参数RSI寄存器第三个参数RDX寄存器第四个参数RCX寄存器第五个参数R8寄存器第六个参数R9寄存器只有当参数超过六个时额外的参数才会通过栈传递。这种变化直接影响我们构造ROP链的方式。寄存器使用优先级对比表参数位置32位架构64位架构第1参数栈RDI第2参数栈RSI第3参数栈RDX第4参数栈RCX第5参数栈R8第6参数栈R9第7参数栈栈提示在构造ROP链时必须按照这个顺序设置寄存器值否则函数调用将无法正确获取参数。2. ROPgadget工具的核心功能解析ROPgadget是一款强大的二进制分析工具专门用于在可执行文件中搜索有用的代码片段(gadgets)。这些gadgets通常以ret指令结尾可以串联起来形成ROP链。2.1 安装与基本配置在开始使用前确保你的系统已经安装了必要的依赖# 安装Capstone反汇编框架 sudo apt-get install python-capstone # 安装ROPgadget git clone https://github.com/JonathanSalwan/ROPgadget.git cd ROPgadget python setup.py install安装完成后可以通过以下命令验证是否安装成功ROPgadget --version2.2 常用命令模式ROPgadget提供了多种搜索模式以下是几种最常用的搜索特定类型的gadgetROPgadget --binary ./target --only pop|ret搜索包含特定寄存器的gadgetROPgadget --binary ./target --only pop|ret | grep rdi搜索字符串ROPgadget --binary ./target --string /bin/sh搜索特定指令序列ROPgadget --binary ./target --opcode 5fc3 # 对应pop rdi; ret3. 实战构建完整的ROP利用链现在我们通过一个具体例子来演示如何从零开始构建ROP链。假设我们有一个64位可执行文件vulnerable需要获取shell。3.1 查找关键gadget首先我们需要找到控制RDI寄存器的gadget因为system函数的第一个参数需要通过RDI传递ROPgadget --binary ./vulnerable --only pop|ret | grep rdi典型输出可能如下0x00000000004012a3 : pop rdi ; ret记下这个地址(0x4012a3)它将在ROP链中用于设置RDI寄存器的值。3.2 查找/bin/sh字符串接下来我们需要找到程序中是否存在/bin/sh字符串ROPgadget --binary ./vulnerable --string /bin/sh如果没有找到完整字符串可以尝试搜索部分字符串ROPgadget --binary ./vulnerable --string sh假设我们找到了字符串地址为0x402010。3.3 查找system函数地址在大多数CTF题目中程序会导入system函数。我们可以使用objdump查看objdump -D ./vulnerable | grep system假设system函数的plt表地址为0x401030。3.4 构建ROP链有了以上信息我们可以构造如下ROP链填充缓冲区直到返回地址pop rdi; ret gadget的地址(0x4012a3)/bin/sh字符串的地址(0x402010)system函数的地址(0x401030)ROP链结构示意图顺序内容作用1A*offset填充缓冲区20x4012a3pop rdi; ret gadget30x402010/bin/sh字符串地址40x401030system函数地址4. 高级技巧与常见问题解决在实际CTF比赛中情况往往更加复杂。以下是几个常见场景的解决方案。4.1 当程序没有提供system和/bin/sh时这种情况下我们需要先泄露libc地址然后计算system和/bin/sh的实际地址。基本步骤如下利用puts或write函数泄露某个函数的got表地址根据泄露的地址计算libc基址计算system和/bin/sh在内存中的实际地址构造最终的ROP链4.2 处理ASLR保护当ASLR开启时地址会随机化。我们需要找到信息泄露漏洞获取某个已知地址计算偏移量推导出其他关键地址4.3 多参数函数调用对于需要多个参数的函数我们需要找到控制多个寄存器的gadgets。例如对于execve(/bin/sh,0,0)我们需要RDI - /bin/sh地址RSI - 0RDX - 0相应的gadget搜索命令ROPgadget --binary ./target --only pop|ret | grep rsi ROPgadget --binary ./target --only pop|ret | grep rdx5. ROPgadget命令速查表为了帮助快速查阅以下是ROPgadget最常用的命令组合基本搜索命令# 搜索所有gadget ROPgadget --binary ./target # 搜索特定类型gadget ROPgadget --binary ./target --only pop|ret # 搜索特定寄存器相关的gadget ROPgadget --binary ./target --only pop|ret | grep rdi字符串搜索命令# 搜索完整字符串 ROPgadget --binary ./target --string /bin/sh # 搜索部分字符串 ROPgadget --binary ./target --string sh高级搜索技巧# 搜索特定指令序列 ROPgadget --binary ./target --opcode 5fc3 # pop rdi; ret # 限制gadget长度 ROPgadget --binary ./target --only mov|ret --depth 5 # 排除坏字符 ROPgadget --binary ./target --filter 0x0a|0x0d在多次CTF比赛实战中我发现最有效的学习方式是通过实际题目不断练习ROP链构造。开始时可能会觉得复杂但随着经验积累这些步骤会变得像肌肉记忆一样自然。记住每个gadget都是你武器库中的一件武器熟练运用它们就能攻克各种Pwn题挑战。

更多文章