Exploit Exercises Nebula Level 18 : Another way to solve it

Stanko Jankovic
4 min readJul 28, 2017

--

I had some fun with solving Nebula level 18 at exploit-exercises.com and after finding several ways to solve it, I looked up some blog posts to see other peoples approaches, and noticed that one of my solutions is different than the solutions of most other people, so I thought I should share it :)

I don’t want to spoil anything, so if you haven’t tried to solve level 18 yet, you can give it a try first before you go ahead and read the rest of this blog post.

The first solution I found was the solution that most blog posts about this level describe: simply max out the file descriptor count to prevent the program from reading the password file, and it will log you in. I will not talk about this solution because it has already been described in detail by many blogs. Just google it up.

There are also two memory corruption bugs (one buffer overflow and one format string bug) which were easy to spot, but hard to exploit because the OS has ASLR activated, and the binary has been compiled with buffer overflow protection flags. I did not even try to exploit these (but will one day).

But one thing that was bugging me was the fact that the user is able to specify the name of the debug file of the binary. That means that I can basically set the password file as the debug file, and write to it. Could I just write some password to the password file and use it to log in?

That is not easy because we are very limited in what we can write to the password file. When the program starts, it will automatically write the following string to the debug/password file (where %d is the debug level that you control by specifying -v arguments):

"Starting up. Verbose level = %d\n"

But we can’t use this string as the password because of the newline character. If you look at the source code of the program, it will replace the first occurrence of a newline character with a null byte, which is just one reason that would make it impossible to enter a newline character as part of your password.

But can we somehow remove the newline character from the password file? The answer is yes: by writing to the passwords file from two instances of the vulnerable binary. This is how it can be done:

  1. First just run the binary with the following parameters:
 /home/flag18/flag18 -d password -v

This will start the binary in debug level 1 and write the following string to the password file:

"Starting up. Verbose level = 1\n"

It is important to note that it will start to write from the first position of the file, and will “remember” how many chars it has written so that if it has to write another string, it can just append it to the already written data.

2. Now suspend the running program with CTRL+Z, and run a new instance by using the following parameters:

/home/flag18/flag18 -d password -vvvvvvvvvv

This will start the binary in debug level 10 and write the following string to the password file:

"Starting up. Verbose level = 10\n"

Since this is a different process and a different file descriptor, it will simply start writing form the first position of the file and overwrite the existing string that the first instance has written. Notice that this string is by one char longer than the string that the first instance wrote (debug level 1 vs debug level 10).

3. What will happen if we suspend the second instance with CTRL+Z, and bring the first instance back with “fg 1”, and make it write something to the debug/password file? It will simply continue to write to the file at the position after the last character of the first string. But because we have changed the string using the second instance of the program, that means that the first instance would now overwrite the newline character!

We just have to find a way to now print a string without a newline character in it (otherwise we would just come back to the initial problem), and that is easily possible with the following command (from inside the first instance of the program):

site exec tttttttttttttttttttttttttttttt

I just added many padding letters in order to be sure to overwrite the newline character of the string the second instance wrote. Now, the content of the password file is:

Starting up. Verbose level = 10tttttttttttttttttttttttttttttt

Now we can simply close both instances, run a new one without any parameters, and use that whole string as the password, because it does not contain a newline character anymore :)

For infosec related stuff, please follow me at Twitter: https://twitter.com/stankoja

--

--