unsortedbin leak及unsortedbin attack利用分析

Heap基础知识

[toc]

unsortedbin attack

广义上的unsorted bin attack其实分为unsorted bin leakunsorted bin attack,前者可以根据unsorted bin的特性来泄露出libc的地址,后者的作用是对一个指定地址写入一个非常大的值(其实是写入main_arena的地址的一个偏移)。

unsortedbin特性

首先是unsorted bin的来源,这里抄一下wiki

1
2
3
1.当一个较大的 chunk 被分割成两半后,如果剩下的部分大于 MINSIZE,就会被放到 unsorted bin 中。
2.释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻时,该 chunk 会被首先放到 unsorted bin 中。关于 top chunk 的解释,请参考下面的介绍。
3.当进行 malloc_consolidate 时,可能会把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近邻的话。

然后是使用情况,抄一下wiki

1
2
1.Unsorted Bin 在使用的过程中,采用的遍历顺序是 FIFO,即插入的时候插入到 unsorted bin 的头部,取出的时候从链表尾获取。
2.在程序 malloc 时,如果在 fastbin,small bin 中找不到对应大小的 chunk,就会尝试从 Unsorted Bin 中寻找 chunk。如果取出来的 chunk 大小刚好满足,就会直接返回给用户,否则就会把这些 chunk 分别插入到对应的 bin 中。

用一下gzy的图

img

unsortedbin leak

从上图也可以看到,与unsorted bin直接相连的一个bin是最后插入到unsorted bin里面来的。它的bk指针指向unsorted bin。换句话说,它的bk指针指向main_arena的一个固定偏移,而main_arenalibc_base也有一个固定偏移,那么只要泄露出来了它的bk指针,也就不愁计算出libc的地址了。这里用先插入到unsorted binfd指针也是同理的。

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
2
3
bck = victim->bk;                        
unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);

正常情况下,这一小段代码会将victim取出,而unsorted bin继续保持双向链表。注意,victim始终是unsorted bin里面的最后一个chunk,因为是反向遍历的unsorted bin,且遍历到的chunk要么会返回给用户,要么就会被移动到small bin或者large bin里面去。

而攻击情况下,我们将控制victimbk指针为希望进行地址修改的地方减去0x10的地方。

我们通过画图的方式来解释一下正常情况和攻击的情况。

首先是正常情况:

image-20230623150536713如图所示,我们假设最后一个chunk刚好是malloc需要的大小,因此被标记为victim

此时运行到第一行代码 bck = victim->bk;很简单,我们将victimbk指针指向的chunk标记为bck。如图所示:

image-20230623150554561

然后是第二行代码unsorted_chunks (av)->bk = bck; 很简单,本来unsorted binbk指针是指向victim的,而victim将要被malloc,因此先将unsorted binbk指针指向bck

第三行代码bck->fd = unsorted_chunks (av);也很简单,和上面同理,我们要将bckfd指针指向unsorted bin,以此将victim脱链。这两步如图所示:

image-20230623151132502

此时实际上victim的两个指针还指向它们,但unsorted binbck指针都不再指向它,因此相当于victim已经被取出了。

现在我们考虑对其进行攻击的情况。

若我们能够控制victimbk指针,并将其指向一个fake_chunk(该fake_chunkfd指针是我们希望修改的值。也就是&fake_chunk + 0x10,那么在代码的第一行bck = victim->bk; ,将会出现如图所示的情况:

image-20230623151718915

那么第二行代码unsorted_chunks (av)->bk = bck;,将会将unsorted binbk指针也指向该fake_chunk

第三行代码bck->fd = unsorted_chunks (av);则是攻击的真正实施:它将bck处的fd指针修改为了unsorted bin的地址。也就是实现了这一步:*(&fake_chunk + 0x10) = unsorted_bin

此时如图所示:

image-20230623152236540

至此,已经实现了攻击。


unsortedbin leak及unsortedbin attack利用分析
http://example.com/2023/09/23/system/Heap/unsortedbin_attack/
作者
Ltfall
发布于
2023年9月23日
许可协议