网站建设与管理太原网站建设

靖江市弘光电热电器厂 2026/09/09 17:30:35

CTF Pwn模块系列分享(四):ROP链构造,没有后门也能拿shell

上期我们用ret2text实战搞定了基础栈溢出,有朋友问:“如果程序里没有backdoor这种现成的后门函数,该怎么利用栈溢出呢?”

这就是今天要解决的核心问题!今天咱们进入Pwn栈溢出的进阶环节——ROP链构造(Return-Oriented Programming,返回导向编程)。这是CTF Pwn中最核心的进阶技巧之一,核心逻辑是没有后门就自己拼后门——利用程序代码段中现成的小指令片段(gadget),拼接成我们需要的功能(比如执行system(“/bin/sh”))。

一、先拆解:为什么需要ROP?ROP的核心逻辑是什么?

先回顾上一期的ret2text:我们是把返回地址改成了程序自带的backdoor函数地址,直接调用后门拿shell。但在真实CTF题目中,程序几乎不会有这么明显的后门——这时候就需要ROP登场了。

  1. 为什么需要ROP?
    两个核心原因: ① 程序没有现成的后门函数(比如没有调用system(“/bin/sh”)的函数); ② 栈保护机制(比如NX,栈不可执行)——即使我们把shellcode写到栈里,也无法执行(后续会讲,新手先记住:ROP可以避开NX保护)。

  2. ROP的核心逻辑:用“现成指令片段”拼功能
    用大白话拆解ROP:

    通俗例子:ROP就像“拼积木”——程序代码段里有很多现成的“积木块”(gadget),我们不需要自己造积木,只要把这些积木按顺序拼起来,就能搭出“后门”这个成品。

  3. 关键前提:x86_64函数调用约定(再强调一次!)
    构造ROP链的核心是“正确传递函数参数”,还记得上一期讲的x86_64函数调用约定吗?再复习一次(必须记住):

函数的第1个参数 → rdi寄存器

函数的第2个参数 → rsi寄存器

函数的第3个参数 → rdx寄存器 …

所以,要调用system(“/bin/sh”),我们需要先把“/bin/sh”的地址放到rdi寄存器里,再调用system函数。

今天的实战目标:构造ROP链,完成两个操作——① 把“/bin/sh”的地址传入rdi;② 调用system函数 → 最终拿到shell。

二、实战准备:环境&工具&漏洞程序

我们用“无后门、有system函数”的漏洞程序实战(和CTF比赛中的进阶栈溢题逻辑一致),先准备好这些:

  1. 环境:延续之前的Ubuntu 20.04+GDB+pwntools+IDA+ROPgadget
    新增工具:ROPgadget(专门找gadget的神器),终端直接安装:sudo apt install -y ropgadget

  2. 编写漏洞程序(保存为pwn2.c)

    关键说明:

  • 程序没有backdoor函数,但链接了libc库(默认链接),所以有system函数(libc库中的函数);
  • 我们的目标:通过ROP链,调用libc中的system函数,并传入“/bin/sh”参数,拿到shell。
  1. 编译程序(关闭栈保护,开启NX保护——模拟真实题目)
    终端执行命令(复制直接用):gcc -g -fno-stack-protector -no-pie -o pwn2 pwn2.c

参数解释:

  • 去掉了“-z execstack”(默认开启NX保护,栈不可执行,迫使我们用ROP);

  • 保留“-fno-stack-protector -no-pie”(关闭栈保护和地址随机化,新手先避开干扰)。

三、实战步骤:手把手教你构造ROP链,拿shell!

整个解题流程分5步:找漏洞→算溢出偏移→找关键gadget→找system地址和/bin/sh地址→构造ROP链攻击,一步都不能少!

第一步:找漏洞+算溢出偏移(和上一期完全一样)

  1. 用IDA分析程序:vulnerable_function调用了gets函数,确认存在栈溢出;

  2. 用GDB+cyclic算偏移:方法和上一期完全一致,最终算出偏移还是24(因为buf大小还是16字节,栈帧结构相同)。

