unsorted bin attack
对unsorted bin中的chunk->bk
进行修改,接下来该chunk分配出去时,chunk->bk->fd
就被赋值为unsortedbin头结点地址。
|
|
在glibc2.28中增加了以下检查,使得此攻击失效。
|
|
unsorted bin attack通常为进一步的攻击做准备,比如覆写global_max_fast。
0ctf2016 zerostorage
|
|
关键数据结构
flag:标识该节点是否存在
size:记录大小
content:数据块指针
程序有以下功能
|
|
insert:获取数据块大小,并读入数据。数据块大小在128~4096这个范围内
update:对数据块进行大小内容进行更新
merge:将两节点合并。这里存在漏洞,输入两次相同的id,导致UAF。这个漏洞我没发现,思维还不够猥琐啊
delete:释放数据块,清空节点
总体思路
通过UAF,首先泄露libc基址,然后修改其bk指针,使用unsorted bin attack修改global_max_fast变量;fastbin bin attack覆写__free_hook
为system函数地址。
unsorted bin attack
merge函数中,from的指针将会被释放,to的指针赋值给新的块。而它没有检查from和to是否是一个数据块的情况,导致指针被赋值给新数据块,同时也被释放到unsorted bin中。
当它被释放到unsorted bin中时,fd、bk被填充,view该指针就获得了unsorted bin地址。
使用update函数将global_max_fast-0x10
地址写入到其bk区域,分配一次后就将global_max_fast赋了一个很大的值,接下来只要不超过这个大小的chunk都会被当做fastbin处理。
|
|
fastbin attack
通过以上命令可以看到__free_hook
的低地址方向存在一个0x02,可以通过这个数据构造成chunk->size=0x200
,如下所示。
接下来的工作就是构造一个可以改写chunk->fd的、0x200的伪fastbin。
构造关键点:**realloc函数中,在重新分配的大小大于原来且nextchunk是topchunk时,会直接从topchunk中切割所需大小。**这样就避免了分配的出错。
所以一开始在topchunk分配(0x200-0x10)/2=0xf8
,且接下来不再使用topchunk,unsorted bin attack之后,将它merge,就同时获得了修改该0x200chunk的能力,也被free到0x200的fastbin。
|
|
exp
|
|