简单聊聊堆管理器
众所周知,内存分配方面的策略有很多。不同的操作系统、不同的C语言库甚至应用程序都有不同的堆管理器。就比如:
堆管理器 平台 ptmalloc2 现代Linux (glibc 2.3+) Windows Heap Windows (NT 内核) tcmalloc Google自研,多线程速度快 mallocng musl libc,轻量级而我们主要研究的,就是linux下最常用C语言标准库glibc的堆管理器——ptmalloc2
在pwn区,glibc可谓是令人闻风丧胆,每隔几个版本就整波大的,机制还复杂得离谱。
linux环境下,我们可以运行/lib/libc.so.6查看当前系统的glibc版本。
glibc重大版本
2.23 及之前
除了 safe_unlink 之外,几乎没有值得一提的防护机制。可以理解机制,但过于古老,现在几乎见不到。
2.26
引入万恶之源tcache,虽说在多线程方面性能有所增加,但是安全防护堪称一坨shit。属于堆利用的事故多发地。
2.29
一个密集的“打补丁”版本。Unsorted Bin Attack、House of Force 等经典手法被集中修复,tcache 的 double‑free 检测也进一步增强,利用难度上了一个台阶。
2.32
PWN 选手的噩梦——Safe Linking 横空出世。tcache 和 fastbin 的 fd 指针现在会被加密存储,直接篡改变得非常困难,必须配合地址泄露才能绕过。同时,对齐检查的引入也让构造精密的假堆块变得更加容易失败。
2.34
移除了 __malloc_hook 和 __free_hook 。以前靠堆溢出覆盖这两个钩子就能轻松接管控制流,现在这条路被彻底堵死,攻击者被迫转向_IO_FILE 结构的攻击。
2.36
运行时强制为 GOT 表施加只读保护(等效 Full RELRO)。直接在 GOT 里改写函数指针的方式彻底失效,篡改 _IO_FILE 虚表(如 House of Apple 系列)成为绝对主流。
2.40+
开始重构核心函数,进入现代化阶段。单纯利用堆getshell已经不太可能。
何处启程
- 古代 : 学习无防护的经典利用——glibc 2.23; 学习tcache的经典利用——glibc 2.27。现代环境中,这些手段都有相应的防护措施。
- 近代 :glibc 2.35,Safe-Linking是一个难点,并尝试 tcache stashing unlink attack 等高阶技巧。
- 现代 :glibc 2.37 - 2.43,堆利用与glibc其他模块(
IO_FILE等)结合。
根据 how2heap 的利用教程,这次我们先从glibc2.35的基础环境开始,进行一些机制以及著名利用手段(off-by-one, house-of系列等)。
常用工具
- Docker 环境 (如
pwndocker) :强烈推荐用于搭建本地环境,可以轻松切换不同版本的glibc,确保与远程服务器环境完全一致。另外,虚拟环境也方便与主机隔离,防止自己给自己RCE了 。
- pwndbg : 直观查看堆内存布局与各种结构,本地进行调试
- pwntools : 每一个pwn大手子的专武,用于编写脚本(更多功能等待发现)。
知识库
- how2heap :一个学习堆利用技术的绝佳资源库,包含了针对不同glibc版本的各种利用方法(如fastbin_dup, unsafe unlink, house of系列等)的教学代码。
- CTF Wiki :由社区持续维护的CTF知识库,PWN部分涵盖了从入门基础到高级利用的系统性教程。
- ctf pwn之glibc堆利用 : 我的教程(混进了什么奇怪的东西)
本人第一次写教程,求佬友批评指正,我会不断改进的。 ![]()
2 个帖子 - 2 位参与者