Pwn的堆题对新手可真是不友好,这一道简单的堆题,困扰了我整整一周,我才将其弄明白。特此编写此做题记录,来记录做题路上的种种坑,以此纪念自己做出的第一道堆题。
再开始之前推荐两个网站,buuctf 和 ctfwiki。
这道题主要就是考察了一个堆溢出的知识点:fastbin attack
还有一个知识点是:当只有一个 small/large chunk 被释放时,small/large chunk 的 fd 和 bk 指向 main_arena 中的地址
所以我们可以利用堆溢出来更改fastbin的大小,将small bin包含进去,再将small bin free 之后再利用程序的dump功能 将 main_arena的地址打印出来。
因为main_arena的偏移固定,并且给了libc文件,因此可以求出libc的基地址,之后就可以利用one_gadget 来 get shell。
首先 申请4个chunk, malloc(0x20),malloc(0x20),malloc(0x100),malloc(0x20),申请的最后一个chunk 是为了防止small chunk 与 top chunk合并。
之后 fill chunk0 修改chunk1 的 Size 为 0x141,这样就包含了整个small chunk。
再 free chun1 之后 申请 0x130的 chunk 这样 fake chunk 就构造成功了.
因为 是使用 calloc 函数来分配chunk 所以需要补齐chunk2的头部,因为执行free的时候会 检查chunk的头部。
补齐chunk2之后就free chunk2 ,这样 small chunk 就变成了了small bin ,再打印 chunk1 获取 [48:48+6]位置的数据,就是main_arena的地址。
如何获取main_arena再libc中的偏移呢?
这个 用IDA查看libc文件中 main_arena的偏移,另外这个我还是有点不理解,看别的wirteup中,main_arena的真正偏移是看了汇编代码加上rsp+56,这个还没理解上去。
之后就是利用fastbin attack (修改fastbin的fd 指针)实现任意地址分配。
将chunk1 free 之后 修改 fill chunk 0 来修改chunk1 的 fd 指针,使其指向__alloc_hook 。
这里还有一个知识点:fastbin的大小必须符合 fastbin的范围,即0x10~0x80。
这里因为 fastbin 没有进行对齐检测 所以可以找到 7f大小的在alloc_hook附近的数据。这里使用gdb 来查找符合条件的数据地址。
找到地址之后 执行两次 malloc ,第二次即可将chunk分配到 alloc_hook附近
这时候就可以 覆盖 __alloc_hook 为 one_gadget 函数。
这样再执行 alloc函数的时候就可以 get shell 了。
【babyheap_0ctf_2017记录】这才是最简单的堆溢出,我就做了1周。。。不过还是又收获的,也算是刚刚入门了。
推荐阅读
- 解护网杯一道web(EasyChallenge)
- ctf|ctf-htctf-misc
- C++|一些关于程序内存布局的问题
- QCTF 2018xman夏令营选拔赛
- 第一届桂林电子科技大学绿盟杯CTF大赛 wp
- Capture the flag
- CTF|BUUOJ [2019红帽杯]easyRE
- Buuctf -web wp汇总(二)
- #|CTF-网络信息安全攻防学习平台(脚本关)
- ctf