[Pwnable.kr] passcode

22. 二月 2016 pwnable writeup 0

直接分析可执行文件

@CA)SZZ8[KFC`(([S]$$PVG
main函数里有两个函数,一个是welcome,一个是login。welcome主要做的事是读入了一个名字,名字的存储空间大小是70h-0Ch,也就是100个字符。读取也是用”%100s“读的,所以没法BOF。
}B_23ZTKZN9$W}$X)6P$I)G
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”
080485E3的十进制为134514147,所以构造poc如下:
`P($$015Y){TE4~ZX%S6UBH

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据