首页
社区
课程
招聘
[原创][分享]Pwn从入门到放弃(五)
发表于: 2020-1-19 15:11 11921

[原创][分享]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编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (2)
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
能帮我写个东西吗?QQ:78763707
2020-4-7 23:30
0
雪    币: 14517
活跃值: (17538)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
3
mark,楼主似乎没有提到libc版本呀,如果是有tcache的话应该怎么解决呢??
2020-4-7 23:54
0
游客
登录 | 注册 方可回帖
返回
//