babystack
0x01
刚开始这题一点思路都没有,连溢出点都没有找到。后来参考了
http://pzhxbz.cn/?p=91
https://github.com/dr0gba/dr0gba.github.io/blob/master/pwn/babystack.md
这两个文章,后者是在github上搜索到的exp。
其实还是有些摸不到头脑的,这印证了一句话“学而不思则罔,思而不学则殆”,单纯的想是不会有结果的,要结合实践去了解,这里得到的几个教训是:
1.不去动态调试,永远不知道栈上的信息有多丰富
2.strcpy拷贝的字符串要验证长度
3.strncmp(*str,*str,num),num=0时,这个函数返回值是0,即两个字符串相等。
4.x64的参数调用的方式使得漏洞的利用方式需要使用one_gadgets,或者使用ROP。
程序逻辑:
输入 1 :login and logout
输入 2 :使用exit()退出程序
输入 3 :使用strcpy()向main函数的一个数组中copy
0x02 leak
虽然我们可以使用登录时按一个回车键(即发送’\x0a’)来绕过登陆,但是后面的使用发现登录密码还是要知道的。那么怎么获取登陆密码呢,我对这种爆破信息不怎么敏感,所以想不到密码是固定的,然后密码的比对是这样的
也就是说,它密码的比对,长度是由输入来决定的,所以我们可以一个一个字节来爆破密码,这样我们可以获取密码。但是这个密码在栈中的作用就相当于一个canary,除了这个我们还需要获取获取地址信息才可以完成利用。
main函数栈中的变量分布
这里获取libc地址的方法是:利用3拷贝来将copy()函数中的信息拷贝到main()函数栈中,发现copy()函数栈中有一个libc(setvbuf)的地址
|
|
copy()函数是将 char src; // [sp+10h] [bp-80h]@1这个局部变量copy到给定的参数的位置,由于字符串没有做截止处理,所以我们可以copy很多信息到main()函数栈中的v6变量处,我们设置好copy的内容(passcod等),恰好将这个setvbuf的地址信息copy到main函数中的&choise+8这个位置,然后我们又可以通过爆破登录信息来获取这个地址信息。
其实main函数的ret_addr其实也有地址信息,但是我们爆破不了,因为ebp里面的地址是6位字节的,也就是说最后有两位字节是’\x00’,密码比对使用的是strncmp(),也就是说后面的信息被截止了,我们无法获取,就算使用copy()也会引入’\x00’,使得我们想要爆破的地方信息被截止或者覆盖,所以不可行。
0x03 exploit
leak完成后,利用就很简单了,使用one_gadgets覆盖返回地址即可,构造需要copy()的内容即可
payload = padding + passcode + padding + one_gadgets
one_gadgets查找工具:https://github.com/david942j/one_gadget
exp在这里
Spirited Away
0x01
评论超过10即溢出了一位,comment>100,sprintf连接后的字符串溢出两位,comment在栈上可以溢出写到name这个指针上,然后把name指针指向栈中reason中构造的fake_chunk,free后重新malloc,name指针就可以指向栈,并且可写。
0x02 leak
栈中有很多地址信息,而且输入字符串不闭合,这样可以把栈中的地址泄露出来,可以获取栈地址、堆地址和libc地址。
0x03 exploit
这里由于栈底的reason无法溢出写,所以要构造一个fake_chunk,然后free了之后,重新malloc,将name指针指向了reason区域,这样我们就可以溢出写到ret_addr了
这里构造fake_chunk的方法参考how2heap的house_of_sprit。
另外感谢uafio这位前辈,发邮件去问他这题,他告诉了我这个方法~