ret2win

Most common challenge

file-archive
3KB

A ret2win technique is exactly what it sounds like, 'return to win'. Meaning we find a way to exploit the system and redirect the return address to our function of choice. This might be win() or something similar like flag() .

In the previous topic, we learned that we could overwrite variables to the value that we desired. Now, we will be overwriting return addresses.

Let us begin :)


1. Theory

Firstly, check the type of file

❯ file ret2win
ret2win: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=516803899a2c7d12ad238bfafa4de3895d8c7adf, for GNU/Linux 3.2.0, not stripped

It is a 32-bit binary file

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

// Win function
void win() {
    char buf[64];  
    FILE *f = fopen("flag.txt", "r");   

    fgets(buf, sizeof(buf), f);     
    fclose(f);

    printf("Ret2win successfull here is your flag: %s\n", buf);   
}


// Vuln function
void vuln() {
    char buffer[20];

    printf("What is your name\n> ");
    scanf("%s", buffer);   
    printf("Hey there, nice to meet ya %s\n", buffer);
}

// Main
int main() {
    vuln();
    return 0;
}

Observing the code above, we can notice that the buffer is set to hold 20 bytes. After that, scanf reads the input to an unknown amount of bytes which could cause a buffer overflow vulnerability.

We can also observe that there is a win() function that we would want to call to print the flag.

This is the flow of our program right now:

Current program flow

But what we want is something like this:

Redirect to win

Okay now that we have understood that, let's get to actually exploit it ourselves


2. Finding offset

The program outputs our name. Let's try inputting more than 20 bytes of input

We encountered a segfault where we are trying to access memory where we are not allowed to. Now, the goal, is to find the right padding (offset) to fill the buffer and reach the instruction pointer (EIP register) which is where the control flow happens. If we control the EIP we can control the direction of the program.

We can manually try to guess the number of 'A's needed to fill the buffer and leak to EIP but it is not efficient. That is why we are going to use a plugin to make our lives easier.

GDB Pluginschevron-right

All of the tools has the same function but different commands. I personally, will be using pwndbg.

We can start by starting gdb with the binary

Next we enter this command as it will generate a sequence of 4-byte string to find the offset within the EIP

Copy the long string and run the program

Paste it in and enter

Notice this part and focus on the EIP

We can see it is filled with the sequence. Now, copy the sequence and use this to find the location of the offset

We have found it. Meaning we need to input 32 bytes of junk and then the address of the win()


3. Finding address of win()

Exit gdb and run it again, but this time use this command to find the available functions and addresses

find win() address

Perfect, now we have all the components we need to launch our exploit


4. Exploit

Similar to the last topic we will be echoing our input, but before that remember it is a 32-bit binary. Which means we need to convert the address into little-endian

Launch the payload

BOOM!, we called the win() function. Congrats if you did it ;)

Last updated