BUUCTF-easyheap
题目简介
BUUCTF一道堆题,链接见:BUUCTF:EasyHeap
主要通过这道题进一步了解覆写GOT表这种之前没怎么接触过的利用手法
漏洞点分析
首先checksec,发现除了PIE全部开启,如图:
之后进入IDA,发现是个菜单程序,同时存在malloc和free,是个堆题,如图:
之后寻找溢出点,首先看到create功能:
然后对比观察edit功能,如图:
发现在edit的时候又询问了一次堆块长度,因此这里存在溢出
最后再看一下delete,free后会置空,没有UAF:
漏洞点利用
找到了溢出漏洞点,首先想办法拿任意地址写
思路为:申请超过1个的堆块,free掉后面几个,然后溢出第一个堆块去改后面堆块的fd指针,然后再malloc
但是这里需要注意fast bin的检查机制,主要如下所示:
1 | |
可以看到,fast bin在申请时,会检查 size字段是否属于当前bin规定的大小 ,因此我们需要先办法用一次字节错位去伪造大小;同时,要注意 fast bin的fd指针,应该是指向chunk的头部,而不是数据区的头部
至于如何找错位字节,需要动态调试,如下图所示,想办法在heaparray上方找到了一个0x7f的错位字节:
而且可以看到这里的0x7f是标准输入输出的地址,一般不会改变,因此我们可以malloc到heaparray上方,然后溢出覆盖heaparray实现任意地址写
ok,拿到了任意地址写,但具体该写哪里?
首先注意到main函数里有一个magic变量,位于bss段,如果该变量校验正确会调用一个l33t函数,发现这个函数会执行一个类似cat flag的命令,如图:
于是考虑覆盖bss段的magic去通过检查,但是经过打远程发现,这个路径是错误的,没有flag,看来这是一个假的后门函数
接下来考虑直接拿shell,这里注意checksec中的结果为Partial RELRO,考虑覆盖GOT表
至于覆盖哪个函数,由于能输入控制的地方是heaparray数组,而恰好free函数以该处指针作为第一个参数
因此首先在0x6020ad错位字节malloc一个chunk,然后覆盖heaparray第一次任意地址写free函数的GOT表;
第二次任意地址将heaparray+1的地方填入/bin/sh
最后再free掉1号堆块
最终的exp如下:
1 | |