0.说明
作为学习的堆题,内容涉及堆溢出漏洞、堆块重叠,fastbin attack等。
libc版本是2.23。
1.题解
1-1.ELF分析
主要的函数代码即相应功能如下:
经典的菜单题,漏洞出现在Fill函数,Fill函数在输入堆块大小时是无限制的,这就导致了允许输入的size大于实际申请的size,如此在写入时便会造成堆块溢出现象,可以覆写到下一个堆块。
此外,由Free函数可以看出在free了chunk后相应的指针有清空,因此本题不存在UAF。
1-2.漏洞利用
由于不存在UAF,我们无法直接获取或者改写已释放堆块的信息。但是从刚刚的分析中我们可以知道存在堆溢出漏洞,那么我们可以通过堆溢出来修改已释放堆块的信息,主逻辑如下图:
先申请堆块0、1、2、3(3的作用一是防止2释放后被topchunk吞并,二是为之后的fake_chunk做准备),使得0、1、2等大,且确保释放后能被usortedbin吞并;3的大小等于0x70。释放堆块1,通过0修改1的头部大小,使得1的大小等于原来的两倍。再申请回1,这样堆块1就会和2重叠。需要注意的是申请回1后由于calloc的机制会清空堆块,回导致2的头部信息丧失,因此需要把2的头部信息修改回来。
之后在释放掉2堆块,这样由于1与2重叠,可以通过Dump函数把1的信息打印出来,这样就可以把2的信息也一并打印出来。又由于unsortbin的机制,我们就可以达到泄露libc地址的目的。
再把2申请回来,再申请一个实际大小为0x70的堆块4,释放4,通过3修改4的fd指针为fake_chunk,再申请两个实际大小为0x70的堆块就可以拿到fake_chunk了。
之后的利用参考上一篇博客。
1-3.exp
完整的exp如下:
1 | context.log_level='debug' |