- Access exclusive content
- Connect with peers
- Share your expertise
- Find support resources
This blog was written by Cyber Elite member @Remo.
Have you ever seen a port-knocking feature on other firewalls or router vendors and were looking for something similar on Palo Alto Networks? Or were you searching for a way to secure and emergency access to a critical server, or even to the firewall interface over the internet—but you don't want to expose this to the complete internet, Actually, you don’t want do expose it at all. If this sounds familiar to you, then this post is for you.
With features included in PAN-OS without any additional subscription, it is possible to secure a critical access. This access is not detectable by any scans—which happen continuously in the internet (for example from shodan.io or actual threat actors)—and at the same time, it's easy to use and enables access from anywhere sans an IP address. Even if you're not looking for this creative solution, this post offers ideas and possibilities when using a Palo Alto firewall (and might lead to even better use cases).
So let’s start. In my example I will secure my global protect access. I don’t want this VPN gateway to be discoverable by anyone. Prior to this idea, I was working with geolocations but even this restriction was not good enough for me (a very paranoid person in some situations). At the beginning, I wrote the keyword port knocking. With this in mind I searched for a way to implement that. In the past, I used the built in actions in log-forwarding profiles (logforwardingprofile) to dynamically add some IPs to special decryption rules where the cert validation was disabled, so I started with this here too.
I created a deny firewallrule with a specific port and my GlobalProtect Gateway IP as Destination IP. On this rule, I configured a logforwardingprofile with a built in action to tag the source IP which is then added to an address group that is allowed to connect to GlobalProtect. So far, pretty easy: I send a TCP-SYN to a specific port and after that I am able to connect withGlobalProtect. Unfortunately this was still not secure enough to me as a port scan of all TCP and UDP ports is done pretty fast and after that also an attacked would be able to reach my GlobalProtect Gateway IP—even though the attacker still has no credentials to access the internal network with a VPN tunnel. So right know the chance for a successful attack is 1:131072 (65536 tcp ports and 65536 TCP ports) or actually pretty much higher as really only a simple port scan is required.
So, I brought this theory to the next level. I wanted to have five stages or doors that need to be opened prior to being able to establish a VPN connection. So with five times 131072 the possibility for a successful attack is lowered to 131072^5 which results in a chance of 1:3.86856262×1025 (1: 38685626227668133590597632). This chance is low enough to me so I went this way with a little adjustment. I wanted to implement a mechanism that there is only one guess for the port which will be knocked on. If this port is not guessed correctly at the first try, the IP will be locked out to make it virtually impossible to brute force this port knocking mechanism.
So I started with creating some tag objects which I will use later:
With these tags I created dynamic address groups for each of these tags:
For every one of these dynamic address groups there is the one matching tag criteria. For example, for the group Gr_Door_1_opened the tag «Door 1» is used as filter and so on:
The next step is to create the required security policy rules to configure this port knocking access. As I wanted five doors to be opened I need only for these five different rules where I specify different ports that need to be knocked on. After each port the next door will be opened.
In these six rules, I specified the different dynamic address groups as source. In addition, the first rule only has to match if the source IP has not already arrived at one of the other doors. So I specified the different groups with the negate option for the source IPs.
These rules so far enable a port knocking feature where a «brute forcing» is still possible as a source IP could scan all the ports multiple times until the actual GlobalProtect ports are opened. There are some more rules required that prevent such scans of the full port range and so after some more rules the full port knocking ruleset looks like shown in the following screenshot:
After each rule where a door can be opened there is another drop-rule that will match for all other ports than the one which is required to access the next door.
The almost important part which enables all this I will describe now. In all these rules a specific logforwardingprofile is added where all this adding to dynamic address groups is configured. In order to add this «intelligence» of tagging the source IPs based on the access to the different doors, the logforwardingprofile needs some rules. I configured a log filter based on the rule name for these rules, so generally the profile looks like this:
As described and as you can see in the above screenshot, the filter is always looking for traffic of one of the security policy rules. The log type in all rules is traffic as I created only drop rules for this port knocking access. While the doors are knocked, the firewall does not answer in any way to the TCP-SYN packets (or UDP packets, but in my example I used only tcp ports so far), which reduces the chances of an unwanted access even more. It looks like there is absolutely nothing available here to an external scan. The actual rules in this logforwardingprofile are configured to add the tags to the source IPs, which results in adding the IPs to the dynamic address groups. With the following screenshots you can see all the details of the rules:
The following screenshot shows the matchlist (logforwardingprofilerule) that filters on access attempts to the Door 1.
Now the rule opening Door 2, there are two built-in actions. One is to open Door 2 for one minute and the other one is to close the door 1 (remove the source IP from the dynamic list of IPs that opened Door 1). With this step I will make sure that there is really only one guess for the port so even connecting again to the port of Door 1 will trigger a lockout.
Built in action to open Door 2 for one minute:
Built in action to close Door 1:
The following two rules that will open Door 3 and 5 are actually exactly the same as the one to open Door 2—simply with adding the IP to a different dynamic addressgroup.
Rule to open Door 3:
Built in action to open Door 3 for one minute:
Built in action to close Door 2:
Rule to open Door 3:
Built in action to open Door 4 for one minute:
Built in action to close Door 3:
The rule that opens the last door is now different in one little point. Instead of opening the door only for one minute (which is the min. value that can be entered) the access to GlobalProtect is granted for the source IP for 24 hours ( which i s1440 minutes).
Grant GlobalProtect access for one day:
Built in action to close Door 4:
After the rules that match connections to the correct ports, I need some more rules which kick in if there are connection attempts to the wrong ports. So these are required to make it virtually impossible to “guess” the right ports or find them with a port scan. The first rule matches for traffic to wrong ports after Door 1 was already opened. In addition to close the Door (remove the source IP from the dynamic address group that opened Door 1 the source IP will also be locked out for one hour.
Built in action to close Door 1:
Built-in action to lock out the source IP for one hour:
The remaining four rules will do the same as the rule before. The rules will remove the tag of the door which the source IP did reach at that point and will lock out this IP for one hour:
Built in action to close Door 2:
Built in action to lock out the source IP for one hour:
Log forwarding profile match list to close Door 3:
Built in action to close Door 3:
Built-in action to lock out the source IP for one hour:
Log-forwarding profile match list to close Door 4:
Built-in action to close Door 4:
Built-in action to lock out the source IP for one hour:
The last rule is actually also the same as the one before to close the doors. Here I just wanted to mention that even if Door 5 is the final one which allowed access to GlobalProtect for one day, this rule will be hit if there is anything else than the ports and applications required for GlobalProtect arrives at the firewall. Even when there is a established GlobalProtect connection, the source IP will be blocked if there is unspecified traffic:
Built in action to close Door 5:
Built-in action to lock out the source IP for one hour:
All this enables this port knocking access. For testing this you can use almost any port scanning app on a smartphone or existing command line tools on Windows, Linux and macOS. In a test where I knock the right ports and the doors are opened the IP-tag log looks like the following (by default there is also an IP column which I hided here):
I used a small PowerShell script, which only does one TCP connection attempt to the destination IP. I used this because on my computer I am able to shortly run this script and after that I can connect to my GlobalProtect gateway. I did not use the basic command test-netconnection in PowerShell as it does multiple connection attempts and it also sends an ICMP ping. These multiple connection attempts and ping are a problem because then the first door is opened—but with the additional connection attempts, I always ended up locking myself out. I also added a short sleep period in the script after connecting to every port because depending on the hardware in use it takes some seconds for this IP address added to the right dynamic address groups. My little script looks like this:
After the step where the «Access granted» tag was added to the source IP, I am able establish the GlobalProtect VPN connection from anywhere in the world without opening only IP in general as source IP. If now someone tries to access my GlobalProtect IP the IP tag log is shown in the following screenshot. In this test the first and also the second doors are opened correctly but then the wrong port is accessed, so the source IP will be locked out for one hour (this log where the tag column is empty I don’t know exactly what this is about, but the important one is that the locked out tag is added and this works correctly):
That's it!
With this guide you should be able to implement such a port-knocking access on your Palo Alto firewall. Obviously, my implementation is not very practical for a company’s GlobalProtect access (unless you distribute a little script or application to your users computers which they have to execute prior to connecting to GlobalProtect). For me, this is working perfectly fine on my personal Palo Alto firewall. This could also be used for emergency access to the firewalls management WebUI or CLI in a secure exposure on the external internet-facing interface. Another use case would be a direct access to an internal jump host for situations when there are issues with your active directory or in the internal network in general. This way you could implement an emergency access (as long as internet access still works). Probably there are plenty of other use cases, so be creative and adapt this proposal as you need it. Of course, the door count could be reduced or increased to match your security requirements.
If you used this inspiration for something similar, it would be great if you share your implementation here in the live community. Also, completely different projects are welcome here so others can benefit from your ideas, change or improve them and share them again so everyone benefits.
Sharing is caring and stay secure,
Remo
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Subject | Likes |
---|---|
1 Like | |
1 Like | |
1 Like | |
1 Like | |
1 Like |