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

【学习记录】Week15(四):多漏洞叠加与纯 ROP 艺术一一综合实战的巅峰对决

写在前面:欢迎来到 Week15 的压轴篇!经过前三篇的砺炼,我们已经掌握了栈溢出、格式化字符串、UAF 与 Tcache 的独立利用。然而,现代 CTF 的高分 PWN 题,早已不再是“单打独斗”的舞台。出题人往往会将多个漏洞揉合在一个程序中,并辅以沙箱、去符号表等严苛限制。今天,我们将探讨如何将fmtUAFORW等技术串联成完整的攻击链,并在没有堆漏洞的情况下,利用纯 ROP 完成沙箱逃逸与 Flag 读取。

📑 目录

  1. 循环的艺术:loop 型 fmtstr 综合利用
  2. 终极组合拳:fmt + UAF + ORW 全链路打通
  3. 盲人摸象:无符号漏洞与 Heap 的结合
  4. 纯粹的执行流:无 Heap 漏洞的纯 ROP + ORW
  5. Week15 总结与下期预告

1. 循环的艺术:loop 型 fmtstr 综合利用

在基础题中,格式化字符串漏洞往往只能触发一次(如printf(buf); exit(0);)。但在综合题中,常存在while(1)循环不断接收输入并触发printf。这赋予了我们强大的“无限写”与“无限读”能力。

1.1 劣势反转:从单次到无限

单次 fmtstr 的痛点在于:我们需要在栈上找到指向栈自身的指针,才能实现任意地址写。而 loop 型 fmtstr 彻底解决了这个问题:

  1. 第一步:泄露栈基址。通过%p泄露栈上的旧 RBP 或返回地址,计算出当前栈帧的绝对地址。
  2. 第二步:布置目标地址。通过read将我们要写的目标地址(如 GOT 表项、__free_hook)写入栈上的某个已知偏移。
  3. 第三步:精准写入。利用%N$n将上一步布置在栈上的地址作为指针,写入数据。

1.2 实战场景:劫持printf的返回地址

当程序开启了 Full RELRO(GOT 表不可写)时,我们可以通过 loop 型 fmtstr 直接篡改栈上的返回地址。

  • 泄露栈地址与 Libc 基址。
  • 在栈上布置一段可写的内存地址(如 bss 段或栈本身)。
  • 利用%n将 ROP 链逐个字节(或双字)写入该栈地址。
  • 当循环结束时,程序返回到我们伪造的 ROP 链上。

2. 终极组合拳:fmt + UAF + ORW 全链路打通

设想这样一道“缝合怪”题目:

  1. 菜单题,存在 UAF 漏洞。
  2. 程序中某处存在格式化字符串漏洞(如打印堆块内容时用了printf(chunk_ptr))。
  3. 开启了 Seccomp 沙箱,禁用execve
  4. glibc 2.34(无 Hook)。

2.1 攻击链路规划

面对这种题目,我们需要用 fmtstr 辅助 UAF,最终走向 ORW。

触发 fmtstr 漏洞

泄露 Libc 基址与堆基址

利用 UAF 构造 Tcache Poisoning

劫持 _IO_list_all 或 stdout

伪造 FILE 结构体 (House of Apple)

利用 IO 伪造实现栈迁移

执行布置在堆上的 ORW ROP 链

读取 Flag

2.2 细节剖析

  • 信息泄露:UAF 释放进 Unsorted Bin 可以泄露 Libc,但如果有其他干扰堆块,利用 fmtstr 读取栈上的 Libc 残留往往是更稳定的手段。
  • 栈迁移的桥梁:在 glibc 2.34+ 中,UAF 劫持_IO_list_all后,利用 House of Apple 2/3 可以调用setcontext或 ROP gadget。但 ROP 链写在哪?我们可以利用 UAF 分配一块堆内存,将 ORW 的 ROP 链写在堆上,然后通过伪造 IO 结构体的_IO_save_base或利用_IO_wfile_overflow链中的leave; retgadget,将 RSP 迁移到堆上执行 ORW。

3. 盲人摸象:无符号漏洞与 Heap 的结合

当题目使用strip去除符号表时,IDA 中只能看到sub_XXX,我们无法直接通过elf.symbols['system']获取地址。

3.1 静态分析与动态定位

  1. 字符串定位法:通过查看程序的字符串引用(如/bin/sh、菜单文字),反向定位main函数和各个功能函数。
  2. 偏移特征法:无符号的 libc 函数在 PLT 表中的跳转是有规律的。通过 GDB 动态调试,x/10i 0x401020(假设是某个 PLT 表项),可以识别出这是puts还是malloc
  3. 堆结构特征:即使没有符号,我们依然可以通过释放堆块后的fd指针变化,确认它是 Tcache (glibc 2.26+) 还是 Fastbin (老版本)。

3.2 无符号下的 ORW 构造

在无符号环境下找 ROP gadget 极其困难。此时的核心策略是:利用泄露出真实地址的 libc 函数,在 libc 中寻找 gadget
只要通过 fmtstr 或 UAF 泄露了puts的真实地址,查 Libc 数据库得知 libc 版本,接下来所有的 gadget (pop rdi; ret,syscall; ret) 全部从 libc 中提取,而不再依赖主程序。

4. 纯粹的执行流:无 Heap 漏洞的纯 ROP + ORW

有些题目没有堆操作,只有纯粹的栈溢出,且开了沙箱。由于execve失效,我们必须构造 ORW 链。但这往往面临一个致命痛点:程序本身太短,找不到pop rdx; retsyscall; ret

