当前位置: 首页 > news >正文

【学习记录】Week14(一):信息泄露系统化方法论与 ORW 基础体系构建

写在前面:欢迎进入 Week14 的学习!在过去的几周里,我们深潜了 glibc 堆管理器(Week11-12)和 IO_FILE 机制(Week13),掌握了极其强大的内存破坏与控制流劫持手段。然而,无论多精妙的利用链,都建立在一个绝对前提之上:我们需要知道东西在哪(Libc 基址、堆基址、栈基址)。本周我们将跳出单一漏洞类型的局限,转向系统化的漏洞利用工程学。今天,第一篇将为你梳理信息泄露的系统化方法论,并以此为基础,引入现代 CTF 绝对的高频考点——ORW(Open-Read-Write)任意文件读取体系

📑 目录

  1. 破局之基:为什么信息泄露是 PWN 的生命线?
  2. 🎯 信息泄露系统化 Checklist(实战速查表)
  3. 沙箱降临:为什么execve逐渐失效?
  4. ORW 基础架构:从系统调用到 ROP 链构造
  5. 总结与下篇预告

1. 破局之基:为什么信息泄露是 PWN 的生命线?

现代操作系统普遍开启了 ASLR(地址空间随机化)、PIE(程序代码段随机化)和 NX(不可执行栈)。在没有泄露的情况下,我们手里的漏洞(如栈溢出、UAF)就像是黑夜中拿着一张藏宝图,但既不知道自己在哪,也不知道宝箱在哪。

  • 不知道 Libc 基址:找不到system/bin/sh,无法 ret2libc。
  • 不知道堆基址:无法计算 Tcache 异或密钥(Safe-Linking),无法精准伪造堆块。
  • 不知道栈基址:无法进行栈迁移,无法将 ROP 链写到正确位置。

因此,打 PWN 的第一步,永远是寻找泄露原语。掌握如何从各种残缺的内存环境中“榨取”地址,是成熟 PWN 选手的基本素养。

2. 🎯 信息泄露系统化 Checklist(实战速查表)

💡强烈建议将本节内容保存为你的个人 Checklist,打题时按图索骥。

2.1 泄露 Libc 地址

触发场景 / 漏洞类型泄露目标原理与操作
Unsorted Bin 残留main_arena+88释放一个大于 Fastbin/Tcache 大小的 chunk,其fdbk指向 Unsorted Bin 链表头。通过 UAF 或 Show 功能读取。
GOT 表读取libc 函数真实地址程序若有puts/printf配合格式化字符串或任意读,直接读取 GOT 表中已解析的函数(如puts@got),查 Libc 数据库。
stdout低位覆盖libc 内部地址溢出覆盖_IO_2_1_stdout__IO_write_base低位,触发puts打印出 libc 数据段残留的指针。
Partial Overwrite无需泄露,直接爆破/偏移在不知道 Libc 版本时,只覆盖返回地址末尾 1-2 字节,跳转到 libc 中的one_gadget或特定代码段(需配合环境搭建)。

2.2 泄露栈 地址

触发场景 / 漏洞类型泄露目标原理与操作
格式化字符串 (%p)栈上任意数据printf(fmt)的变参在栈上,通过%p%N$p依次泄露栈上的返回地址、旧 RBP 等。
environ指针读取栈基址libc 全局变量environ存放了环境变量数组的栈地址。通过任意读读取environ的值,即可算出当前栈帧位置。
栈残留数据旧 RBP / 返回地址程序再次调用 read/gets 时,若缓冲区未清空,残留的旧栈帧数据可能被随后的puts打印出来。

2.3 泄露堆 地址

触发场景 / 漏洞类型泄露目标原理与操作
Tcache / Fastbin 残留堆块地址释放单个 chunk 进入 Tcache/Fastbin,其fd指针指向下一个堆块(或 NULL)。通过 UAF 读取。
Safe-Linking 泄露堆基址 >> 12glibc 2.32+ 中,Tcache 的fd被加密为(chunk_addr >> 12) ^ next_ptr。若链表仅有一个 chunk,fd即为堆基址的明文右移。
Largebinfd_nextsize堆块地址Largebin 中的 chunk 含有fd_nextsizebk_nextsize指针,必定指向堆区,UAF 读取即可。

