Nebula level02 – exploit exercises walkthrough

nebula - exploit exercises

Nebula is the first VM of and I highly recommend it to those who want to challenge themselves to discover vulnerabilities, practice privilege escalation, exploit development, debugging, reverse engineering and other cyber security issues.

It consists of 20 different levels. Let’s take a look at level 02.

Click Here
To Download It!

Nebula – level 02

nebula level02nebula level02 source code

The first thing you need to do is downloading the VM, run it and log in using user: level02 and password level02 if you didn’t do it yet.

Let’s start by analysing the source code of the vulnerable application. We already saw gid, uid and the functions setresgid() and setresuid() in level01, check that in case you don’t remember.

Then we can see the functions asprintf() and printf(). Both are used for printing a message on the screen. Isn’t that a harmless thing? Why is the program vulnerable then?


Some functions are more dangerous than others and may lead to buffer overflow, so you need to be careful when you use them or even better avoid them if possible. See an article I wrote about that here.

Anyway asprintf() seems a function even recommended for security reasons. If you use sprintf() and vsprintf() you need to allocate a buffer that is big enough to contain the input, otherwise you’ll overflow the buffer. asprintf() is smarter, because it calculates the size of the input and allocates the buffer by itself, so it’s safer. Anyway after the buffer was used, you should release it in order to avoid memory leak. asprintf() is an implicit malloc() so you have to check the value it returns:

Getenv() is a function for getting the value of an environment variable.

System() is used to execute a command as we saw also in level01.

Hmm what’s wrong then?

The information I gave you should be enough for solving the challenge. I recommend you to try by yourself first and if you don’t find the way to solve it soon don’t worry. Chances are it is the first challenge you do, so that’s alright. Try harder! If you really got stuck and you want to see the solution, check the paragraph below.

Solution – Walkthrough

Hmm first let’s locate the flag02 program and run it so check its behaviour.

check program flag02

The program prints 2 strings when executed. We can see the text in the source code. “level02” isn’t hardcoded in the source code so it must come from somewhere else.

It seems that the string we are looking for is stored in the environment variable USER and is retrieved by the function getenv().

This is an hypothesis, let’s verify it.

If we type env we can see ALL the environment variables, USER included.

check env variables

Even better, we could use the printenv() function that accepts the environment variable name as argument and prints directly its value.

check user variable

It is also possible to SET the value of an environment variable. I can see the grin on your face.

Try to insert what you want, a simple string, like this:


to run the program and observe the output.

You’ll notice that the value of the USER variable is embedded directly into the string printed by the program. Input validation/sanitisation is an utopia.

Now that you learnt the trick, you can try something more evil, like passing some commands. If it works (and it does) you just discovered a command injection vulnerability which is pretty serious.

Even if you write a command name, it will be treated as a string, because remember that the value of USER is an argument passed to the echo command. 🙁

Wait, you said you could inject commands, I believed you and now I’m sad. 🙁

Don’t be sad, you can actually do it, trust me when I tell you something 🙂 .

In order to succeed, you need to break (terminate) the echo command before passing another command, you can simply use a semi-colon ; .

I injected various payloads, I wanted to have fun 🙂 See the image below and then we’ll comment it together.

getflag and pwn

I wanted to exploit the fact that the echo command is called, for printing “Fabio Baroni is cool”. Yup that’s me, cooler than “level02” 😀

Then I used ; as separator for issuing another command. Then I decided to get the flag here (getflag). That was enough for winning the challenge, but if a shell is free why not to get one?

Then I inserted another ; followed by /bin/bash .

If you observe the source code you can see that also another string is printed. That string ends with “is cool”. Then I provide some words before that.

Yep, I think “also getting a shell is cool” 😉 .

So to recap, we displayed a string saying how cool I am, got the flag, opened an elevated shell (see the user is flag02 instead of level02), then after we exit the shell it prints “also getting a shell is cool”.

We managed to force the program to do what we wanted even if it wasn’t intended by the carelesss developer. I think that’s awesome.

I hope you enjoyed it and had fun.

See you at the next challenge 🙂


Did you enjoy this article?
Signup today and receive free updates straight in your inbox. We will never share or sell your email address.

Author: Fabio Baroni   Date: 2016-10-02 23:38:12

Related posts:

Leave a Reply

Your email address will not be published. Required fields are marked *