Port knocking

Security with obscurity, on the side

Document by Patrick F. Wilbur

Spring 2006


Introduction

Background

Port knocking is the act of connecting to a closed port (or ports in a certain "combination" sequence) in order to pre-authenticate access to particular services. Upon "knocking" on a closed port(s), clients that administer the proper secret knock can have ports for other services opened up for them and gain access to those services. By default, services protected by a portknocking implementation should have their ports closed until the portknocking daemon, the "doorman", receives the proper expected connection attempts.

Why Closed-Port Pre-Authentication?

Why talk to strangers? If strangers know what services you or your firm are running then your services may be exploited by whatever vulnerabilities they may have. Even if certain services you or your firm intentionally run are fairly secure in authentication and operation, port scan details can reveal to a potential attacker what operating systems and versions of them are in use and promote system-specific attacks. Furthermore, providing inside knowledge of you or your firm's operation may be dangerous in other ways, such as with social engineering. Pre-authenticating firewalls provide a buffer between the hostile Internet and your services, both of which may have well-known or surprise vulnerabilities; closed-port pre-authentication, more specifically, helps obscure details of the pre-authentication implementation to potential attackers.

Portknocking Example: Our Implementation

Background

First of all, we decided to implement a conventional multiple-port port knocking system because it is what first comes to mind for most who are familiar with the concept of port knocking. It is also possible to send (optimally encrypted) authentication data to a single, closed port and consider the data sent the "secret knock", but we felt the multiple-port approach would be the most interesting and challenging (due to packet-order considerations).

Our implementation is the first of its kind (as far as we could tell) to solve a problem we saw in conventional multiple-port port knocking approaches. Some very simplified approaches use a single port with no authentication methods beside watching a single port for an attempted connection, and other simple approaches watch a single port and authenticate based on an encrypted string that is sent to the closed port containing user information; more complicated approaches use a sequence of many ports as a combination code, which may even contain an entire (possibly encrypted) message. The problem with using sequences of ports is that IP-based protocols (at best) preserve the order of packets sent on a single port but do not guarantee the preservation of packet order over different ports.

Our solution to this problem is to segment the 65k ports that are available, so that each segment of a certain length corresponds to a single digit of the encrypted message. The value of a digit is the offset from the start of the segment's range for that particular digit, or the incoming port number modulo the number of ports allocated to each digit's segment. The digit that this value corresponds to is the incoming port number divided by the number of ports allocated to each digit's segment.

A simplified example: if dealing with values that represent a single character each (256 possibilities) and if using encrypted messages of a max length of 4 digits, ports 1-256 could correspond to the first digit, 257-512 to the second, 513-768 to the third, and 768-1024 to the fourth; if the incoming port sequence is {3, 260, 516, 773} then the values of the four digit encrypted message is 3,4,5,6, which is the same even if the order of arrival for those same ports changes.

Strengths

This segmentation of the port range allows us to identify the order of digits simply by the looking at what range a particular incoming port falls into, so we piece together the array of digits accordingly.

In our encrypted message, we include a time stamp containing the local time as reported by the client, the IP address claimed by the client, the port the client has identified it wishes to toggle (either opened at the start or closed when done using it), and a name/comment field for the user of the client (not yet used, but available if needed in the future). Our "door" daemon will take a few safety precautions: it will check to make sure the current time is not greater than the timestamp + expiration time, and will check that the IP address claimed by the client's message matches the IP address that the knock appears to be actually originating from. That way if a spy on the network repeats the exact same knock it saw pass by with no knowledge of the encryption key, the spy cannot alter the message and still send a valid message, so the spy's IP address should not match the IP encoded in the message. Even if an IP is spoofed later on after the authentic client is done using its ports and the spoofer blindly repeats the same message, the timestamp will indicate a knock that is too old to be valid and will be unsuccessful.

Weaknesses

The main weakness we see with our message implementation is that a prankster can start closing same port(s) an authentic client just opened, or an intruder can re-open the same port(s) an authentic client just closed, provided the attacker repeats the knock very shortly after the authentic user finishes sending it (within the window that is open before that knock's expiration). We don't feel that solving this weakness is within the scope of our project, but others may choose to account for this (which stems from a flaw in the design of the network and its control mechanisms).

One possible solution to this problem is to have a key or part of the message change according to a predictable pattern that both the client and server can expect, but we chose not to include this solution because an authentic client could be locked out completely if the client and server lose synchronization with one another for this rotating element (which is very likely to happen since there is no way to provide discreet feedback from the server to client to hint when rotations occur, which could occur during an erroneous transmission of the message). Another (MUCH better) solution is to tunnel all traffic between the client and server through a proxy/VPN that uses strong encryption (where the client and server are already aware of the keys and the keys are not shared across the net), to ensure that a blind attacker could not actually gain the ability to send data to ports. Either way, if an attacker really wanted to, s/he could also spoof the IP address of the authentic client while the authentic client is using the ports that were opened, so strong encryption is a must during the transactions that follow pre-authentication and authentication (REMEMBER: security with obscurity is desired, not security through obscurity, alone).

Another weakness is the fact that we are not using really any form of encryption at all. Dealing with encryption was out of the scope of this project. Please do not rely on our implementation in production environments!

Since we used a multiple-port instead of a single-port implementation, it may be more obvious to an untrustworthy member of a network that port knocking is in use (due to the large number of near-simultaneous connection attempts to closed ports during each knock). This could be overcome by using a single-port implementation, where the knock is a string message sent to a closed port, but we wanted to demonstrate solutions to potential multiple-port implementation problems (plus the flood of closed-port connections was more fun to monitor during testing).

Conlusions

I learned many new things from this project. First of all, since I knew almost nothing at all about IP, TCP/IP, or UDP/IP prior to this project, I'd say that I learned quite a bit about such packets and some general networking concepts. I had to learn to examine raw packet data, which was accomplished with the help of Professor Matthews and Ethereal. Second of all, I learned a great deal about the pcap libraries (like those used in Ethereal) to enable monitoring of inactive ports that knocks may be received upon. We wanted to use libpcap instead of relying on firewall logs due to the great performance disadvantages to using file-based logs and constantly re-scanning them.

Interestingly enough, our assumption that packet delivery is "goulash" when it comes to order-preservation failed to be confirmed. In all our tests, packets were received in the order they were sent, so connections to individual ports were received in the proper order; however, it is important to note that we were on an internal, private network performing our tests, so this result may not be typical across hostile networks like the Internet. Our implementation accounts for the potential for order-loss.

Useful Resources

Port knocking

Development With libpcap

"Security Through Obscurity" vs. "Security With Obscurity"



Credits

Document

This document was written by Pat Wilbur and is Copyright 2006 Patrick Wilbur. You may site it if you find it useful. Feel free to use information from it or quote it, provided proper citation (if you do, feel free to drop me a line at my e-mail address and make me feel useful!). If you wish to reprint this document for some unforeseen reason for other than personal purposes, please e-mail me and ask first. Thanks. projects ("at"-symbol) pdub ("dot") net

Project Code/Ideas

Code and ideas for this project are Copyright 2006 Jason Galens and Patrick Wilbur.

Thanks

Thanks to Professor Jeanna Matthews for advising this project and contributing her networking expertise.


Patrick F. Wilbur
Last modified: 7-31-2006 16:08 EST