pfSense: NAT Traffic through HackTheBox OpenVPN Tunnel

In this post, I show you how you can create a HackTheBox OpenVPN tunnel on a pfSense firewall, using a single connection to NAT specific subnets through the tunnel.

8 months ago   •   12 min read

By 0xBEN
Table of contents

Network Diagram





The Question

I saw someone ask about it in the HackTheBox Discord server and I wanted the challenge. The question was (copied and pasted from the server):

can I have a PFSense vm running with htb vpn then connect my kali vm and other vm to that router vm and access htb network ?

And that got me thinking that it should be quite similar to setting up a site-to-site tunnel. Except in this case, we'd only be configuring a client and have no control of the connection on the other side. So, I dug into the Netgate documentation.

pfSense® software Configuration Recipes — OpenVPN Site-to-Site Configuration Example with SSL/TLS | pfSense Documentation
pfSense® software Configuration Recipes — Routing Internet Traffic Through A Site-To-Site OpenVPN Tunnel | pfSense Documentation





The Solution

Install the OpenVPN Client Import Package

Go to System > Package Manager
Search 'openvpn' and install this package



Note: pfSense CE Users

If you have pfSense installed on a VM or unofficial hardware, then you're almost guaranteed to have installed the pfSense Community Edition (CE) version.

I was talking to @Mickhat from the HackTheBox server, as he is currently trying to duplicate this setup in his own lab environment. And, he brought to my attention that he was unable to find the openvpn-client-import package in his package manager.

ℹ️
Doing some research, I found that this pacakge is only available to pfSense Plus users. But, the good news is that migrating to pfSense Plus is free for pfSense CE users.
Netgate now offers the ability to migrate from the Community Edition (CE) of pfSense® software to pfSense Plus software.

This enables users with virtual machines or hardware not sold by Netgate to utilize the advantages of pfSense Plus software.

Information on how to migrate from pfSense CE to pfSense Plus can be found here. Again, it's $0.00 for the software. You only pay when you need support.

Installing and Upgrading — Migrate from pfSense® CE software to Netgate pfSense Plus software | pfSense Documentation





Download Your HTB VPN File

Log into your HackTheBox account and click this icon
For this demonstration, I'll be using the Machines lab
Choose 'OpenVPN'
Choose your access level, server, and protocol (TCP or UDP) and download
You should now have a .ovpn file downloaded to your system





Import the VPN Configuration

Go to VPN > OpenVPN
Client Import
Choose File and choose the .ovpn file you just downloaded
Fill out the form like so (you can use any name you like) and click 'Import'
You should now see your tunnel created
Go to Status > OpenVPN
If all went well, you should see a successful connection
⚠️
Click the button to restart the VPN connection, because upon first connection, there seems to be some issues creating the IPv4 routes.





Create the Gateway

Go to Interfaces > Assignments
You should see a new interface
Click 'Add'
Click your interface name (eg. 'OPT12')
Configure as such and click 'Save' and 'Apply Changes'





Add NAT Processing Rules

pfSense creates some NAT rules automatically when first setup to NAT traffic through the Default WAN gateway. However, now that we have a VPN tunnel acting as a gateway, we need configure pfSense to route only certain traffic out the VPN.

Make a Note of the IPv4 Routes

Go to Diagnostics > Routes

Filter the routing table to the 'ovpnc1' connection

There are three routes we need to note here:

  • 10.10.10.0/23
  • 10.10.14.0/23
  • 10.129.0.0/16





Create Outbound NAT Rules

ℹ️
There is no way to reference aliases or multiple networks in the outbound NAT rules. We are going to create outbound NAT rules for each route mentioned above.

For example, if you wanted to NAT two networks through the tunnel:

  • 10.6.6.0/24
  • And, 172.16.1.0/24

There are three routes mentioned above, so you'd need a total of six NAT rules; three for each source network.

Go to Firewall > NAT
Click 'Outbound'
Set the mode to 'Hybrid' and click 'Save' and 'Apply Changes'
ℹ️
Using Hybrid mode will work best, as it will maintain the default NAT rules while allowing you to add your own.

Click the 'Add' (up) button
ℹ️
I am using 10.6.6.0/24 as my source network here, as this is the subnet where I keep most of my security infrastucture; including my Kali VM.

Fill out according to your network conditions and click 'Save'
Click the 'Copy' button
Fill out according to your network conditions and click 'Save'
Click the 'Copy' button again
Fill out according to your network conditions and click 'Save' and 'Apply Changes'





Add Policy Based Routing Rules to Firewall

Create some Firewall Aliases for Easy Reference

Go to Firewall > Aliases
Click 'Add'
Create an alias for destination networks and click 'Save'
Add another alias
Add an alias for any hosts allowed to enter the tunnel and click 'Save' and 'Apply Changes'





Create a Floating Firewall Rule

Go to Firewall > Rules
Click 'Floating'
ℹ️
The reason we're adding the rule to the Floating section is because the host(s) added to the ALLOWED_TO_HTB_MACHINE_LAB alias could span multiple subnets. It's just a good catch-all for any future changes.
Click 'Add'
Set 'Quick' to enabled
Traffic is going 'in' to the gateway and is IPv4 traffic
Choose any interfaces where your hosts in "ALLOWED_TO_HTB_MACHINE_LAB" reside
Click 'Display Advanced'
Set the gateway and click 'Save' and 'Apply Changes'





