【学习记录】Week2(六):崩溃复盘——Core Dump 分析与精准定位实操
写在前面:在写 Exploit 的过程中,程序崩溃是家常便饭。段错误往往意味着我们覆盖到了关键地址,但到底覆盖了哪个偏移?返回地址跑飞到了哪里?如果只靠肉眼看报错信息,无异于盲人摸象。今天我们就来学习 PWN 界的“黑匣子”——Core Dump 文件,教你如何在程序坠毁的废墟中秒级定位漏洞偏移。
📑 目录
- 什么是 Core Dump?为什么它是 PWN 神器?
- 第一步:开启 Core Dump 生成
- 第二步:手动分析 Core Dump(GDB 基础)
- 终极杀器:Pwntools 自动化偏移定位
- Week2 完结感言
1. 什么是 Core Dump?为什么它是 PWN 神器?
当程序发生严重错误(如段错误Segmentation Fault)崩溃时,操作系统会将该进程在崩溃瞬间的内存镜像、寄存器状态、栈信息等全部转储到一个文件中,这就是 Core Dump 文件。
在 PWN 中的作用:
当你发送了一大串不可读的 Payload(比如cyclic生成的偏移字符串)导致程序崩溃时,你不需要知道是第几个字符导致了溢出。只需要查看 Core Dump 文件中崩溃瞬间的RIP或RSP寄存器值,就能反推出精确的填充长度!
2. 第一步:开启 Core Dump 生成
出于系统性能考虑,大多数 Linux 发行版默认关闭了 Core Dump 的生成。我们需要手动开启。
命令:
ulimit -c unlimitedulimit -c用于设置 Core 文件的最大大小,unlimited表示不限制。
假设性说明(模拟验证环境):
执行完毕后,你可以通过ulimit -c查看当前设置,终端应输出unlimited。此时,如果你运行一个会段错误的程序,当前目录下通常会生成一个名为core或core.<pid>的文件。
3. 第二步:手动分析 Core Dump(GDB 基础)
假设我们用cyclic 200(生成 200 字节的规律字符串)打爆了一个 64 位程序的栈溢出,生成了core文件。
命令:
gdb ./vuln coreGDB 会自动加载二进制文件和崩溃时的内存镜像,并直接停在崩溃的那一行。
假设性说明(模拟 GDB 输出):
GDB 加载后,终端会显示崩溃原因和寄存器状态:
[New LWP 12345] Core was generated by `./vuln'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x0000616161616162 in ?? ()看到这里,关键信息来了!程序试图跳转到0x0000616161616162执行,但这并不是一个合法地址,所以崩溃了。这说明我们成功覆盖了返回地址,且返回地址被填充成了baaa(由于小端序,倒序显示为6161...6261)。
我们在 GDB 中查看寄存器:
pwndbg> info registers rsp rsp 0x616161616163 0x616161616163此时RSP(栈顶指针)指向的值是caaa。
手动计算偏移:
我们打开 Python,使用 pwntools 的cyclic_find函数:
from pwn import * print(hex(cyclic_find(0x616161616162))) # 或者用 nfind 视具体覆盖情况模拟输出:
0x48秒出结果!偏移量就是 72(0x48 的十进制)。我们只需要在 Payload 前面填充 72 个字节,就能精准控制返回地址。
4. 终极杀器:Pwntools 自动化偏移定位
手动生成 Core 文件再拖进 GDB 还是太慢了。Pwntools 提供了一个极其优雅的模块corefile,可以在脚本运行崩溃后瞬间完成上述所有分析。
实战脚本模板:
from pwn import * context.binary = './vuln' context.log_level = 'debug' # 1. 启动进程并发送导致崩溃的 cyclic pattern p = process('./vuln') p.sendline(cyclic(200)) # 2. 等待进程崩溃并自动加载 corefile p.wait() core = p.corefile # 3. 提取崩溃时的寄存器值 (以 64 位 RIP 为例) # 如果是 32 位,通常看 EIP crash_addr = core.rsp log.success(f"程序崩溃时的栈顶值为: {hex(crash_addr)}") # 4. 自动计算偏移 offset = cyclic_find(core.rsp & 0xffffffffffffffff) log.success(f"计算得出精准偏移量: {offset}")假设性说明(模拟脚本运行输出):
[DEBUG] Received 0x1 bytes [*] Process './vuln' stopped with exit code -11 (SIGSEGV) [*] './vuln' core dumped [+] 程序崩溃时的栈顶值为: 0x616161616163 [+] 计算得出精准偏移量: 72不需要打开 GDB,不需要手动敲命令,一行脚本直接把偏移量吐到屏幕上。这就是自动化的力量!
5. Week2 完结感言
至此,Week2 的全部六大模块宣告完成!
从微观的 ELF 节区、汇编指令,到宏观的 Glibc 版本演进;从信息泄露的 Libc 定位,到对抗反调试与崩溃定位。我们补齐了 PWN 学习中所有关键的底层拼图。
如果说 Week1 是学会了“怎么打”,那么 Week2 就是学会了“打哪里”、“为什么这么打”以及“打坏了怎么修”。
如果 Week2 的系列文章对你的 PWN 学习有帮助,请一键三连支持一下!你的鼓励是我持续更新的动力。我们 Week3 见!🙏