2021长城杯PWN
前言
这次一共三题pwn,两题其实都是比较常见的堆题,可惜只做出了一题,还有一题堆上的orw在比赛前没能出 。不过总的来说:比之前还是进步了很多,加油
K1ng_in_h3Ap_I
毫无疑问的64位,保护全开
程序一共有着三个功能以及一个好心送我们的三字节libc地址
输入666会打印出后三字节地址
申请堆块没有特殊的,只是不能申请大于0xF0的堆块
写入功能存在着offbyone,还要注意的就是交互要输入’\n’才能结束,否则就要输入完所有长度数据
释放功能存在UAF
所以我的思路是借着offbyone生成unsorted chunk,得到libc地址,然后再将他分为一块大小为为0x70的fast chunk,借用UAF对着libc后三位进行覆盖,覆盖成stdout的地址,将堆块分配到stdout上,吐出libc地址。然后故技重施,再分配到__malloc_hook上,但是还要借用relloc调整一下才行
看了别人的wp,对于第一次把chunk分配到stdout还有别的思路:先释放一块unsorted chunk,然后申请回来0x70大小的fast chunk,此时这块chunk上也是会残留着libc地址(正常的malloc是不会清零的),然后释放两个fast chunk进入bin链,将后进的那块,借用UAF把fd指针修改成指向有着libc地址的那个chunk,这时也能将堆块申请到stdout上
1 |
|
K1ng_in_h3Ap_II
来源:https://blog.csdn.net/eeeeeight/article/details/120386415
常规checksec,64位保护全开。在程序上跟上题是差不多的,少了666的地址泄露以及offbyone漏洞,但是多了打印功能,以及libc版本提升至2.27,至于2.27,就是标志性的tcache bin
然后申请的size只能是在0x10~0x60
UAF依然存在
多了一层沙箱,看到这个基本都是orw的思路:借用setcontext + 53上的gadgets,调用mprotect使得堆可执行,然后执行布置在堆上的rop链,读取flag
申请0x50的堆块是因为链上没有0x60的空闲堆块,所以申请出来的堆块是在最底下的(与top chunk相近的)并且两块是连续的,好算偏移
然后先后释放,借用UAF泄露出堆上地址,进而计算tcache地址
然后把我们之后要申请用到的堆块的count数量改为2,以及把unsorted chunk的count全部一次性改为7,为后续释放unsorted chunk进入bin链泄露libc基址做工作
1 |
|
修改之前释放堆块的fd指针指向0x20堆块,而前面也修改了0x60堆块的count数量为2,所以可以申请,造成overlap,之后修改0x20堆块的size,申请0x30的堆块,(原因是这个大小的堆块是不存在空闲的堆块,所以可以全部相邻在一起,方便操作)。把底下的堆块都包含在内,记得要留一个防止与top chunk进行合并
然后释放得到libc地址
1 |
|
往free_hook里面写入setcontext+53的地址
然后根据setcontext+53
上的寄存器布置环境:而rdi的值是我们等下要释放的堆块的地址,根据这个计算出偏移,在对应的地址为rdi,rsi,rdx设置参数,然后设置rcx的值为mprotect的地址,去执行mprotect,再跳转回来执行shellcode读取flag
成功读取flag!
1 |
|
完整exp:
1 |
|
easy_vm
以后学到了,再回来复现(可能是近期 吧,近期决定爆肝学习,希望能)
- 本文作者:ShouCheng
- 本文链接:http://shoucheng3.github.io/2021/09/21/2021-09-21-2021%E9%95%BF%E5%9F%8E%E6%9D%AFPWN/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!