> For the complete documentation index, see [llms.txt](https://l0mb4rd.gitbook.io/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://l0mb4rd.gitbook.io/home/ctf-stuff/playgroundsctf-24-writeups/binary-exploitation-pwn.md).

# Binary Exploitation (pwn)

## Pwnterpolations

First step is to check the binary information using `file` and the protections used in compilation using `checksec`&#x20;

<figure><img src="/files/STyuHCj10eQlZk1CX9ON" alt=""><figcaption></figcaption></figure>

Now I've highlighted 3 main parts, these are usually the parts we wanna try to focus on in the `file` output feel free to do some research on what each part means.

<figure><img src="/files/w8vB6zRTG6ulunvirjym" alt=""><figcaption></figcaption></figure>

Nothing interesting here, no canary, no PIE and Partial RELRO, could be anything except shellcode injection since NX is enabled.&#x20;

We're given an ELF binary, after decompiling the binary using ghidra, we find the following code:

<figure><img src="/files/MglCPmg8EUwexSA69Cci" alt=""><figcaption></figcaption></figure>

Analyzing the code, we find that the flag is imported into the binary and stored into a variable, then uses `fgets` to take the user input, and prints that input using `printf`&#x20;

One thing we know is the following:

* This isnt a shellcode injection for the reason stated above
* This isnt a ret2win challenge, since there isn't a stack overflow vulnerability with the usage of fgets and specifying the exact amount of bytes to be taken.

let's see how ChatGPT does with our analysis.

<figure><img src="/files/V6bOBZXn72eZujfCrsaz" alt=""><figcaption></figcaption></figure>

If we ask ChatGPT for further explanation or do some reading on format string vulnerabilities, we'll find that we can leak variables off the stack using such vulnerability.

<figure><img src="/files/3Y6LVJ0UFynTfTg7TmpL" alt=""><figcaption></figcaption></figure>

if we try out the vulnerability, we see that we're leaking addresses off the stack, and we know that the variables in this program are stored on the stack, let's keep leaking until we find something weird.

After leaking a few positions on the stack we find that position 8 is a little interesting.

<figure><img src="/files/UWfFMzdbEOGRmsEx6vUv" alt=""><figcaption></figcaption></figure>

This is too long to be an address (addresses are either 4 bytes for 32-bit systems or 8 bytes for 64-bit systems), then this must be the content of a variable, let's try decoding it using [cyberchef](https://gchq.github.io/CyberChef/)

of course knowing it's running on little endian we have to swap endianess then decode from hex:

<figure><img src="/files/VKeLkKoW3hRzhdOAm03h" alt=""><figcaption></figcaption></figure>

Hmm interesting, this is the start of the flag format...

After leaking the positions that follow 8 (9,10,11) and doing the same we see more of the flag is showing up:

<figure><img src="/files/wAgCqCmIfLAXQ4cVyGpY" alt=""><figcaption></figcaption></figure>

Keep doing this and you'll get your flag :)

Of course this is peasantry...

<div align="left"><figure><img src="/files/X1dWgzsUc3y8GnbV6h2j" alt=""><figcaption></figcaption></figure></div>

Now let's stop with the peasant ways and solve the challenge with a script, here's a script that solves our challenge in a cooler manner:

```python
from pwn import *
from pwnlib.util.packing import *

context.binary = binary = ELF("./chall")
context.log_level = "error"

p = process()

p.recvuntil(b'> ')
for i in range(8,13):
    p.sendline(f'%{i}$p'.encode())
    out = p.recvline().strip().decode()
    out = p64(int(out[2:],16)).decode()
    print(out,end='')

p.close()    

# for i in range(1,40):
# 	p = process()
# 	p.recvuntil(b"> ")
# 	tst = f'%{i}$p'
# 	p.sendline(tst.encode())
# 	out = p.recvline().strip().decode()
# 	p.recvuntil(b"> ")
# 	try:
# 		print(i, (p64(int(out,16))))
# 	except:
# 		continue
# 	p.close()
```
