[Pwnable.kr] passcode
直接分析可执行文件
![@CA)SZZ8[KFC</code>(([S]$$PVG” width=”751″ height=”554″></div>
<div>main函数里有两个函数,一个是welcome,一个是login。welcome主要做的事是读入了一个名字,名字的存储空间大小是70h-0Ch,也就是100个字符。读取也是用”%100s“读的,所以没法BOF。</div>
<div><img fetchpriority=](file:///C:\Users\Delostik\AppData\Roaming\Tencent\Users\704679462\QQ\WinTemp\RichOle\@CA)SZZ8[KFC<code>(([S]$$PVG.png” alt=””><img decoding=)
login函数主要是读入了两个passcode,分别应该等于528E6h和0CC07C9h。脚本验证一下,Login Failed。
仔细看___isoc99_scanf上面的两个参数,eax里的是格式字符串,edx的是……不应该是ptr [ebp+var_10]么,联想到题目描述,应该是吧scanf(“%d”, &passcode)写成了scanf(“%d”, passcode)。
怎么办?
首先想到用welcome里的name去预先设置两个passcode(释放栈空间时栈内存不会清空)。但是注意到welcome函数段里,ebp-0Ch位置设置了一个“哨兵”,当这个值被修改时会触发___stack_chk_fail,而这个位置恰好是passcode2会被分配的位置。所以这种方法只能修改passcode1,改不了passcode2.
后来了解到另一种方法……scanf崩溃的条件是地址为passcode的内存不可写,只要让它可写就可以了。所以可以修改got@exit, 改成system命令的地址,这样就可以使判断失败时不执行exit(0),而是执行system(‘bin\bash’)了。至于第二个scanf,只要输入非法数据让它跳过就可以了。
用ida查看got表似乎不太准确,所以还是用readelf -r passcode比较准,got@exit地址为0x0804a018,system的地址在ida中
.text:080485E3 mov dword ptr [esp], offset command ; “/bin/cat flag”
.text:080485E3 mov dword ptr [esp], offset command ; “/bin/cat flag”
080485E3的十进制为134514147,所以构造poc如下:
