堆入门---unlink的理解和各种题型总结
字数 1397 2025-08-04 08:17:33

堆利用技术:Unlink机制详解与题型总结

一、Unlink机制原理

1. 源码分析

Unlink操作用于合并相邻的free chunk,主要出现在malloc和free函数中:

向后合并(合并前一个free chunk)

if (!prev_inuse(p)) {
    prevsize = p->prev_size;
    size += prevsize;
    p = chunk_at_offset(p, -((long) prevsize)); 
    unlink(p, bck, fwd);
}

向前合并(合并后一个free chunk)

nextchunk = chunk_at_offset(p, size);
nextsize = chunksize(nextchunk);
if (nextchunk != av->top) {
    if (!nextinuse) {
        unlink(nextchunk, bck, fwd);
        size += nextsize;
    }
}

2. Unlink宏定义

#define unlink(P, BK, FD) { 
    FD = P->fd; 
    BK = P->bk; 
    FD->bk = BK; 
    BK->fd = FD; 
    ...
}

3. 保护机制

现代glibc加入了安全检查:

if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                      
    malloc_printerr (check_action, "corrupted double-linked list", P, AV);

二、Unlink利用技术

1. 绕过保护机制的方法

构造满足 P->fd->bk == PP->bk->fd == P 的条件:

  • P->fd = ptr - 24
  • P->bk = ptr - 16

这样:

  • FD->bk = FD + 24 = ptr
  • BK->fd = BK + 16 = ptr

最终执行unlink后,ptr会被修改为ptr-24。

2. 利用步骤

  1. 构造fake chunk
  2. 通过堆溢出修改相邻chunk的size和prev_size
  3. 触发unlink操作
  4. 利用unlink后的指针修改关键数据(如GOT表)

三、典型题型与案例分析

1. bamboobox题型

保护机制:NX、Canary

漏洞点:堆溢出

利用步骤

  1. 构造fake chunk
  2. 溢出修改相邻chunk的size和prev_size
  3. free触发unlink
  4. 修改ptr指向GOT表
  5. 覆盖GOT表为one_gadget

关键exp代码

FD = 0x6020c8 - 3*8
BK = FD + 8
py1 = p64(0) + p64(0x81) + p64(FD) + p64(BK)
py1 += "a"*0x60 
py1 += p64(0x80) + p64(0x90)
change(0,0x90,py1)
free(1)

2. babyheap题型(固定大小malloc)

保护机制:Full RELRO、NX、Canary

利用技术

  1. 泄露堆地址
  2. 构造fake chunk实现堆块错位
  3. 修改chunk大小使其大于fastbin
  4. 构造unlink条件
  5. 泄露libc地址
  6. 修改__free_hook

关键点

  • 通过UAF泄露堆地址
  • 利用堆块错位修改chunk大小
  • 双重功能:泄露libc和任意地址写

3. silent2题型(UAF利用)

利用步骤

  1. 申请多个chunk
  2. 释放特定chunk
  3. 构造fake chunk
  4. 触发unlink
  5. 修改GOT表为system
  6. 执行/bin/sh

4. stkof题型(无输出函数)

利用技巧

  1. 通过unlink修改free的GOT为puts
  2. 使用free作为puts泄露地址
  3. 再次修改free的GOT为one_gadget

5. PWN1题型(off-by-null)

特殊技巧

  1. 计算精确的堆块大小(0xf8)
  2. 利用off-by-null修改chunk状态
  3. 三个地址写同一位置
  4. 覆盖bss段key实现功能解锁

四、防御与绕过技巧

  1. 保护机制

    • Double-linked list检查
    • Size字段检查
    • Inuse位检查
  2. 绕过方法

    • 精确构造fake chunk
    • 利用数学等式满足检查条件
    • 结合其他漏洞如UAF、off-by-one

五、总结与扩展

  1. 关键技术点

    • Fake chunk构造
    • 堆布局控制
    • 保护机制绕过
    • 地址泄露技巧
  2. 扩展方向

    • 结合house of force
    • 结合fastbin attack
    • 结合tcache机制
  3. 学习建议

    • 理解glibc源码实现
    • 动态调试跟踪内存变化
    • 多练习不同场景下的unlink利用

通过系统学习unlink机制及其在各种场景下的应用,可以深入理解堆管理的工作原理,为更复杂的堆利用技术打下坚实基础。

堆利用技术:Unlink机制详解与题型总结 一、Unlink机制原理 1. 源码分析 Unlink操作用于合并相邻的free chunk,主要出现在malloc和free函数中: 向后合并(合并前一个free chunk) 向前合并(合并后一个free chunk) 2. Unlink宏定义 3. 保护机制 现代glibc加入了安全检查: 二、Unlink利用技术 1. 绕过保护机制的方法 构造满足 P->fd->bk == P 和 P->bk->fd == P 的条件: 令 P->fd = ptr - 24 令 P->bk = ptr - 16 这样: FD->bk = FD + 24 = ptr BK->fd = BK + 16 = ptr 最终执行unlink后,ptr会被修改为ptr-24。 2. 利用步骤 构造fake chunk 通过堆溢出修改相邻chunk的size和prev_ size 触发unlink操作 利用unlink后的指针修改关键数据(如GOT表) 三、典型题型与案例分析 1. bamboobox题型 保护机制 :NX、Canary 漏洞点 :堆溢出 利用步骤 : 构造fake chunk 溢出修改相邻chunk的size和prev_ size free触发unlink 修改ptr指向GOT表 覆盖GOT表为one_ gadget 关键exp代码 : 2. babyheap题型(固定大小malloc) 保护机制 :Full RELRO、NX、Canary 利用技术 : 泄露堆地址 构造fake chunk实现堆块错位 修改chunk大小使其大于fastbin 构造unlink条件 泄露libc地址 修改__ free_ hook 关键点 : 通过UAF泄露堆地址 利用堆块错位修改chunk大小 双重功能:泄露libc和任意地址写 3. silent2题型(UAF利用) 利用步骤 : 申请多个chunk 释放特定chunk 构造fake chunk 触发unlink 修改GOT表为system 执行/bin/sh 4. stkof题型(无输出函数) 利用技巧 : 通过unlink修改free的GOT为puts 使用free作为puts泄露地址 再次修改free的GOT为one_ gadget 5. PWN1题型(off-by-null) 特殊技巧 : 计算精确的堆块大小(0xf8) 利用off-by-null修改chunk状态 三个地址写同一位置 覆盖bss段key实现功能解锁 四、防御与绕过技巧 保护机制 : Double-linked list检查 Size字段检查 Inuse位检查 绕过方法 : 精确构造fake chunk 利用数学等式满足检查条件 结合其他漏洞如UAF、off-by-one 五、总结与扩展 关键技术点 : Fake chunk构造 堆布局控制 保护机制绕过 地址泄露技巧 扩展方向 : 结合house of force 结合fastbin attack 结合tcache机制 学习建议 : 理解glibc源码实现 动态调试跟踪内存变化 多练习不同场景下的unlink利用 通过系统学习unlink机制及其在各种场景下的应用,可以深入理解堆管理的工作原理,为更复杂的堆利用技术打下坚实基础。