shellphish/how2heap

GitHub: shellphish/how2heap

系统性的glibc堆利用技术学习仓库,提供跨版本的实践代码和详细注释,是CTF选手和二进制安全研究者的必备参考资料。

Stars: 8558 | Forks: 1257

# 堆利用教学 本仓库用于学习各种堆利用技术。 我们以 Ubuntu 的 Libc 版本作为黄金标准。每项技术均已验证可在相应的 Ubuntu 版本上运行。 你可以运行 `apt source libc6` 来下载你在基于 Debian 的操作系统上所使用的 Libc 源代码。你也可以点击 :arrow_forward: 在浏览器中使用 gdb 调试该技术。 这个想法是在一次黑客会议中提出的,并且我们已经实现了以下技术: | 文件 | :arrow_forward: | 技术 | Glibc-Version | 补丁 | 适用 CTF 题目 | |------|-----|-----------|---------------|-------|---------------------------| | [first_fit.c](first_fit.c) | | 演示 glibc malloc 的 first-fit(首次适配)行为。 | | | | | [calc_tcache_idx.c](calc_tcache_idx.c)| | 演示 glibc 的 tcache 索引计算。| | | | | [fastbin_dup.c](glibc_2.35/fastbin_dup.c) | :arrow_forward: | 通过滥用 fastbin freelist,欺骗 malloc 返回一个已分配的堆指针。 | < 2.43 | [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=fa854fc4b8f75b09902ea7ed1180487beb6e4683;hp=7811152d9d9eba3e0f0a3416d9944cc142caaafe;hb=bf1015fb2d7e4057925481960626533f8571a2fb;hpb=e3062b06c5767f672baf9574c4d7cbebf7d0ee6e) | | | [fastbin_dup_into_stack.c](glibc_2.35/fastbin_dup_into_stack.c) | :arrow_forward: | 通过滥用 fastbin freelist,欺骗 malloc 返回一个近乎任意的指针。 | < 2.43 | [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=fa854fc4b8f75b09902ea7ed1180487beb6e4683;hp=7811152d9d9eba3e0f0a3416d9944cc142caaafe;hb=bf1015fb2d7e4057925481960626533f8571a2fb;hpb=e3062b06c5767f672baf9574c4d7cbebf7d0ee6e) | [9447-search-engine](https://github.com/ctfs/write-ups-2015/tree/master/9447-ctf-2015/exploitation/search-engine), [0ctf 2017-babyheap](https://web.archive.org/web/20181104155842/http://uaf.io/exploitation/2017/03/19/0ctf-Quals-2017-BabyHeap2017.html) | | [fastbin_dup_consolidate.c](glibc_2.35/fastbin_dup_consolidate.c) | :arrow_forward: | 通过将指针同时放入 fastbin freelist 和 top chunk,欺骗 malloc 返回一个已分配的堆指针。 | < 2.43 | [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=fa854fc4b8f75b09902ea7ed1180487beb6e4683;hp=7811152d9d9eba3e0f0a3416d9944cc142caaafe;hb=bf1015fb2d7e4057925481960626533f8571a2fb;hpb=e3062b06c5767f672baf9574c4d7cbebf7d0ee6e) | [Hitcon 2016 SleepyHolder](https://github.com/mehQQ/public_writeup/tree/master/hitcon2016/SleepyHolder) | | [unsafe_unlink.c](glibc_2.35/unsafe_unlink.c) | :arrow_forward: | 利用对一个损坏 chunk 的 free 操作来实现任意写入。 | latest | | [HITCON CTF 2014-stkof](http://acez.re/ctf-writeup-hitcon-ctf-2014-stkof-or-modern-heap-overflow/), [Insomni'hack 2017-Wheel of Robots](https://gist.github.com/niklasb/074428333b817d2ecb63f7926074427a) | | [house_of_spirit.c](glibc_2.35/house_of_spirit.c) | :arrow_forward: | 释放一个伪造的 fastbin chunk 以让 malloc 返回一个近乎任意的指针。 | latest | | [hack.lu CTF 2014-OREO](https://github.com/ctfs/write-ups-2014/tree/master/hack-lu-ctf-2014/oreo) | | [poison_null_byte.c](glibc_2.35/poison_null_byte.c) | :arrow_forward: | 利用单字节 NULL 溢出。 | latest | | [PlaidCTF 2015-plaiddb](https://github.com/ctfs/write-ups-2015/tree/master/plaidctf-2015/pwnable/plaiddb), [BalsnCTF 2019-PlainNote](https://gist.github.com/st424204/6b5c007cfa2b62ed3fd2ef30f6533e94?fbclid=IwAR3n0h1WeL21MY6cQ_C51wbXimdts53G3FklVIHw2iQSgtgGo0kR3Lt-1Ek)| | [house_of_lore.c](glibc_2.35/house_of_lore.c) | :arrow_forward: | 通过滥用 smallbin freelist,欺骗 malloc 返回一个近乎任意的指针。 | latest | | | | [overlapping_chunks.c](glibc_2.27/overlapping_chunks.c) | :arrow_forward: | 利用 unsorted bin 中被释放 chunk 的 size 被覆写,使新分配与现有 chunk 重叠 | < 2.29 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c) | [hack.lu CTF 2015-bookstore](https://github.com/ctfs/write-ups-2015/tree/master/hack-lu-ctf-2015/exploiting/bookstore), [Nuit du Hack 2016-night-deamonic-heap](https://github.com/ctfs/write-ups-2016/tree/master/nuitduhack-quals-2016/exploit-me/night-deamonic-heap-400) | | [overlapping_chunks_2.c](glibc_2.23/overlapping_chunks_2.c) | :arrow_forward: | 利用正在使用的 chunk 的 size 被覆写,使新分配与现有 chunk 重叠 | < 2.29|[补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c) | | | [mmap_overlapping_chunks.c](glibc_2.35/mmap_overlapping_chunks.c) | | 利用正在使用的 mmap chunk,使新分配与当前 mmap chunk 重叠 | latest | | | | [house_of_force.c](glibc_2.27/house_of_force.c) | :arrow_forward: | 利用 Top Chunk (Wilderness) 头部,让 malloc 返回一个近乎任意的指针 | < 2.29 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c) | [Boston Key Party 2016-cookbook](https://github.com/ctfs/write-ups-2016/tree/master/boston-key-party-2016/pwn/cookbook-6), [BCTF 2016-bcloud](https://github.com/ctfs/write-ups-2016/tree/master/bctf-2016/exploit/bcloud-200) | | [unsorted_bin_into_stack.c](glibc_2.27/unsorted_bin_into_stack.c) | :arrow_forward: | 利用 unsorted bin freelist 上被释放 chunk 的覆写,返回一个近乎任意的指针。 | < 2.29 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)| | | [unsorted_bin_attack.c](glibc_2.27/unsorted_bin_attack.c) | :arrow_forward: | 利用 unsorted bin freelist 上被释放 chunk 的覆写,将一个大值写入任意地址 | < 2.29 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c) | [0ctf 2016-zerostorage](https://github.com/ctfs/write-ups-2016/tree/master/0ctf-2016/exploit/zerostorage-6) | | [large_bin_attack.c](glibc_2.35/large_bin_attack.c) | :arrow_forward: | 利用 large bin freelist 上被释放 chunk 的覆写,将一个大值写入任意地址 | < 2.42 | [补丁](https://patchwork.sourceware.org/project/glibc/patch/20250214053454.2346370-1-benjamin.p.kallus.gr@dartmouth.edu/) | [0ctf 2018-heapstorm2](https://dangokyo.me/2018/04/07/0ctf-2018-pwn-heapstorm2-write-up/) | | [house_of_einherjar.c](glibc_2.35/house_of_einherjar.c) | :arrow_forward: | 利用单字节 NULL 溢出欺骗 malloc 返回一个受控指针 | latest | | [Seccon 2016-tinypad](https://gist.github.com/hhc0null/4424a2a19a60c7f44e543e32190aaabf) | | [house_of_water.c](glibc_2.36/house_of_water.c) | | 利用 UAF 或 double free 来实现对 tcache 元数据的无泄漏控制,以及一种将 libc 链入 tcache 的无泄漏方法 | latest | | [37c3 Potluck - Tamagoyaki](https://github.com/UDPctf/CTF-challenges/tree/main/Potluck-CTF-2023/Tamagoyaki)| | [sysmalloc_int_free.c](glibc_2.39/sysmalloc_int_free.c) | | 演示利用 malloc (sysmalloc `_int_free()`) 释放近乎任意大小的 Top Chunk (Wilderness) | latest | | | | [house_of_orange.c](glibc_2.23/house_of_orange.c) | :arrow_forward: | 利用 Top Chunk (Wilderness) 以获得任意代码执行 | < 2.26 | [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) | [Hitcon 2016 houseoforange](https://github.com/ctfs/write-ups-2016/tree/master/hitcon-ctf-2016/pwn/house-of-orange-500) | | [house_of_tangerine.c](glibc_2.39/house_of_tangerine.c) | | 利用 Top Chunk (Wilderness),通过滥用 tcache freelist 欺骗 malloc 返回一个完全任意的指针 | >= 2.26 | | [PicoCTF 2024- high frequency troubles](https://play.picoctf.org/practice/challenge/441?category=6&page=1&search=high%20frequency%20troubles) | | [house_of_roman.c](glibc_2.23/house_of_roman.c) | :arrow_forward: | 通过伪造 fastbins、unsorted_bin 攻击和相对覆写,实现无需泄漏的技术以获得远程代码执行。 |< 2.29 |[补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c) || | [tcache_poisoning.c](glibc_2.35/tcache_poisoning.c) | :arrow_forward: | 通过滥用 tcache freelist 欺骗 malloc 返回一个完全任意的指针。(在 2.32 及以后版本需要堆泄漏) | > 2.25 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=a1a486d70ebcc47a686ff5846875eacad0940e41) | | | [tcache_house_of_spirit.c](glibc_2.35/tcache_house_of_spirit.c) | :arrow_forward: | 释放一个伪造的 chunk 以让 malloc 返回一个近乎任意的指针。 | > 2.25 | | | | [house_of_botcake.c](glibc_2.35/house_of_botcake.c) | :arrow_forward: | 绕过 tcache 上的 double free 限制。让 `tcache_dup` 再次伟大。 | > 2.25 | | | | [tcache_stashing_unlink_attack.c](glibc_2.35/tcache_stashing_unlink_attack.c) | :arrow_forward: | 利用 small bin freelist 上被释放 chunk 的覆写,借助 calloc 欺骗 malloc 返回任意指针并将大值写入任意地址。 | > 2.25 | | [Hitcon 2019 one punch man](https://github.com/xmzyshypnc/xz_files/tree/master/hitcon2019_one_punch_man) | | [fastbin_reverse_into_tcache.c](glibc_2.35/fastbin_reverse_into_tcache.c) | :arrow_forward: | 利用 fastbin 中被释放 chunk 的覆写,将大值写入任意地址。 | 2.26 - 2.42 | [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=fa854fc4b8f75b09902ea7ed1180487beb6e4683;hp=7811152d9d9eba3e0f0a3416d9944cc142caaafe;hb=bf1015fb2d7e4057925481960626533f8571a2fb;hpb=e3062b06c5767f672baf9574c4d7cbebf7d0ee6e) | | | [house_of_mind_fastbin.c](glibc_2.35/house_of_mind_fastbin.c) | :arrow_forward: | 利用带有 arena 处理的单字节覆写,将大值(堆指针)写入任意地址 | < 2.43 | [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=malloc/malloc.c;h=fa854fc4b8f75b09902ea7ed1180487beb6e4683;hp=7811152d9d9eba3e0f0a3416d9944cc142caaafe;hb=bf1015fb2d7e4057925481960626533f8571a2fb;hpb=e3062b06c5767f672baf9574c4d7cbebf7d0ee6e) | | | [house_of_storm.c](glibc_2.27/house_of_storm.c) | :arrow_forward: | 利用对 large 和 unsorted bin chunk 的 use after free,让 malloc 返回任意 chunk| < 2.29 | | | | [house_of_gods.c](glibc_2.24/house_of_gods.c) | :arrow_forward: | 在 8 次分配内劫持线程 arena 的技术 | < 2.27 | | | | [decrypt_safe_linking.c](glibc_2.35/decrypt_safe_linking.c) | :arrow_forward: | 解密链表中的中毒值以恢复实际指针 | >= 2.32 | | | | [safe_link_double_protect.c](glibc_2.36/safe_link_double_protect.c) | | PROTECT_PTR 的无泄漏绕过,通过保护指针两次,允许在 t-cache 中进行任意指针链接 | >= 2.32 | | [37c3 Potluck - Tamagoyaki](https://github.com/UDPctf/CTF-challenges/tree/main/Potluck-CTF-2023/Tamagoyaki)| | [tcache_dup.c](obsolete/glibc_2.27/tcache_dup.c)(已过时) | | 通过滥用 tcache freelist 欺骗 malloc 返回一个已分配的堆指针。 | 2.26 - 2.28 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commit;h=bcdaad21d4635931d1bd3b54a7894276925d081d) | | | [tcache_metadata_poisoning.c](glibc_2.27/tcache_metadata_poisoning.c) | | 通过操纵 tcache 元数据结构欺骗 tcache 提供任意指针 | >= 2.26 | | | | [house_of_io.c](glibc_2.31/house_of_io.c) | | 通过对已释放 tcache chunk 的 UAF 操纵 tcache 管理结构,欺骗 malloc 返回指向任意内存的指针。 | 2.31 - 2.33 | | | | [tcache_relative_write.c](glibc_2.41/tcache_relative_write.c) | | 通过越界 tcache 元数据写入在堆中进行任意十进制值和 chunk 指针写入 | 2.30-2.41 | [补丁](https://sourceware.org/git/?p=glibc.git;a=commit;h=cbfd7988107b27b9ff1d0b57fa2c8f13a932e508) | | | [tcache_metadata_hijacking](glibc_2.42/tcache_metadata_hijacking.c) | | 通过溢出到 tcache 元数据进行任意分配 | >= 2.42 | | | GnuLibc 处于持续开发中,上述技术中有几项已导致在 malloc/free 逻辑中引入了一致性检查。 因此,这些检查经常破坏某些技术,并需要调整以绕过它们(如果可能的话)。 我们通过为每个需要调整的 Glibc 版本保留同一技术的多个版本来解决这个问题。 结构为 `glibc_/technique.c`。 有好的例子? 把它添加到这里! 尽量将整个技术内联在一个 `.c` 文件中 —— 这样学习起来会容易很多。 # 入门指南 ## 快速设置 - 确保你已安装以下包/工具:`patchelf zstd wget`(当然也需要 `build-essential` 或类似的编译器、`make` 等) - 此外,`/usr/bin/python` 必须是/指向你的 `python` 二进制文件(例如 `/usr/bin/python3`) ``` git clone https://github.com/shellphish/how2heap cd how2heap make clean base #### ./malloc_playground Notice that this will link the binaries with your system libc. If you want to play with other libc versions. Please refer to `Complete Setup`. ## 完整设置 You will encounter symbol versioning issues (see [this](https://github.com/shellphish/how2heap/issues/169)) if you try to `LD_PRELOAD` libcs to a binary that's compiled on your host machine. We have two ways to bypass it. ### 方法 1:link against older libc This one tells linker to link the target binary with the target libc. ```shell git clone https://github.com/shellphish/how2heap cd how2heap #### H2H_USE_SYSTEM_LIBC=N make v2.23 This will link all the binaries against corresponding libcs. What's better is that it comes with debug symbols. Now you can play with any libc versions on your host machine. In this example, it will compile all glibc-2.23 binaries and link them with libc-2.23. You can change the number to play with other libc versions. ### 方法 2:use docker This uses Docker-based approach to complie binaries inside an old ubuntu container so it is runnable with the target libc version. ```shell git clone https://github.com/shellphish/how2heap cd how2heap # 下一条命令将准备目标 binary,使其以 # 预期的 libc 版本运行 make base ./glibc_run.sh 2.30 ./malloc_playground -d -p # 现在你可以使用 glibc-2.30 来操作该 binary # 甚至可以使用正确的符号进行调试 readelf -d -W malloc_playground | grep RUNPATH # or use checksec readelf -l -W malloc_playground | grep interpreter #### gdb -q -ex "start" ./malloc_playground # Heap Exploitation 工具 There are some heap exploitation tools floating around. ## Malloc Playground The `malloc_playground.c` file given is the source for a program that prompts the user for commands to allocate and free memory interactively. ## Pwngdb Examine the glibc heap in gdb: https://github.com/scwuaptx/Pwngdb ## pwndbg An exploitation-centric gdb plugin that provides the ability to view/tamper with the glibc heap: https://github.com/pwndbg/pwndbg ## gef Another excellent gdb plugin that provides the ability to examine the glibc heap: https://github.com/hugsy/gef ## heap-viewer Examine the glibc heap in IDA Pro: https://github.com/danigargu/heap-viewer ## heaptrace Helps you visualize heap operations by replacing addresses with symbols: https://github.com/Arinerron/heaptrace # 其他资源 Some good heap exploitation resources, roughly in reverse order of their publication, are: ## 有用的 Heap Exploitation 教程 - Overview of GLIBC heap exploitation techniques (https://0x434b.dev/overview-of-glibc-heap-exploitation-techniques/) - glibc in-depth tutorial (https://heap-exploitation.dhavalkapil.com/) - book and exploit samples - Heap exploitation techniques that work on glibc-2.31 (https://github.com/StarCross-Tech/heap_exploit_2.31) - Painless intro to the Linux userland heap (https://sensepost.com/blog/2017/painless-intro-to-the-linux-userland-heap/) - ptmalloc fanzine, a set of resources and examples related to meta-data attacks on ptmalloc (http://tukan.farm/2016/07/26/ptmalloc-fanzine/) - Glibc Adventures: The Forgotten Chunk (https://github.com/bash-c/slides/blob/master/pwn_heap/Glibc%20Adventures:%20The%20forgotten%20chunks.pdf) - advanced heap exploitation ## 历史上的 Heap Exploitation (The History) - Pseudomonarchia jemallocum (http://www.phrack.org/issues/68/10.html) - The House Of Lore: Reloaded (http://phrack.org/issues/67/8.html) - Malloc Des-Maleficarum (http://phrack.org/issues/66/10.html) - some malloc exploitation techniques - Yet another free() exploitation technique (http://phrack.org/issues/66/6.html) - The use of set_head to defeat the wilderness (http://phrack.org/issues/64/9.html) - Understanding the heap by breaking it (https://www.blackhat.com/presentations/bh-usa-07/Ferguson/Whitepaper/bh-usa-07-ferguson-WP.pdf) - explains heap implementation and a couple exploits - OS X heap exploitation techniques (http://phrack.org/issues/63/5.html) - The Malloc Maleficarum (http://seclists.org/bugtraq/2005/Oct/118) - Exploiting The Wilderness (http://seclists.org/vuln-dev/2004/Feb/25) - Advanced Doug lea's malloc exploits (http://phrack.org/issues/61/6.html) # 加固 There are a couple of "hardening" measures embedded in glibc, like `export MALLOC_CHECK_=1` (enables some checks), `export MALLOC_PERTURB_=1` (data is overwritten), `export MALLOC_MMAP_THRESHOLD_=1` (always use mmap()), ... More info: [mcheck()](http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html), [mallopt()](http://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html). There's also some tracing support as [mtrace()](http://manpages.ubuntu.com/mtrace), [malloc_stats()](http://manpages.ubuntu.com/malloc_stats), [malloc_info()](http://manpages.ubuntu.com/malloc_info), [memusage](http://manpages.ubuntu.com/memusage), and in other functions in this family. ```
标签:Debug, GDB, Glibc, PWN, Web报告查看器, 二进制安全, 内存管理, 堆利用, 堆溢出, 堆风水, 客户端加密, 恶意代码分析, 攻击样本, 缓冲区溢出, 网络安全, 请求拦截, 逆向工具, 配置文件, 隐私保护