整数溢出(攻防世界新手pwn题)

int_overflow

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

整数溢出(攻防世界新手pwn题)_第6张图片
根据之前的数据可知输入的密码总长度不能大于0x199(即409)。除了复制给dest的0x14个字符,填充的地址(4个字节)和上面提到的需要再填充的4个字节的字符,还有剩下的字符数没确定(需要保证它们的和整数溢出后在4~8的范围内)。用计算器先查看4 ~ 8的二进制数,再手动输入一个最后四位完全相同的二进制数,其十进制值就是输入密码的总长度:
整数溢出(攻防世界新手pwn题)_第7张图片
取260作为总长度,写payload:
整数溢出(攻防世界新手pwn题)_第8张图片
再运行:
整数溢出(攻防世界新手pwn题)_第9张图片

你可能感兴趣的:(整数溢出(攻防世界新手pwn题))