Double Free
简介
- 学习double free的具体利用
Fastbin Double free
Fastbin Double Free 是指 fastbin 的 chunk 可以被多次释放, 因此可以在 fastbin 链表中存在多次。这样导致的后果是多次分配可以从 fastbin 链表中取出同一个堆块, 相当于多个指针指向同一个堆块, 结合堆块的数据内容可以实现类似于类型混淆 (type confused) 的效果。
例子
这里我们还是用how2heap
中的fastbin_dup.c来学习
➜ double_free gcc --version |
解释得蛮清楚的, 但依旧惯例还是自己解释一波吧
首先我们malloc三块chunk
然后free掉第一块
由于fastbin的机制原因, 它在执行
free
时会验证main_arena
直接指向的块, 即指针头部的块。因此如果我们再一次free
chunk1, 会报错。/* Another simple check: make sure the top of the bin is not the
record we are going to add (i.e., double free). */
if (__builtin_expect (old == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}直接再一次free chunk1:
root@6268e63608bf:/ctf/work# ./elf
This file demonstrates a simple double-free attack with fastbins.
Allocating 3 buffers.
1st malloc(8): 0x55d65bb9f010
2nd malloc(8): 0x55d65bb9f030
3rd malloc(8): 0x55d65bb9f050
Freeing the first one...
If we free 0x55d65bb9f010 again, things will crash because 0x55d65bb9f010 is at the top of the free list.
*** Error in `./elf': double free or corruption (fasttop): 0x000055d65bb9f010 ***
Aborted (core dumped)但是它也只检测了第一块, 对链表后面的块却没有执行检测, 因此我们先
free chunk2
, 再free chunk1
是没有问题的, 我们在三个free
后下断来看一下fast bin
pwndbg> bins
fastbins
0x20: 0x555555757020 —▸ 0x555555757000 ◂— 0x555555757020 /* ' puUUU' */
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty然后我们再申请回来三个chunk, 就会发现我们第一个申请的chunk和第三个申请的chunk是同一个chunk
这就是
fast bin
的double free
总结
通过 fastbin double free 我们可以使用多个指针控制同一个堆块, 这可以用于篡改一些堆块中的关键数据域或者是实现类似于类型混淆的效果。 如果更进一步修改 fd 指针, 则能够实现任意地址分配堆块的效果 (首先要通过验证), 这就相当于任意地址写任意值的效果。
Tcache Double free
类似于fastbin, 但是tcache free时没有会验证main_arena
直接指向的块
static __always_inline void |
可以看出, tcache_put()
的检查也可以忽略不计(甚至没有对 tcache->counts[tc_idx]
的检查), 大幅提高性能的同时安全性也下降了很多。
因为没有任何检查, 所以我们可以对同一个 chunk 多次 free, 造成 cycliced list。
例子
这里以tcache_dup.c为例
➜ Desktop ./tcache_dup |
首先我们malloc一块大小为8的chunk
然后我们直接free两次, 现在看
tcache bins
, 可以看到已经形成环链这时我们
malloc(8)
两次, 这时两个chunk指针指向了同一个chunk