小提醒:如果偏移算错,后续全白费!不确定的话,再重新算一次~

第二步:找关键gadget(核心!用ROPgadget)

我们需要的核心gadget是“能把参数传入rdi寄存器的gadget”——因为调用system函数需要把“/bin/sh”的地址放到rdi里。

用ROPgadget找gadget,终端执行命令:ROPgadget --binary pwn2 --only “pop|ret”

命令解释: - --binary pwn2:指定要分析的程序; - --only “pop|ret”:只显示包含pop指令和ret指令的gadget(我们需要的是“pop 寄存器; ret”格式的gadget)。

执行后,会找到类似这样的gadget:0x00000000004011c3 : pop rdi ; ret

这就是我们需要的核心gadget!记下来这个地址(比如0x4011c3,每个人的地址可能一样,以自己的输出为准)。

功能:执行“pop rdi”(把栈顶的数据弹出到rdi寄存器),然后执行“ret”(跳转到下一个地址)。

第三步:找system函数地址和/bin/sh字符串地址

要调用system(“/bin/sh”),需要两个关键地址:system函数的地址、“/bin/sh”字符串的地址(这两个都在libc库中)。

  1. 找system函数地址(用IDA)
    打开IDA,把pwn2拖进去,等待分析完成;

按“Shift+F12”打开“Strings window”(字符串窗口),在搜索框输入“system”,找到“system”字符串;

双击“system”字符串,跳转到对应的反汇编代码,顶部显示的地址就是system函数的地址(比如0x401060,以自己IDA显示的为准),记下来!

  1. 找/bin/sh字符串地址(用ROPgadget)
    终端执行命令:ROPgadget --binary pwn2 --string “/bin/sh”

执行后,会输出“/bin/sh”字符串的地址(比如0x402008,以自己的输出为准),记下来!

小技巧:如果ROPgadget没找到,也可以用IDA的“Shift+F12”搜索“/bin/sh”字符串,找到对应的地址。

第四步:构造ROP链(核心!按顺序拼接)

结合x86_64函数调用约定和栈溢出原理,ROP链的结构如下(x86_64架构,每个地址占8字节):ROP链 = 垃圾数据(偏移字节数) + pop rdi; ret gadget地址 + /bin/sh字符串地址 + system函数地址

链的执行逻辑(关键!一定要懂):

  1. 程序执行到ret时,先跳转到“pop rdi; ret” gadget;

  2. 执行“pop rdi”:把栈顶的“/bin/sh字符串地址”弹出到rdi寄存器(完成参数传递);

  3. 执行“ret”:跳转到栈下一个地址——system函数地址;

  4. 调用system函数,此时rdi寄存器里是“/bin/sh”的地址,所以会执行system(“/bin/sh”),拿到shell!

结合我们的实战数据(假设偏移24、gadget地址0x4011c3、/bin/sh地址0x402008、system地址0x401060),用Python构造:

第五步:发送ROP链,拿到shell!

和上一期一样,有两种方式发送,新手先学第一种:

方式1:GDB中测试(确认ROP链有效)
启动GDB:gdb ./pwn2

输入r < rop_payload(把ROP链作为输入发送);

程序执行后,出现“$”提示符——成功拿到shell!输入cat flag即可获取Flag。

方式2:pwntools脚本自动化攻击(比赛常用)
编写完整exp脚本(保存为rop_exp.py):


终端执行脚本:python3 rop_exp.py,直接拿到shell~

四、这6个问题最容易卡壳!

  1. gadget找错:一定要找“pop rdi; ret”格式的,少了ret不行;如果没找到,检查程序是否编译正确,或换用IDA找gadget。

  2. 地址填错:system地址、/bin/sh地址、gadget地址一定要用自己程序的,不能直接抄我的。

  3. ROP链顺序错:必须是“gadget地址 → 参数 → 函数地址”,顺序颠倒会导致执行失败。

  4. 没加p64:所有地址都要用p64转成64位小端字节序,直接写字符串地址会失败。

  5. 偏移算错:偏移错了会覆盖不到返回地址,重新用cyclic确认偏移。

  6. 程序有PIE保护:如果编译时没加“-no-pie”,地址会随机化,导致ROP链失效——新手先关闭PIE练手。

