int_overflow(攻防世界新手pwn题)
利用整数溢出
先检查防御机制,开启了NX保护,即堆栈不可执行。
先试着随便输入些字符,发现选择1后共输入2次,而且success了。
用ida查看主函数,既然只能选择1那就查看选择1后执行的函数login()。输入的buf规定长度为0x199u,即409。
继续查看check_passwd()函数。因为v3只有一个字节,可想到当传入的密码长度足够长时可以利用整数溢出的原理,使其统计的长度仍在4~8的范围内,从而绕过 if(v3<=3u || v3>8u),并且实现我们想要的数据覆盖。 同时此处复制到dest的长度为0x14。
在其他函数中找到一个后门函数,地址为0x804868B,猜想在输入的时候把它写到返回函数地址的位置上,直接跳转到该函数中cat flag。
再查看check_passwd()函数的汇编语句看看整个流程有没有什么细节没注意到。如图,将s复制到dest位置之后跳转到 loc_804871D 的位置,执行了“ leave ”指令(相当于执行了mov esp,ebp和pop ebp)。所以在执行到返回地址之前有一次出栈,为防止出栈的数据是我们填充的地址,需要在地址前再传入4个字节的数据。
根据之前的数据可知输入的密码总长度不能大于0x199(即409)。除了复制给dest的0x14个字符,填充的地址(4个字节)和上面提到的需要再填充的4个字节的字符,还有剩下的字符数没确定(需要保证它们的和整数溢出后在4~8的范围内)。用计算器先查看4 ~ 8的二进制数,再手动输入一个最后四位完全相同的二进制数,其十进制值就是输入密码的总长度:
取260作为总长度,写payload:
再运行: