B站PWN教程笔记-12
完结撒花。
今天还是以做题为主。
fmtstr+uaf
格式化字符串+USER AFTER FREE
首先补充一个背景知识,指针也是有数据类型的,不同数据类型的指针+xx,所加的字节数也不一样,其实是指针指的项目的下一项。如int a[20],a是指针,a+1就是往后4字节。
根据这个地址的思想,可以把func(args)等效为==(0xaaaa)(args)
------------------------------------------
首先checksec,看到了有可读可写可执行的地方,先留个心眼。
开始做题。做题可以自己摆弄摆弄程序,或者输入一些自己觉得可能会出漏洞的地方,说不准就会出现问题,这里就是发生了double free。虽然还不太理解,但感觉不太正常。
漏洞出现在这里,还没有确认退出就已经free了chunk o。如果我们输入n,程序会重新来一次,但是o对应的指针已经指向了free chunk,在UAF这个选项,有一个malloc,恰好满足UAF漏洞,这个o是写入函数地址的chunk,我们可以实现任意函数执行了,或者其他操作(因为这里没看到明显的后门函数)
这里要注意这个o指向的位置,其实还是那个chunk,不要弄混淆。
大概思路就清晰了。首先这个题没有栈溢出,我们考虑用堆。先通过UAF,搞一个shellcode到栈上。然后想办法执行它。
难题出现,UAF能写入的最多是24字节,但是pwntool生成的肯定不止。所以我们可以在之前的shellcode database里面搞一个shellcode出来。难题解决。
接下来是泄露栈的地址,如下,我们只需要知道了prev rbp的内容即可知道v7-v9地址。这样就可以把shellcode注入到指定位置。
小技巧:可以在特定位置搞一个标记字符,如下所示,在recv和send会更加方便。
这个标记字符还有一种情况,就是格式化字符不足一个字长,他就可以起到补满一个字长。不然全乱了,因为它找参数是step为一个字长来找。
下面就是UAF示意图。
变为
最后不要忘记程序执行是在1,2,3选项分别执行不同对应的o里面的代码,还要发送一个让shellcode被执行才可以!
hacknote(经典UAF)
堆题经典模板:可以创建堆,可以释放,可以查看堆列表。
而且,好消息是,因为题目模板化,exp同样也是模板化,一会便知。
···········································································
先来看看add函数。首先映入眼帘的就是它设置了一个限制。最多只能存在5个note,然后搞了个指针数组,来存储note的地址。
看一下添加的逻辑:很简单其实。
就是add的时候,遍历这个象征着note的ptr数组,如果是空的,就malloc一个。但是这个malloc的是8,如下所示:会出来两个实际上。
所以最终的结构实际上如下所示,每个数组指向了第一个chunk,而后第二个chunk还有一个大小看自己的chunk。
上面的chunk可是同样有函数地址的,需要注意。
还是一样的漏洞,看free,没有free指针:
其实可以觉得是UAF了
然后开始做题。这里要用函数的思想,每一次进入子函数,都是那些代码,输入什么,输出什么,而我们要不断调用子函数,因此可以用函数在脚本里面封装下:
我们可以先new两次。上面的chunk类似于控制信息,下面的就是(垃圾)数据。
我们再free。这样的话上面的chunk进入一个bin(估计是fast bin),下面的进入一个bin。
这里就已经初具雏形了,UAF。弄完后是下面这样
我们再执行add。会重新malloc。看这个,我们malloc一个8size。fast bin是类似于栈,后进先出。首先2申请一个控制chunk,就是1原来所对应的。再申请一个8size的chunk,就是0所对应的控制chunk。
这里不要忘记UAF的关键,就是没有free原来的指针,导致那个指针和新malloc的指针指向同一个地方,可以篡改老指针指的地方,借用老指针做一些坏事。
在这里面,0认为的控制信息,就是2认为的数据区域
这里题目还给一个so文件,肯定是需要泄露地址。
所以先用2,给0的控制块第二个(相当于参数)写入puts的got表地址。这是泄露这一步要干的事情。
我们用程序显示chunk内容的那个子函数,来搞泄露。
泄露完之后,再填充为:
即可。
注意,这里参数是||sh,为啥有个杠杠?因为程序设计问题。程序设计的system参数实际上是*0,也就是这一段。实际的执行语句见下面:
第一个是system的真实地址,肯定会执行失败。||这个特殊的符号(意思是或),会在第一个执行失败,执行第二个sh。那为什么泄漏的时候,不用考虑这个。因为泄露的时候的puts,是出题人写的my_puts,不是plt表的puts。已经考虑这里的情况了。
这还只是初级堆利用,以一张完整的本题利用图作为收尾吧!愿顶峰相见!