经过前三个flag的练习,目前对edb的使用已经算是轻车熟路了。第4个flag还是用老方法寻找突破口——edb调试。
简单分析一下反编译的汇编代码,发现在56556236处调用了levelFour!overflow,突破口应该就在这个过程中,继续调试。
在levelFour!overflow中看到了熟悉的strcpy,还有老方法定位返回地址。
这里可以看到存放输入字符串的地址与待覆盖的地址之间可利用的空间很小,只有28字节,我的shellcode为21字节,貌似空间够大。
先测试一下能否准确覆盖目标地址。
输入28个A和4个B并用edb进行调制,在levelFour!overflow返回之前设置断点,可以看到ffffd2ec处保存的为过程的返回地址5655623b
继续进行调试,可以看到输入字符串从ffffd2d0开始被压入栈中。ffffd2ec的值由于前面的数据越界,其值已经被覆盖为42424242。
依旧利用python脚本,将shellcode加入到payload中进行验证。
在执行后,发现并没有成功获得level4的shell,再次利用edb进行调试并查找问题。在levelFour!overflow返回之前,shellcode已经成功写入,跳转地址也没有问题。
继续单步调试,程序已经成功跳转到shellcode,看来是执行时出现了问题,继续单步调试。
这里连续两次执行了入栈操作,从栈的内容来看,第二次入栈的数据把之前写入的shellcode最后一个字节覆盖了。
本应该执行int 0x80,变成了int 0x2f,这样shellcode就失效了,所以并不能得到shell。
解决方法也比较简单,因为strcpy是把字符串从一个位置复制到另一个位置,所以可以在变量保存的位置去找不会被改写的shellcode就行了,也就是说把payload的跳转地址跳到变量保存的位置而不是复制之后的位置。
在edb中搜索shellcode的前4个字节,找到3个结果,第一个结果就是变量保存的位置。
修改python脚本,重新运行程序。
通过edb调试,可以看到跳转地址正确。
单步调试,成功跳转到shellcode。
运行成功,没有报错。
接下来直接运行levelFour,成功拿到level4的shell。