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.
pfSense: NAT Traffic through HackTheBox OpenVPN Tunnel
In: Computer Networking, HackTheBox, Attack, CTF
Updated: 11/29/2023 — Netgate no longer provides a no-cost upgrade from pfSense CE to pfSense Plus Home+Lab. This article now includes OpenVPN client configuration import steps for pfSense CE and pfSense Plus users.

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

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

pfSense Plus Users

Install the OpenVPN Client Import Package

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



Import the .OVPN Configuration File

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.



NOTE: If you're not a pfSense CE user, you can skip down to the next section.





pfSense CE Users

Unfortunately, Netgate no longer offers the option to upgrade pfSense CE to pfSense Plus Home+Lab. So, I've had to re-write this article to include the .ovpn import instructions for both user sets.

HTB .OVPN File Structure

HackTheBox .OVPN Example

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> 

This file contains the following sections:

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



Create the Certificate Authority

Go to System > Certificates
Authorities
Click '+Add'
Change to 'Import an existing Certificate Authority'
Set a Descriptive Name and choose options accordingly

In the .ovpn file, you'll need EVERYTHING between the <ca> and </ca> tags. Copy and paste this info into the Certificate data textbox.

Paste the certificate data and set options accordingly
Click 'Save'



Add the HackTheBox Labs VPN Certificate

Go to System > Certificates.

Click 'Certificates'
Click '+ Add/Sign'
Change to 'Import an existing certificate'
Enter a descriptive name for the certificate

In the .ovpn file, you'll need EVERYTHING between the <cert> and </cert> tags. Copy and paste this info into the Certificate data textbox.

In the .ovpn file, you'll need EVERYTHING between the <key> and </key> tags. Copy and paste this info into the Private key data textbox.

Click 'Save'



Create the OpenVPN Client

Go to VPN > OpenVPN
Clients
Click '+ Add'
Set the General Info and Mode accordingly

In the next part, you'll need the remote ... and proto options from the .ovpn file. This defines the HackTheBox OpenVPN server's hostname, transport protocol, and port. For example, in my configuration, I have:

  • proto udp
  • remote edge-us-free-3.hackthebox.eu 1337
Leave the User Authentication Settings empty

In the next part, you'll need the following sections from the .ovpn file:

  • data-ciphers ...
  • data-ciphers-fallback ...
  • auth ...
  • key-direction ...
  • tls-cipher ...

You'll also need everything between the <tls-auth> and </tls-auth> tags. This defines the cryptographic algorithms the client will use when communicating with the server, as well as the client authentication key.

In the next part, you'll configure the Tunnel Settings, all of which will remain unchanged.

Intentionally left blank
Intentionally left blank
All set to defaults here as well
Keep default settings
Set the 'tls-cipher' option to prevent OpenSSL errors
⚠️
Click the button to restart the VPN connection, because upon first connection, there seems to be some issues creating the IPv4 routes.





Verify the Client is Connected

Go to Status > OpenVPN and you should see the status of the OpenVPN client.





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

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.
Click 'Save', no need to apply changes yet
Click the 'Copy' button
Click 'Save', no need to apply changes yet
Click the 'Copy' button again
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.

Importing the New Data

For the next few steps, you'll be extracting some information from your .ovpn configuration file. When you've downloaded your fresh copy, open it up and follow along.

Editing the CA Data

Go to System > Cert. Manager

Copy everything between the <ca> and </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> and </cert> tags and paste it here:

Copy everything between the <key> and </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

For the next few steps you'll need the following bits of information from your .ovpn file:

  • proto
    • udp or tcp
  • remote
    • server DNS name
    • server port

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

Copy everything between the <tls-auth> and </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!

More from 0xBEN
Proxmox: GNS3 Lab 2
Proxmox

Proxmox: GNS3 Lab 2

This is the second post in a computer networking mini-series following the University of the Pacific COMP 177 labs, using GNS3 hosted on my Proxmox server.
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.