2.4 无 Libc 环境的特殊泄露

  • DynELF 技术:通过putswrite的任意读漏洞,不断泄露内存,暴力搜索 ELF 动态链接结构,远程还原 libc(耗时极长,但有效)。
  • 延迟绑定机制攻击:通过覆盖.got.plt的特定字节,强制触发_dl_runtime_resolve,泄露动态链接器内部地址。

3. 沙箱降临:为什么execve逐渐失效?

在掌握信息泄露后,我们通常的目标是执行system("/bin/sh")execve("/bin/sh", NULL, NULL)。这对应着系统调用号59

然而,在 2020 年以后的 CTF 赛事中,出题人越来越频繁地引入Seccomp (Secure Computing Mode)沙箱保护。Seccomp 通过 BPF(伯克利包过滤器)在内核态拦截系统调用。

常见的沙箱规则

line 1: ALLOW syscalls: open, read, write, mmap, mprotect... line 2: KILL syscalls: execve, fork, clone...

一旦execve被拦截,程序直接被内核 SIGKILL。我们精心构造的one_gadgetsystem全部失效。
出路何在?既然不能执行 shell,我们就自己写代码把服务器上的flag文件读出来打印到屏幕上。这就是ORW

4. ORW 基础架构:从系统调用到 ROP 链构造

ORW 是 Open-Read-Write 的缩写,是一套标准的文件读取流程:

  1. open("/flag", 0)-> 返回文件描述符fd(通常是 3)
  2. read(3, buf, 0x100)-> 将 flag 内容读到可写内存buf(如 bss 段或堆)
  3. write(1, buf, 0x100)-> 将buf内容写到标准输出 (fd=1)

4.1 构造 ORW 的前置条件

  1. 能够执行 ROP:栈溢出,或者堆漏洞结合setcontext/IO_FILE 实现栈迁移。
  2. 知道 Libc 地址:用于寻找syscall; ret等 gadget,以及/flag字符串(或自己写入)。
  3. 控制寄存器:能够控制rdi, rsi, rdx, rax这四个关键寄存器。

4.2 ROP 链构造模板 (x64)

假设我们已经能控制栈并执行 ROP,且已知 Libc 基址。我们需要以下 Gadgets:

  • pop rdi; ret
  • pop rsi; ret
  • pop rdx; ret(如果没有,可使用__libc_csu_init中的万能 gadget)
  • pop rax; ret(用于设置系统调用号)
  • syscall; ret

完整 ROP 链伪代码

// 假设 bss_addr 是一块可写内存,用于存放 "/flag" 字符串和读取的数据 // open("/flag", 0) -> sys_open = 2 pop rdi; ret; bss_addr; // rdi = "/flag" 字符串地址 pop rsi; ret; 0; // rsi = O_RDONLY pop rax; ret; 2; // rax = 2 (sys_open) syscall; ret; // read(3, bss_addr+0x100, 0x100) -> sys_read = 0 pop rdi; ret; 3; // rdi = fd (open返回值为3) pop rsi; ret; bss_addr + 0x100; // rsi = 缓冲区地址 pop rdx; ret; 0x100; // rdx = 读取长度 pop rax; ret; 0; // rax = 0 (sys_read) syscall; ret; // write(1, bss_addr+0x100, 0x100) -> sys_write = 1 pop rdi; ret; 1; // rdi = fd (stdout) pop rsi; ret; bss_addr + 0x100; // rsi = 缓冲区地址 pop rdx; ret; 0x100; // rdx = 写入长度 pop rax; ret; 1; // rax = 1 (sys_write) syscall; ret;

漏洞触发: 栈溢出/堆劫持

栈迁移到可控内存

布置 ROP 链

open 打开 /flag

