-
-
[原创] pwnable.kr 中 栈溢出问题 simple login 的writeup
-
2019-3-5 23:18 7081
-
Download : http://pwnable.kr/bin/login
Running at : nc pwnable.kr 9003
首先将文件下载下来,拖入IDA,按F5得到伪码。
来到第14行,这里表示会对我们的输入进行一次base64的解密,返回解密后字符串的长度赋值给v6.
最后一步关键操作就是第22行的auth验证函数。
在这里它会生成哈希值,即使每次我们的输入完全一样它也会生成不同的哈希值,所以只能想办法来绕过它。
看一下auth函数的反汇编代码:
这里var_14= byte ptr -14h,eax就是v4,它距离ebp的距离为0x14-0xC = 0x8,但是我们input的最大长度为0xC,比v4大了4字节,所以我们的input可以在memcpy的时候将ebp覆盖。
接下来就是分析思考的时候了。
在执行call指令的时候,类似于执行了push eip,jmp xxxxxxxx,而这里ret类似于pop eip。
在执行call memcpy的时候,假设执行auth函数的时候esp的值为0x0010038,此刻的栈类似这样:
如果我们input输入了0xC个字符的话,假设我们输入0xC个a,执行完memcpy以后栈的情况就变成了:
当auth函数执行到最后的时候,是这样:
会执行一个leave和一个retn。
我们知道,leave的作用类似于mov esp,ebp ,pop ebp ,retn的作用相当于pop eip。
因此,当指令执行到完leave的时候,栈以及相关寄存器的情况是这样:
然后执行retn:
此时程序就会接着执行接下来的代码:
由于与指定哈希值不匹配,因此程序最终会运行到0x084941F这里,发现这里还有leave和retn,于是再进行一波分析。
首先执行完leave:
然后执行完retn:
这时灵感就出来了。我们可以构造输入,结构类似于这样:aaaa+(correct_addr)+ebp_addr,让第一次leave的时候ebp变为input的地址,这样到最后EIP就会编程我们所设置的correct_addr了!对了,最后不要忘了再进行一次base64的加密。
correct函数中也有一个过滤,所以我们的correct_addr要写jnz指令之后的地址才能执行system("/bin/sh")。
这是input所在的地址:
所以最终代码如下:
from pwn import* io=process('./login') io.recvuntil("Authenticate : ") payload="" payload+="aaaa"+p32(0x0804927F)+p32(0x0811EB40) payload=payload.encode("base64") io.sendline(payload) io.interactive()
新人第一次发帖,如有不对的地方劳烦指出,谢谢!
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
赞赏
他的文章
看原图