五、下期预告&福利时间

今天我们搞定了ROP链的基础构造,学会了“没有后门也能拼后门拿shell”!下期我们将进入系列最后一期——Pwn实战技巧大整合,涵盖pwntools进阶用法、常见栈保护机制绕过思路、比赛答题策略,帮你整合所有知识点,轻松应对CTF比赛中的Pwn题型!

如果今天的内容对你有帮助,别忘了点赞、在看,转发给一起学CTF的小伙伴~

🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源

想要的兄弟,关注我发送CTF入门,直接免费分享!前提是你得沉下心练,别拿了资料就吃灰,咱学技术,贵在坚持!

给大家准备了2套关于CTF的教程,一套是涵盖多个知识点的专题视频教程:


另一套是大佬们多年征战CTF赛事的实战经验,也是视频教程:

🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源

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

徐州网站建设大良网站建设

第一章:为什么90%的量子程序调试失败?量子程序调试的高失败率源于其与经典计算范式的根本差异。传统调试工具无法直接观测量子态而不破坏叠加性,导致常见的断点和日

2026/06/30 13:25:35

呼和浩特网站建设网站建设公司排名

GTK+开发入门:从历史到安装的全方位指南1. 开启GTK+开发之旅GTK+开发是图形编程领域的重要组成部分,对于想要成为专业图形程序员的开发者来说,深入了解GTK+及其相关知识至关重要。在开始之前,

2026/06/30 14:10:39

黄冈网站建设富阳网站建设

智能家居场景下VibeVoice提供个性化语音反馈在智能音箱越来越“懂”用户的今天,我们却仍常听到机械的播报声:“检测到您已回家。”——语气平板,毫无温度。孩

2026/06/30 11:52:28

大型门户网站建设黄冈网站建设

第一章:Open-AutoGLM跑不动?:深度剖析Mac内存管理与模型量化优化策略在 macOS 平台上部署 Open-AutoGLM 时常遇到“模型加载失败

2026/06/30 10:14:19

网站建设中图片淮北网站建设

作为一名长期使用Mac微信的重度用户,我发现原生微信在功能上存在诸多不便。经过亲测,WeChatExtension-ForMac这款微信插件彻底改变了我的使用体验。它不仅解

2026/06/30 10:37:52

南昌网站建设婚纱摄影网站建设

审计日志留存:满足监管机构的追溯要求在金融风控系统中,一次异常的信贷审批决策引发了合规部门的关注。调查人员试图复现该次推理过程时却发现:模型版本不详、运行环境

2026/06/30 13:39:37

南宁网站建设小企业网站建设

Qwen3Guard-Gen-8B能否检测AI辅助写作中的抄袭倾向?在AI生成内容(AIGC)快速渗透教育、媒体与创作领域的今天,一个日益尖锐的

2026/06/30 12:13:59

广州建设网站邵阳网站建设

LoRA训练日志分析:从Loss曲线中捕捉最佳保存时机在生成式AI的浪潮中,LoRA(Low-Rank Adaptation)已成为开发者手中最

2026/06/30 13:38:06

pc网站建设网站建设域名

解决阅读3.0书荒难题:1629个精品书源完全指南【免费下载链接】最新1629个精品书源.json阅读3.0最新1629个精品书源.json阅读3.0项目地址: https://gitc

2026/06/30 13:30:36

网站建设流程顺德网站建设

💡实话实说:有自己的项目库存,不需要找别人拿货再加价,所以能给到超低价格。摘要随着全球公共卫生事件的频发,高校作为人员密集场所&

2026/06/30 12:34:02