-
-
[原创][分享]Pwn从入门到放弃(五)
-
发表于:
2020-1-19 15:11
11921
-
题目为HCTF2016的一道PWN题,名为fheap,题目下载:
fheap
也可以直接使用c源代码自行编译生成:
话不多说,开始尝试解题:
程序为64位小端,除了stack canary外,保护全开,似乎有些棘手啊。
是一个典型的Create、Delete菜单类题目:
第三步,将程序丢到IDA中看一下:
通过F5,可以在create函数中查看到,当create时,程序会先申请0x20字节的堆块存储空间,如果输入的字符串长度小于0xf,则直接存储于0x20字节的前16个字节处,如果输入的字符串长度大于0xf,则申请相对应长度的空间存储字符串。
而在delete函数中,可以看到,由于程序只是未将指针置空,因此存在Double Free漏洞:
Double Free内存布局:
知识点1-Fastbin:Fast bins用于提高小内存的分配效率,不大于max_fast的chunk被释放后,首先会被缓存到Fast bins中。当分配的chunk小于或等于max_fast时,首先会在fast bins中查找相应的空闲块,用于加速分配。(在32bit的系统中,max_fast的值为64;在64bit的系统中,max_fast的值为128)。
因此只要我们能够将新申请块中的Free函数指针修改为我们想要的函数地址,就可以达到劫持的目的,但是这里有个难点,因为程序开启了PIE保护,导致内存地址随机化的问题。虽然地址随机变化,但由于内存页的载入机制,PIE的随机化只能对单个内存页进行随机化,因此它的低12bit并不会改变,正是因为如此,为我们绕过PIE提供了帮助,具体的方法是将free函数指针的最低位修应该为我们想要改变的函数指针(比如puts),从而去泄露我们想要的函数地址,通过计算偏移可以得到程序的加载基址等信息。
动态调试一下看看,下面是申请了两次小于0xf的堆结构:
释放后重新申请大于0xf的堆结构:
可以看到2260的地方指向的是存放字符串的地址,而free指针已被我们修改为了puts的指针。
完整EXP代码:
参考资料:
https://www.anquanke.com/post/id/85281
https://blog.csdn.net/CharlesGodX/article/details/88911417
http://www.rai4over.cn/2019/11/03/Use-After-Free%E6%BC%8F%E6%B4%9E-2016-HCTF-fheap-WriteUp/index.html
https://www.cnblogs.com/shangye/p/6156391.html
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-1-19 15:43
被bugchong编辑
,原因: