0.说在前面
先声明一下,这题我之前是看wp解出的,但是当时不理解。现在学了一些栈溢出,再反过来看这道题时发现还是挺简单的。下面我把思路以及解法说一下。
1.解法(自己理解后写的,可能和wp有些不一样)
由于我之前解过这道题,所以无法再获取在线环境。因此这里我在本地进行模拟。我创建了一个flag.txt的文件,内容是“You got the flag!”来模拟取得了flag。
下面正式开始。
首先我们先检查一下附件的安全防护,用命令“ checksec <filename> ”即可。如下图:
可以发现这是一个64位的ELF,并且没有开启canary和PIE保护,这意味着这题大概率是个栈溢出的题目。
然后试着运行一下程序,与之交互,发现什么也没返回……如下图:
没关系,没返回才是正常的。(不然解什么题?当它是get_shell啊?)
把它拖入64位的IDA里看看。查看伪C代码,找到主函数,如下:
可以发现有一个条件语句。只要达成条件,就会执行函数sub_400686();点击查看该函数,如下图:
发现该函数的功能就是获取flag。那这就是我们的目标了。
回到主函数,发现在条件语句前有一个 read() 函数。并且它读入了16字节。
再查看一下unk_601068的分布,如下图:
发现它是一个未被初始化且可修改的数据(.bss),只有4个字节。并且它的高地址下一个数据就是刚才条件语句中的变量。(妥妥的栈溢出了。)
由此很容易得出偏移量为4。那么可以构造的一种载荷就是“ b’A’*4+p64(1853186401) ”。(注意,这里不一定要字母A,只要能占4字节就行。)由此可以将dword_60106C 的值改写为1853186401。
思路有了,脚本就好写了。这里给出一种脚本的写法,如下图:
(注意:由于我是在本地模拟的,所以用的是process,如果是远程则用remote。并且recvuntil中的参数只要是输入前的最后几个字符就行了,比如说还可以用”bof”, 但是注意一定不能是随意的字符或字符串,因为我试过…… )
之后运行脚本,如下图:
可以发现返回了“ You got the flag! ”,说明成功了,我们获取了flag。这道题也就解完了。
2.总结
栈溢出类的题核心方法就是通过栈溢出改写数据劫持控制流,把程序的运行引导到我们想要的方向。