Ping Test

Got the 'Squashed' machine running
Showing the IP address on VLAN 666
No tunnels running
Good ping test





Key Differences with a Point-to-Site VPN

Since the connections to the HackTheBox targets are going out over NAT, be ready to troubleshoot issues with connectivity. I am going to detail some issues I had with the NAT connection as well as the more intricate way of receiving reverse shell connections (bind shells are not affected).

Example Issue 1: NFS

Continuing with the reference to the Squashed target in the HTB machine labs, I ran into some issues when I was doing quality-of-life testing with this Site-to-Site VPN setup.

When mapping a NFS share through NAT, our traffic is going to flow like this:

[Kali VM] ======> [pfSense] ==[tunnel]==> [10.10.11.191]
NFS client                NAT                  NFS Server
10.6.6.6:54789         10.10.x.x:64588         10.10.11.191:2049

The problem here is that because of the NAT connection, pfSense is going to forward our NFS client's traffic over a high port and the NFS server is going to reject this. This is because the NFS server is expecting a client connection from a reserved port.

Therefore, we need to configure another NAT rule for NFS connections, so that pfSense will forward them over low port numbers.



Configuring the NAT Rule for NFS

Go to Firewall > NAT > Outbound
Click 'Add'
This is for IPv4 TCP connections going out the HTB VPN interface

You can't use aliases here, so you'll have to configure for each network. Since the Squashed target is on the 10.10.10.0/24 network, I'm only going to add the NAT outbound rule for this network. Always start small when troubleshooting and expand scope as needed.

Use the Interface Address and only NAT out TCP ports 1-1024
Click 'Save' and 'Apply Changes'





Example Issue 2: Catching Reverse Shells

Continuing with the Squashed target, I am not going to over how to get the initial foothold, but I'll show you how to catch your reverse shell in the event you try this target.

Get Your VPN Address

Go to Status > OpenVPN
Make a note of your VPN address



Create Your Reverse Shell

I am using this PHP reverse shell for a quick and easy test.

php-reverse-shell/php-reverse-shell.php at master · pentestmonkey/php-reverse-shell
Contribute to pentestmonkey/php-reverse-shell development by creating an account on GitHub.

Change your variables for your listener:

$ip = '10.10.?.?';  // CHANGE THIS
$port = 8443;       // CHANGE THIS
I am going to have my listener on TCP/8443

Save your reverse shell payload in the writable directory.



Create a Port Forward in pfSense

Go to Firewall > NAT
Click 'Port Forward'
Click 'Add'
Click 'Show Advanced' and set the source IP to your target's IP address
You don't need a 'To port' if it's only one port
Your attack VM's IP address
Click 'Save' and 'Apply Changes'

So effectively, any connections from 10.10.11.191 to your-vpn-address on TCP port 8443 will be forwarded internally to your attack VM listening on TCP 8443.

Success!





Updating the VPN Client Config

Let's say for example your HackTheBox subscription changes or you need to regenerate your VPN configuration. This will cause your existing OpenVPN tunnel to break. The bright side is that you don't need to tear down start from scratch, but you will need to update some certificates.

HTB .ovpn Structure

client
opevpn-option1
opevpn-option2
opevpn-option3
opevpn-option4
<ca>
-----BEGIN CERTIFICATE-----
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
    Data: blahblahblahblahblahblahblah
    More data: blahblahblahblahblah
    
-----BEGIN CERTIFICATE-----
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
-----END PRIVATE KEY-----
</key>
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
-----END OpenVPN Static key V1-----
</tls-auth>

So, we have the following sections:

  • client
    • client options
  • <ca></ca>
  • <cert></cert>
  • <key></key>
  • <tls-auth></tls-auth>





Importing the New Data

Editing the CA Data

Go to System > Cert. Manager

Copy everything between the <ca></ca> tags and paste it into here:

Click 'Save' and 'Apply Changes'





Editing Certificate Data

Click on 'Certificates'
Edit your certificate entry

Copy everything between the <cert></cert> tags and paste it here:

Copy everything between the <key></key> tags and paste it here:

Click 'save' and 'apply changes'.





Updating the Client Config

Go to VPN > OpenVPN
Click 'Clients'
Edit your VPN client
ℹ️
Copy the server name next to the remote client option. For example if the option is remote server-name.hackthebox.eu 1337, you should copy server-name.hackthebox.eu and paste it here:

If the port changes from 1337 to another port, update it here:

Copy everything between the <tls-auth></tls-auth> tags and paste it here:

Click 'Save' and 'Apply Changes'





Test Your New Config

Go to Status > OpenVPN
Click the button to restart your connection





Conclusion

I don't know if I'd use this as my regular means of connecting to the HackTheBox labs. It feels over-engineered and a lot more cumbersome to complete simple tasks, but I can see how this might have its benefits in situations where you are using something like a team server for C2 activities.

This was a great learning experience for me and a very rewarding challenge to explore and overcome. If you've read up to this point, I want to thank you for reading. Have fun out there!

Spread the word

Keep reading