Introduction to Port-knocking
Changing the port numbers is not a proper security policy. Changing the port numbers and services is a common mistake. Hackers are going to find out what you are hiding by just a simple port scanner which takes about 2 minutes, nothing more. Nmap will take care of this process, and it’s over.
Port-Knocking mitigates this type of security issues. A Port-knocking server listens to all traffic on an Ethernet (or PPP) interface, looking for special “knock” sequences of port-hits. A client makes these port-hits by sending a TCP (or UDP) packet to a port on the server. This port need not be open since knockd listens at the link-layer level, it sees all traffic even if it’s destined for a closed port. When the server detects a specific sequence of port-hits, it runs a command defined in its configuration file. This can be used to open up holes in a firewall for quick access. The complexity of the knock can be anything from a simple ordered list (e.g., TCP port 1000, TCP port 2000, UDP port 3000) to a complex time-dependent, source-IP-based and other-factor-based encrypted hash.
Port-knocking can be implemented in a number of ways, such as:
- Daemon – With a simple daemon (service), you can run your port-knocked server.
- Kernel-Module – Kernel-Module or device driver is more complicated, but it’s more stable. In fact, Port-knocking has been used in many hacking tools, like rootkits.
Installing Port-Knocking Client/Server
There is a flexible Port-knocking server and client. You can easily install it by port tree or pkg:
# cd /usr/ports/security/knock # make install clean rehash
Tip: issue the above commands on both the client and the server.
This port consists of two app:
Configuring Port-Knocking Server
To configure knockd service, you have to edit knockd.conf. To facilitate that, we must first create a conf file from a sample and then add configurations:
# cp /usr/local/etc/knockd.conf.sample /usr/local/etc/knockd.conf # ee /usr/local/etc/knockd.conf
Contents of knockd.conf:
[options] logfile = /var/log/knockd.log interface = re0 [openSSH] sequence = 7000,8000,9000 seq_timeout = 5 command = /sbin/ipfw -q add 00100 pass proto tcp src-ip %IP% dst-port 22 tcpflags = syn [closeSSH] sequence = 9000,8000,7000 seq_timeout = 5 command = /sbin/ipfw -q delete 00100 pass proto tcp src-ip %IP% dst-port 22 tcpflags = syn
As you can see, there are three sections and many directives. An options section which is dedicated to interface name and log file. The other two sections are for executing the command by a custom sequence of ports within five seconds that has a syn flag.
The first command adds a rule number 00100 to ipfw that allows connection to SSH port by IP address of who knocked successfully.
The second command deletes the previous rule. However, you can execute any command.
One of the most important directives is One_Time_Sequences. You can add this directive by:
One_Time_Sequences = /path/to/one_time_sequences_file
The above referenced file contains the one-time sequences to be used. Instead of using a fixed sequence, knockd will read the sequence to be used from that file. After each successful knock attempt, this sequence will be disabled by writing a ‘#’ character at the first position of the line containing the used sequence. That used sequence will then be replaced by the next valid sequence from the file.
Also, TCPFlags directive can be these values: TCPFlags = fin|syn|rst|psh|ack|urg
When using TCP flags, knockd will IGNORE TCP packets that don’t match the flags. This is different from the normal behavior, where an incorrect packet would invalidate the entire knock, forcing the client to start over. Using “TCPFlags = syn” is useful if you are testing over an SSH connection, as the SSH traffic will usually interfere with (and thus invalidate) the knock. Separate multiple flags with commas (e.g., TCPFlags = syn, ack, urg). Flags can be explicitly excluded by a “!” (e.g., TCPFlags = syn,!ack ).
On your serverm issue the following command to run the port-knocking server:
On your client, issue this command:
# knock “server ip” 7000 8000 9000
Replace “server ip” with your server’s IP.
There are other ways to do Port-Knocking:
The Nmap is a Network exploration tool and security / port scanner, but you issue this command to initiate port-knocking:
# for x in 7000 8000 9000; do nmap -Pn –host_timeout 201 –max-retries 0 -p $x “server ip”; done
The nc (or netcat) utility is used for just about anything under the sun involving TCP, UDP, or UNIX domain sockets. It can open TCP connections, send UDP packets, listen on arbitrary TCP and UDP ports, do port scanning, and deal with both IPv4 and IPv6.
And it can do the same thing with:
# nc -z “server ip” 1000 2000 3000
Pros and Cons
Everything has its advantages and disadvantages and port-knocking is not an exception to this rule:
- Very low overhead
- Easy to deploy
- Compatible with any platform
- Useful directive
- Very hard to brute force
- Can be a single point of failure
- Vulnerable to man in the middle attack
- Sensitive to latency
Reverse shell is a type of connection that the server starts to communicate with the client, and allows the client to use its shell. As you can imagine, the server has no open port to listen but you can connect to it.
All you do is to edit knockd.conf and replace that command with this:
command = ssh -fN -R 9000:localhost:22 [email protected]%IP%
This command binds client port 9000 to server port 22.
And then from client, issue this:
# ssh [email protected] -p 9000
The client connects itself at port 9000, but because ports are interconnected, the client is going to connect to the server.
- Configure the server to do password-less ssh (public key)
- Make sure that parameters such as TCPKeepAlive, ClientAliveInterval,
- ClientAliveCountMax and GatewayPorts are set to appropriate values
Port-knocking is not only about opening a port or something like that. You can do whatever you want like executing a special script or something like reverse shell ot etc.
About The Author
Abdorrahman Homaei has been working as a software developer since 2000. He has used FreeBSD for more than ten years. He became involved with the meetBSD dot ir and performed serious trainings on FreeBSD. He started his company (corebox) in February 2017.
Full CV: http://in4bsd.com
His company: http://corebox.ir