pwnable.kr —— flag
送分题
下载文件,查看一下,是ELF文件并且有UPX壳。这个壳只是个压缩壳,不是难事,脱壳。之后用IDA打开看一下,加载完之后主函数就是整个逻辑,malloc()一个空间,然后使用strcpy复制。数据的来源也很清晰,来自CS段的flag变量。直接进入到cs:flag的位置复制出来目标字符串提交即可。
pwnable.kr —— passcode
题目主要的逻辑函数是main()、welcome()和login()。后面两个函数是在main()中连续调用的,这导致它们拥有相同的栈底。具体可以连接之后看源代码,或者下载到本地调试。welcome()是一个字符输入,由变量name接收。login()主要是scanf(“%d”, passcode1);和scanf(“%d”, passcode2);两个输入,之后进行比较:if(passcode1==338150 && passcode2==13371337),最后执行system()读取flag。
没有加&,没有办法把338150和13371337直接输入进去,直接输入符合条件的数字会失败,readelf -r ./passcode
。
没法直接覆盖写passcode2。
scanf("%d", passcode1);
中passcode1没有加取地址符号&,如果scanf没加&的话,程序会默认从栈中读取4个字节的数据当做scanf函数中取回的地址,并在操作之后写到这个地址中。
在scanf之后下一个要执行的函数是fflush函数,并且两者都在GOT表中,这就可以使用GOT覆写技术。
scanf("%d", passcode1);
fflush(stdin);
首先,GOT表段是可写的
。基于同一个函数的连续调用有相同栈底
的条件,计算passcode1和name的距离:0x60。
用一个GOT表中的函数地址来充当scanf取的地址,然后把system(“/bin/cat flag”)这条指令的地址
通过scanf写到这个函数中,当这个函数被调用时,跳到system(“/bin/cat flag”)。这里就用fflush()作为scanf()写入的地址,当程序调用fflush()的时候就会执行system()。
scanf(“%d”,&fflush())接受的参数格式是十进制%d,所以在传递参数时把system("/bin/cat flag")的地址
转换成十进制134514147
写进去。
python -c "print 'A'*96+'\x00\xa0\x04\x08'+'134514147\n'" | ./passcode
enter you name : Welcome AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!
Sorry mom.. I got confused about scanf usage :(
enter passcode1 : Now I can safely trust you that you have credential :)