Unsorted Bin
FIFO双链表结构:fd指针指向后一个堆块,bk指向前一个。 插入的时候插入到 unsorted bin 的头部,取出的时候从链表尾获取。
chunk size>=0x80
可以leak main arena ==> leak libc base
chunk 通过以下三种途径进入UB
- 当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中。
- 释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。关于 top chunk 的解释,请参考下面的介绍。
- 当进行 malloc_consolidate 时,可能会把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近邻的话。
UB Attack principle
在 glibc/malloc/malloc.c 中的 _int_malloc
有这么一段代码,当将一个 unsorted bin 取出的时候,会将 bck->fd
的位置写入本 Unsorted Bin 的位置。
1 | /* remove from unsorted list */ |
换而言之,如果我们控制了 bk 的值,我们就能将 unsorted_chunks (av)
写到任意地址。
Premise
能够控制free UBchunk的bk指针
Exploit
victim = unsorted_chunks(av)->bk=p
bck = victim->bk=p->bk = target addr-0x10
unsorted_chunks(av)->bk = bck=target addr-0x10
bck->fd = *(target addr -0x10+0x10) = unsorted_chunks(av);
简而言之,将UBchunk->bk改为target addr-0x10,再申请一个UBchunk,target addr的值就被修改为 UB 的链表头部 (一个不可控且很大的值)
Sample
只要choice==4869,magic>=4869就可以cat flag。
create和delete都没问题。edit中对于输入的idx未加校验导致堆溢出。
因此我们通过UB Attack将magic覆盖就能得到flag。
1 | #! /usr/bin/python |