read 读入到 bss/heap

write 打印到屏幕

获取 Flag

4.3 常见难点与对策

  • 没有/flag字符串:ROP 链前面加上read(0, bss_addr, 8),自己从键盘输入/flag\x00写入 bss 段。
  • 没有pop rdx; ret:利用libc_csu_init中的mov rdx, r15; call [r12]进行复杂调用;或者利用read函数本身,因为read的第三个参数在调用前可能残留了合适的值。
  • 没有syscall:如果只禁用了execve而没有禁用open,可以直接调用 libc 中的open函数。

5. 总结与下篇预告

5.1 核心知识点总结

  1. 信息泄露是地基:牢记 Unsorted Bin 泄露 Libc、environ泄露栈、Tcache 残留泄露堆的系统化方法论。
  2. 沙箱逼出 ORW:Seccomp 禁用execve是现代出题趋势,必须掌握 ORW 体系。
  3. ORW 的本质:通过控制寄存器执行open/read/write三个系统调用,核心在于对pop rdi/rsi/rdx/rax; syscall链的拼装。

5.2 下篇预告

在下一篇中,我们将深入探讨沙箱的分析与绕过技术。

  • 如何使用seccomp-tools工具逆向分析题目的沙箱规则。
  • 进阶 ORW:如果open也被禁用了怎么办?(利用openat/proc/self/mem魔法)。
  • ret2mprotect进阶应用:在无libc环境下绕过 NX 执行 shellcode。

结语:信息泄露 Checklist 是你的“寻宝图”,ORW 是你的“破墙锤”。当你把这两者烂熟于心时,无论题目套了多少层保护,你都能找到一条通往 flag 的物理路径。

http://www.jsqmd.com/news/1132445/

相关文章:

  • 用虚拟机实际体验Google Chromium OS (Chrome OS) Pre-Built
  • FastAPI 新手入门第 8 篇:让 /docs 更像一份 API 文档
  • 【 CLI与GUI两种AI编程范式技术解析】终端Agent与可视化IDE架构对比
  • ClaudeCode Skills:IDE内可工程化的AI编程技能体系
  • 从 Agent Memory 到 Object-Scoped Context 的思考
  • !ccstatusline:让你的 Claude Code 状态栏直接封神!
  • 华为防火墙Web登录配置:eNSP环境搭建与安全策略详解
  • JQuery Tips(4)----一些关于提高JQuery性能的Tips
  • 软件:STM32-F1系列-存储器映像(2026/7/5)
  • 基于自然语言的软件工程和程序设计(中)
  • AI模型安全测试革命:从手工POC到自动化Fuzz框架的工程实践
  • GitHub Copilot 实战指南:结对编程式AI辅助开发核心逻辑与7大高频场景
  • 新手流量池实战:从零搭建你的第一个桌面自动化工作流
  • 判断dll是debug还是release,这是个问题
  • SpringBoot JUnit 教程
  • Qt界面底层实现浅谈: 多渲染后端的分层架构
  • CAF 与 PDAF 监控机制对比:从 3 种检测逻辑到触发条件差异分析
  • 126、DyHead 动态检测头替换 YOLOv11 Head:Scale+Space+Task 三维注意力的实现
  • 宝鸡装修必看:安柏特全屋定制厂环保板材解析
  • 视频孪生时空感知技术详解
  • C# 基础入门指南:从零开始学习 C# 编程
  • XCA开源证书管理:如何用现代工具解决传统PKI难题
  • 【译】组织好你的Asp.Net MVC解决方案
  • 实战指南:如何将微信聊天记录转化为个人AI训练数据资产
  • NHibernate Issues之1255:联合主键(composite-id)
  • 该如何进行WPF界面设计
  • o1-preview在机器学习项目中的协同建模实战
  • 6款主流AI智能降重工具 降痕效果拉满
  • Claude Code Review实战:AI驱动的自动化代码审查部署与优化指南
  • 【Bug已解决】Claude Team Plan 购买席位报错 Payment failed 解决方案