Vulnerability Assessment for SSH Port Knocking

Christian Goeschel Ndjomouo
8 min readMay 21, 2023

--

Introduction

Security controls are one of the most essential elements that need to be implemented in an IT system in order to protect the three core principles of Information Security which are Confidentiality, Integrity and Availability.

Aside from the importance of their implementation, what is even more important than that is the methodology used for the implementation.

What does that mean ? Well, that basically means that the way how a given security control is implemented, installed or setup determines how effective it will be in securing the Information System and it’s relative data.

For example, the installation of a Next-Gen firewall in an IT network is good security practice and important, but it is not effective and useful in the protection of the network until it has been populated with rules that will do so.

Another example that will be the main focus of this article is a specific security control called Port Knocking that is often used to add another security layer to SSH connections.

Definition

Port Knocking is a security control, more specifically an authentication technique, where a predetermined port knocking sequence, initiated by the client, is used for the authentication before a specific port to a service can be opened.

This methodology is called security through obscurity (STO) which is ancient and kind of primitive. It relies on the secrecy and confidentiality of a vulnerability which in this case would be the port knocking sequence. This is dangerous because if the secret is shared or discovered it will give access to unauthorized individuals.

However, there is nothing wrong with the addition of a STO layer but the emphasis is laid on layer. Security controls should always be stacked on top of each other because an upper layer can always fail and too few layers can render your IT system vulnerable to a magnitude of attacks. The reason for that will be shown shortly.

Analysis

Now, lets come back to the part where I explained that security through obscurity layers are not a bad thing but can be exploited if the vulnerability secret has been leaked.

This is exactly what makes Port Knocking so dangerous because if an upper layer that protects the confidentiality of the port sequence ( vulnerability secret ) fails, a replay attack could be used to gain unauthorized access to a system.

The secret can be disclosed by someone internal, unintentionally or intentionally, or during a man-in-the-middle attack where the bad actor was able to gain access to the network, due to an upper security layer’s failure, and then monitors it’s traffic and then compiles the sequence.

After setting up a server — client environment in my Homelab that consisted of the following:

  • Kali Linux Server (SSH Server)
  • Ubuntu Server (SSH Client)
  • MacOS host (Traffic Monitor / Man in the middle)
  • Cisco Catalyst Switch
  • Wireshark
  • Knockd (Debian Linux — Port Knocking program)

I was able to do exactly that.

I will not explain the setup of the Linux machines, monitoring feature on the Cisco switch or Knockd.

You will just have to assume that I breached the security controls on the Cisco switch of an enterprise and am able to monitor the network traffic.

In this scenario I also know the IP address of my victim server which will help me filter out the traffic in Wireshark to facilitate the compilation of the knocking sequence.

So, here is how I conducted the attack:

Attack Development

First I installed the Knockd program on both the SSH server and SSH client. After that I configured the predetermined knocking sequence on the server which was ( 7000, 8000, 9000 — timeout of 5 secs ) and ( 9000, 8000 7000 — timeout of 5 secs).

Now, in order to understand this sequence I will briefly explain how Knockd works.

Knockd listens on the ports pretermined in the knocking sequence and expects knocks within the set timeout.

Iptables (Linux firewall) has been configured to close the SSH port 22 by default. So, before a client can ssh into the server he will have to initiate a connection attempt by knocking on these 3 ports (7000 8000 9000) in a matter of 5 secs and after successfully doing that Iptables will populate the firewall rules with a rule that allows the clients IP address on port 22. If he fails to do so his IP address will not be added to the firewall allow rule and a SSH connection will not be possible.

Now, when the client has closed the SSH connection he will have to knock the server’s ports in a predetermined sequence again in order to delete his previously added firewall rule to not leave it open unnecessarily. Because an unauthorized access could occur if someone gains access to his machine.

Knockd keeps track of all the knocks and calls the first knock sequence that opens the SSH port openSSH and the knock sequence that is sent after the SSH connection has been closed is called closeSSH.

After every successful knock sequence Knockd handles the population of the Iptables rule list accordingly.

After setting up Knockd, I connected my macOS machine to the Cisco Catalyst switch on which I have previously configured a monitoring feature which will copy all the network traffic from my victims subnet to the Cisco Switchport (interface) that I am connected to.

This gave me the ability to analyze the traffic with Wireshark and compile the knocking sequence.

Once everything was ready I launched Knockd’s feature from the the SSH client (Ubuntu Server) to initiate the openSSH knock sequence, the SSH connection, and the closeSSH knock sequence and captured the traffic with Wireshark.

I filtered out TCP packets that had my victims IP address as destination and the TCP SYN flags value 1 and the ACK flag value 0. Because Knockd uses TCP SYN flag packets for it’s knocks by default.

Now here is what I captured:

I could identify packets that one specific IP address kept sending to my victim (192.168.5.25) over and over again. The IP is my Ubuntu server’s address which is the SSH client that I initiated the openSSH knock sequence with.

The SSH server (victim) has the IP address 192.168.5.36. After a closer look you can see that Port 22 of the SSH Server has also received a few packets.

And lastly you see a few other packets that were sent again, which belong to the closeSSH knock sequence.

Now someone who knows how Knockd works and was able to compile the knock sequence from this capture could care less about the knocks after the SSH connection because that only serves as a security measure in case someone gains unauthorized access to ones machine.

Now in order to determine the knock sequence you need to look at the destination ports of all packets that arrived before the one that were send to port 22.

The first packet arrived was sent to destination port 7000, the second to 8000 and the third to 9000.

You may think that this is enough but there is one more thing missing, the timeout. This will determine with what interval we will send out the packets/knocks.

Wireshark has a vast option of packet analysis tools of which one we will make use. The I/O Graph shows how fast the packets were sent. And you can choose which packet stream to inspect. The graph down below shows that each knock sequence took approximately 1 second which means that we will have to set our knocking interval at a speed that will guarantee the knocking of all three ports in under a second.

Knowing all of that I launched a Ubuntu Server VM on my macOS machine which will serve as the attacker host and ran the following command:

Knockd has a feature called ‘knock’ which initiates the port knocking and it requires three parameters.

The destination IP, the destination ports in chronological order and the interval between each knock in msec which is assigned after the ‘-d’ switch.

The SSH server (victim) IP is 192.168.5.36, the destination ports in the TCP packets we captured were 7000,8000,9000 and in that order, and since we want to make sure that all three packets arrive in under a second I set the interval to 200 milliseconds which would equal to 600 msecs.

The I/O graph showed one second but that does not necessarily mean that the timeout configured on the SSH server is 1 second it could be 1 sec or higher.

So, after the port knocking completed I tried to connect via SSH.

I successfully logged in using the password I already knew. But in a real life scenario it is more probable that an attacker would need to perform a dictionary or brute force attack.

But this article just aims on proving that a replay attack on a SSH server that solely relies on port knocking is not safe at all.

After looking at the logs from Knockd you can see that it registered the knocks and passed the authentication.

Conclusion

What can we learn from this ?

Most importantly, that you should always layer as many security controls as possible. You can never rely on the upper layer security control and should always expect it to potentially fail and implement countermeasures that would prevent your Information System from rendering vulnerable.

What could we do to secure SSH Ports ?

  • Periodically change the SSH port to another port than the default port 22
  • Use SSH keys instead of a password to login
  • Make the Port knocking sequence more sophisticated by changing it after each SSH connection
  • Use GeoIP to block a wide range of IP addresses originating from countries that you wont SSH from anyways
  • Set a cap to the allowed number of concurrent connections

I hope you enjoyed this article and would appreciate any type of support whether it be a clap , comment or share :D

--

--