2019西湖论剑杯pwn-noinfoleak
这题在比赛的时候没能做出来,借着这道题学习一下fastbin attack的doublefree和house of spirit
1 | __int64 __fastcall main(__int64 a1, char **a2, char **a3) |
题目逻辑很清楚,就三个功能,添加表,编辑表,删除表,漏洞在删除表
1 | void delete() |
这里可以使用fastbin的double free实现任意地址写,大致原理就是:fastbin是一个后进先出(LIFO)的单向链表,chunk大小包含16-80byte,只有一个fd指针,当我们malloc两个chunk,然后按照第一、第二、第一的顺序free,就会发现两个chunk的fd各自指向对方,这就存在double free。
这时候只要使用house of spirit技术,也就是申请相同大小的栈,并且加上数据fake_chunk_addr,然后接着再连续申请两次,第四次申请的时候就会把fake_chunk_addr作为一个chunk分配给你。
fake_chunk_addr只要满足几个条件,其中一个是fake_chunk_addr的size段要符合fastbin,而且要满足malloc的要求,这一题只需要知道这两点(其它条件我一时搞不明白),这里所谓的double free就是两次free同一个chunk从而能分配到一个fake_chunk,但是不能连续free同一个chunk两个,这会触发警报,而且free的chunk的fd不能指向自身。
这一题我们会发现在index数组(0x6010a0)的上方0x60108d处有一个0x7f,正好符合fastbin的size,我们可以利用double free使得(0x60108d-8)进入index数组,然后通过edit函数对(0x60108d-8)进行写入,然后就能随意地修改index数组,让各个index指向我们想要的地址。
虽然能进行任意写了,但是这题没有能泄露信息的函数,这就需要我们自己构造info leak了,其中一个方法是把已有的函数比如free的got表内容改成puts_plt,这样调用free时就会变成free->free_plt->free_got->puts_plt->puts_got(这里的原理我不清楚),从而调用puts,这时候index数组的地址值原本是在delete函数中作为free的参数的,现在变成了puts的参数,因此我们可以把puts_got的值通过之前的house of spirit放入index数组中,然后更改free_got表,之后调用delete函数就能泄露出puts的实际地址了(got表中存储着函数的真实地址),然后就能计算base_addr,之后得到system_addr,把free_got的内容再修改成system_addr的值,这时候add(0x20,”/bin/sh\00”),那么index数组里面就多出了一个/bin/sh字符串的地址,再调用delete就好了。
exp如下:
1 | from pwn import * |
该脚本来自 https://blog.tangent.ink/
我只做了很小的修改以适应我系统的堆栈,网上找的脚本没有一个能在我kali本地跑的,也不懂得为什么,因为20还有一场比赛,所以对fastbin attack的学习先到这里。
遗留困惑:
1、double free到底能分配什么样的地址?因为我实际很多地址不能用double free,都会直接在heap里给我分配。
2、house of spirit对fake chunk的审查机制具体是怎么样的?为什么0x7f可以满足对size的检查,这里我有查到一篇 https://www.jianshu.com/p/1c4fab29ea34 讲了自己实验的几个size,似乎后四位是f就能满足size的检查了?具体我也不太明白,因为我自己实验的0x60不知道为什么不能满足。
3、got、plt我虽然有经过学习,但是实际具体的函数是怎样的我并没有完全弄清,像这次的连续两次plt got我就不理解是怎么实现的,按理来说got表里应该是实际地址,希望之后阅读《程序员的自我修养》能理解这一点
4、在我看的七八个EXP里,有用到unsortbin、IO_FILE、uaf等技术,因为我实验了好久都难以复现,所以留在困惑里。
评论加载中