4.1 ret2csu 控制参数

主程序中通常包含__libc_csu_init,利用其中的 gadget 可以控制rdi, rsi, rdx

mov rdx, r14 mov rsi, r13 mov edi, r12d call [r15]

通过这段代码,我们可以调用read(0, bss_addr, 0x100),将我们的 Shellcode 或后续的 ROP 链读到 bss 段。

4.2 ret2mprotect 执行 Shellcode

既然能控制read,为什么不用mprotect给 bss 段加上执行权限呢?

  1. 利用 ret2csu 调用mprotect(bss_page_addr, 0x1000, 7)(7 = RWX)。
  2. 利用 ret2csu 调用read(0, bss_addr, len),输入 ORW 的 Shellcode。
  3. 通过jmp bss_addr跳转执行。

4.3 纯 ROP 的 ORW 替代方案

如果连mprotect的 PLT 都没有,但程序中残留了__libc_start_main的地址(通常在栈底),我们可以部分覆盖它,将其偏移到 libc 中的syscall; ret附近,从而获得syscall指令,再配合 ret2csu 完成纯 ROP 的 ORW。

5. Week15 总结与下期预告

5.1 核心知识点总结

  1. 多漏洞协同:fmtstr 用于信息泄露和绕过限制,UAF 用于内存控制,ORW 作为最终执行手段。根据题目环境,三者可以灵活组合。
  2. loop 型 fmtstr:赋予了攻击者任意地址写的绝对主动权,是 Full RELRO 下的栈劫持利器。
  3. 无符号对策:静态特征识别结合动态调试,将目光从主程序转向 libc,利用 libc 中的庞大 gadget 库完成利用。
  4. 纯 ROP 突破:在缺乏 gadget 时,__libc_csu_init(ret2csu) 是控制参数的万能钥匙,结合mprotect可以完美降维打击 ORW 需求。

5.2 Week16 预告

历经 Week15 的综合实战,我们对用户态的漏洞利用已驾轻就熟。下周,我们将开启全新的篇章——工具链整合与内核 PWN 入门

  • 工程化武器库pwninit自动化环境搭建、patchelfglibc-all-in-one的无缝切换、GDB 脚本编写。
  • 符号执行辅助:使用angr解决复杂的路径约束与迷宫类题目。
  • 内核初探:从用户态跨入内核态,理解 Ring 0 与 Ring 3 的边界。
  • Kernel 环境搭建:使用 QEMU + GDB 调试 Linux 内核。
  • ret2usr 攻击:利用用户态进程“刺杀”内核的经典操作。

结语:多漏洞叠加题目就像是一组拼图,单独看每一块都不复杂,难点在于如何根据拼图的边缘(漏洞触发的条件和限制)将它们严丝合缝地拼接在一起。本周的综合训练到此结束,当你能独立打通一条从信息泄露到 ORW 的全链路时,你已经具备了在大型赛事中稳定拿分的能力。下周,我们将升级我们的武器库,向内核发起冲锋!

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

相关文章:

  • Savant OpenCV CUDA支持:高性能视频变换的完整指南
  • MarkItDown:如何用Python统一处理数十种文档格式
  • 揭秘Lit模板引擎:10个性能优化技巧让你的Web组件快如闪电 [特殊字符]
  • Thrift接口测试与性能分析:Team IDE的高级功能详解
  • Path of Building PoE2:流放之路2最强离线构建规划工具完全指南
  • Rust Result 组合:错误处理别急着 unwrap
  • FineTuningLLMs实战案例:构建个性化聊天机器人的完整教程
  • 终极深度解析:REPENTOGON如何重塑《以撒的结合》MOD开发新纪元
  • AI Coding 为什么选择 TUI ,前端的新机会在哪里?
  • 如何永久保存微信聊天记录:WeChatMsg让你的对话数据真正属于你
  • 无需Kubernetes也能运行Pod!Demystifying Containers之CRI-O实战教程
  • NVIDIA cuCollections 深度解析:GPU加速并发数据结构的架构设计与实战指南
  • JMeter HTTP缓存管理器:构建真实性能测试场景的核心配置
  • 一套方案跑通三大平台:YOLO全场景部署实战指南,附一键环境配置脚本
  • React Native Paper Dates与React Native Paper完美集成终极教程 [特殊字符]
  • 解决Polars 20个高频技术问题:从安装失败到大数据处理的实战指南
  • 解密机械工程学习新革命:3个突破性方法让你零基础变高手
  • Rain性能优化秘籍:如何提升大规模任务图(10万+任务)的执行效率
  • 基于 OAuth 2 in Action Code 构建移动应用授权:原生客户端实现
  • Vitis-HLS-Introductory-Examples完全指南:从FPGA新手到硬件加速大师的终极路径
  • Catch2 C++测试框架:现代单元测试的优雅解决方案
  • Vue-Croppa视频帧提取:3步实现从视频中获取裁剪图片的完整指南
  • TPH-YOLOv5实战教程:如何在自己的无人机数据集上训练模型
  • 企业级代码库智能分析:5大性能优化策略深度解析
  • Shiny-Server安全加固:保护你的Web应用免受常见威胁
  • Obsidian插件汉化终极指南:如何5分钟让英文插件变中文
  • 5分钟集成方案:为企业级应用添加HTML表格数据导出功能
  • GTA5终极增强指南:YimMenu五分钟快速上手指南
  • 如何快速上手ComfyUI-WanVideoWrapper:AI视频生成终极指南
  • 告别模组混乱:XCOM 2 Alternative Mod Launcher 一站式智能管理解决方案