- Published on
PCC CTF - ROP Reverse Engineering Challenge Writeup
- Authors
- Name
- Muhammad Huzaifa
ROP - Reverse Engineering Challenge Writeup
Challenge Overview
- Category: Reverse Engineering
- Challenge: ROP - reverse
- Description: "You might've thought that this challenge was in the wrong category 😅"
- Format: PCC{}
Files Provided
rop
- 64-bit ELF binaryrop.chain
- Binary file containing encrypted data and ROP chainrun.sh
- Script that runs./rop < rop.chain
Initial Analysis
Binary Analysis
The rop
binary is a 64-bit ELF executable with the following characteristics:
- Stripped binary (no debug symbols)
- Uses standard libc functions:
puts
,gets
,exit
,setvbuf
,memset
- Contains many ROP gadgets for various operations
Key Strings Found
"Did, you, really, ROP???"
"????? gg"
"Nope"
"Did you think you'd get a chance to give input?"
ROP Gadgets Available
The binary contains numerous useful ROP gadgets:
pop rax; ret
(0x4012b7)pop rcx; ret
(0x4012b9)pop rdi; ret
(0x4012bb)pop rsi; ret
(0x4012bd)pop rdx; ret
(0x4012bf)mov rdi, rax; ret
(0x4012c7)mov r10, rax; ret
(0x4012cf)mov cl, [rax]; ret
(0x4012e5) - Load byte from memoryxor rcx, rax; ret
(0x4012e8) - XOR operationcmp rcx, rax; jne ...; ret
(0x4012df) - Comparesyscall; ret
(0x4012ec) - System call- And many more...
ROP Chain Analysis
File Structure
The rop.chain
file (11,080 bytes) contains:
- Encrypted data (first 112 bytes) - This is the flag encrypted with XOR
- Padding (0x70 bytes of zeros)
- ROP chain (remaining bytes) - Contains the decryption logic
ROP Chain Pattern
The ROP chain implements a decryption algorithm with this pattern:
1. Load address pointer (starts at 0x404038)
2. pop rdi; ret
3. Load data address (0x404038)
4. pop rdx; ret
5. Load value 1
6. sub rax, rdx; ret (decrement address)
7. mov r10, rax; ret (save address)
8. pop rcx; ret
9. Load value 0
10. mov rax, r10; ret (restore address)
11. inc rax; ret (increment address)
12. mov r10, rax; ret (save address)
13. mov cl, [rax]; ret (load byte from memory)
14. pop rax; ret
15. Load XOR key
16. xor rcx, rax; ret (XOR with key)
17. pop rax; ret
18. Load value 0
19. cmp rcx, rax; jne ...; ret (check if result is 0)
This pattern repeats for each byte of the encrypted data.
Decryption Process
Extracting XOR Keys
The XOR keys are embedded in the ROP chain after pop rax; ret
instructions that precede xor rcx, rax; ret
gadgets.
Decryption Algorithm
# Extract XOR keys from ROP chain
xor_keys = []
# Parse ROP chain to find XOR key values...
# Decrypt the data
encrypted_data = rop_chain_file[:112] # First 112 bytes
decrypted = bytes([encrypted_data[i] ^ xor_keys[i] for i in range(len(encrypted_data))])
Key Insight
The challenge title "ROP - reverse" and description hint that this isn't about exploiting with ROP, but rather reverse engineering what the ROP chain does. The ROP chain itself is the "program" that decrypts the flag!
Solution
Automated Decryption
import struct
# Read the ROP chain
with open('rop.chain', 'rb') as f:
data = f.read()
# Parse as 64-bit addresses
chain = []
for i in range(0, len(data), 8):
if i + 8 <= len(data):
addr = struct.unpack('<Q', data[i:i+8])[0]
chain.append(addr)
# Extract XOR keys from ROP chain
xor_keys = []
start_idx = 32 # After padding
i = start_idx
while i < len(chain):
addr = chain[i]
# Look for pattern: pop rax; ret followed by XOR key
if addr == 0x4012b7 and i+1 < len(chain):
next_val = chain[i+1]
# Check if next instruction is xor (0x4012e8)
if i+2 < len(chain) and chain[i+2] == 0x4012e8:
xor_keys.append(next_val & 0xFF)
i += 3
continue
i += 1
# Decrypt the data
encrypted = data[:112]
decrypted = bytes([encrypted[i] ^ xor_keys[i] for i in range(len(encrypted))])
print(decrypted.decode())
Flag
PCC{`r3vers31ng_r0p_ch41ns_1s_34s13r_th4n_u_th0ugh7_but_1f_y0u_d1d_7h1s_m4nually_w3lllll_y0u_ar3_1nd33d_4_m4dM4n`}
Key Takeaways
Think Outside the Box: This challenge appears to be about ROP exploitation but is actually about reverse engineering a ROP chain that performs decryption.
ROP as Programming: ROP chains can be used to implement complex algorithms, not just for exploitation.
Pattern Recognition: The ROP chain follows a clear pattern that can be automated for analysis.
Data Hiding: The flag was hidden in plain sight at the beginning of the file, just encrypted with XOR.
Challenge Design: The description "You might've thought that this challenge was in the wrong category" is a hint that this isn't a traditional ROP exploitation challenge.
Tools Used
file
- Identify file typestrings
- Extract readable stringsobjdump
- Disassemble binaryxxd
- View hex dump- Python - Parse and decrypt data
This challenge demonstrates that reverse engineering can involve analyzing any form of code execution, including ROP chains used for purposes other than exploitation.