逆向实战:从一道 CTF Pwn 题看栈溢出与动态调试
原创
写代码的老兵
写代码的老兵
船山信安
2026年11月3日 00:00
湖南
去阅读
底层手艺 · BINARY
逆向实战:从一道 CTF Pwn 题看栈溢出与动态调试
逆向不是炫技,是把「黑盒二进制」读回「逻辑」。用一道 CTF 题讲清楚栈溢出怎么定位、动态调试怎么跟。
内容偏教学,所有环境为本地练习程序,不涉及任何真实在运营系统。
本文为二进制安全教学,基于本地 CTF 练习程序;不提供针对真实软件的利用,仅讲原理与调试方法。
0101 静态:先用 IDA 看伪代码
拿到二进制先查保护:checksec 看有没有 Canary、NX、PIE、RELRO。再丢进 IDA 看 main 的伪代码,找「用户可控输入写到固定大小缓冲区」的地方。
查看二进制保护机制
checksec --file=./challenge
常见输出:Canary=yes NX=yes PIE=yes
0202 漏洞点:栈溢出与格式化
题目常把 read(0, buf, 0x100) 写进一个远小于 0x100 的栈缓冲区,这就是经典栈溢出。另一种是把用户输入直接送进 printf(user\_input),造成格式化字符串泄露。
静态看到「输入长度不受限」或「格式化参数来自用户」时,基本就能定位漏洞函数。教学题往往把这两类放在一起,逼你先认得、再组合。
0303 动态:gdb 动调跟一遍
静态判断要用动态验证。用 gdb 在漏洞函数下断点,观察输入写到了哪、返回地址被覆盖了多少字节。
在 main / vuln 下断点,观察栈
gdb ./challenge
break vuln
run
x/20xw $rsp # 看栈上内容
动调的价值:把「理论上能写这么多字节」变成「实际看到返回地址在第 N 字节被覆盖」。差这一个确认,利用脚本就写不对。
0404 利用思路(教学):从溢出到控制流
在开启 NX 的环境下,直接塞 shellcode 跑不了,要走 ROP:用程序里已有的代码片段(gadgets)拼出「调用系统函数」的链。这是教学核心,不是真实攻击。
1泄露 libc 基址(通过格式化字符串或 GOT 泄露)。
2用 ROP gadget 调 system(\"/bin/sh\")。
3PIE 下还需先泄露代码段基址。
0505 防护:为什么这些措施存在
| 防护 | 挡住什么 |
| Canary | 覆盖返回地址前先校验cookie |
| NX/DEP | 数据段不可执行 |
| ASLR/PIE | 地址随机化,难定位 |
| FORTIFY | 编译期检查危险函数 |
理解这些防护,才知道真实漏洞为什么「看着能溢出却打不进去」——而加固的方向,正是把它们都打开。
0606 从 CTF 到真实:差异在哪
CTF 把漏洞「摆得很清楚」,真实软件里你要先自己找。但底层能力通用:读保护、看伪代码、动调跟栈、理解调用约定——这些在真实二进制审计里一样用得上。
CTF 练的是「在已知有洞的程序里把利用写出来」;真实逆向练的是「在一堆正常程序里先把洞认出来」。前者是后者的基本功。
参考来源
CTF-Wiki — Stack Overflow / Format String
《程序员的自我修养》— 链接、装载与库
checksec 工具说明(pwntools)
本文为二进制安全教学,基于本地 CTF 练习程序讲解栈溢出与动态调试原理,不提供针对真实软件的利用。
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论