unsortedbin leak及unsortedbin attack利用分析
Heap基础知识
[toc]
unsortedbin attack
广义上的unsorted bin attack其实分为unsorted bin leak和unsorted bin attack,前者可以根据unsorted bin的特性来泄露出libc的地址,后者的作用是对一个指定地址写入一个非常大的值(其实是写入main_arena的地址的一个偏移)。
unsortedbin特性
首先是unsorted bin的来源,这里抄一下wiki
1 | |
然后是使用情况,抄一下wiki
1 | |
用一下gzy的图

unsortedbin leak
从上图也可以看到,与unsorted bin直接相连的一个bin是最后插入到unsorted bin里面来的。它的bk指针指向unsorted bin。换句话说,它的bk指针指向main_arena的一个固定偏移,而main_arena和libc_base也有一个固定偏移,那么只要泄露出来了它的bk指针,也就不愁计算出libc的地址了。这里用先插入到unsorted bin的fd指针也是同理的。
unsortedbin attack
作用是向指定地址写入一个非常大的值,即main_arena的一个固定偏移。
unsotred bin attack的攻击过程发生在这种情况:
调用malloc时,反向遍历unsorted bin,若unsorted bin里面恰好有与请求的chunk size相等的chunk大小,那么将对应的chunk取出来,该chunk也就被叫做victim。若不是恰好相等,那么这个chunk就会被放到对应的small bin或者large bin中去。
来看这一小段glibc2.23的源代码:(第一行和第二行之间省略了一部分不影响的)
1 | |
正常情况下,这一小段代码会将victim取出,而unsorted bin继续保持双向链表。注意,victim始终是unsorted bin里面的最后一个chunk,因为是反向遍历的unsorted bin,且遍历到的chunk要么会返回给用户,要么就会被移动到small bin或者large bin里面去。
而攻击情况下,我们将控制victim的bk指针为希望进行地址修改的地方减去0x10的地方。
我们通过画图的方式来解释一下正常情况和攻击的情况。
首先是正常情况:
如图所示,我们假设最后一个chunk刚好是malloc需要的大小,因此被标记为victim。
此时运行到第一行代码 bck = victim->bk;很简单,我们将victim的bk指针指向的chunk标记为bck。如图所示:

然后是第二行代码unsorted_chunks (av)->bk = bck; 很简单,本来unsorted bin的bk指针是指向victim的,而victim将要被malloc,因此先将unsorted bin的bk指针指向bck。
第三行代码bck->fd = unsorted_chunks (av);也很简单,和上面同理,我们要将bck的fd指针指向unsorted bin,以此将victim脱链。这两步如图所示:

此时实际上victim的两个指针还指向它们,但unsorted bin和bck指针都不再指向它,因此相当于victim已经被取出了。
现在我们考虑对其进行攻击的情况。
若我们能够控制victim的bk指针,并将其指向一个fake_chunk(该fake_chunk的fd指针是我们希望修改的值。也就是&fake_chunk + 0x10,那么在代码的第一行bck = victim->bk; ,将会出现如图所示的情况:

那么第二行代码unsorted_chunks (av)->bk = bck;,将会将unsorted bin的bk指针也指向该fake_chunk。
第三行代码bck->fd = unsorted_chunks (av);则是攻击的真正实施:它将bck处的fd指针修改为了unsorted bin的地址。也就是实现了这一步:*(&fake_chunk + 0x10) = unsorted_bin。
此时如图所示:

至此,已经实现了攻击。