Single Packet Authorization
Countless pieces of software, protocols and complex interdependencies together form a system for which it is difficult to guarantee any particular property—particularly security. Even software specifically designed to enhance security can, at the behest of clever individuals armed with detailed knowledge, work to its detriment. Vulnerabilities have been discovered in all sorts of security software from firewalls to implementations of the Secure Shell (SSH) Protocol. For example, OpenSSH is developed by some of the most security-conscious developers in the world, and yet it occasionally contains a remotely exploitable vulnerability. This is an important fact to note because it seems to indicate that security is hard to achieve and, therefore, bolsters the case for a defense-in-depth approach. This article explores the concept of Single Packet Authorization (SPA) as a next-generation passive authentication technology beyond port knocking.
When an attacker is on the prowl in an attempt to exploit a vulnerability in server software (as opposed to client software), the first step is reconnaissance; the attacker needs to locate a target. This process has been brilliantly automated by Nmap, so it is easy to construct a list of target systems that may be ripe for compromise. If the attacker has found a zero-day vulnerability in server software that you happen to be running, you don't want to appear in this list of targets! Both port knocking and Single Packet Authorization use a packet filter configured in a default-drop stance and simultaneously provide service only to those IP addresses that can prove their identity via a passive mechanism. No TCP/IP stack access is required to authenticate remote IP addresses via this passive means. Nmap cannot even tell that a server is running when protected in this way, and it does not matter even if the attacker has a zero-day exploit.
This article is the first of a two-part series on Single Packet Authorization, and it lays the theoretical foundation for Single Packet Authorization and why it is a next-generation passive authorization technology beyond port knocking. The next article will provide a hands-on look at using fwknop to provide Single Packet Authorization protection for your SSH dæmon.
Port knocking is a first-generation technology that uses the port fields within TCP and UDP packet headers to communicate information. Normally, these protocols are used to encapsulate application layer data, but port knocking encodes information in sequences of packets to various ports by using the port numbers themselves as fields to transmit data. These packets are typically either monitored out of a firewall log or via a packet capture mechanism, such as libpcap. Typically, there is a port knocking client and a port knocking server. The terms client and server, in this case (and throughout the remainder of this article unless otherwise noted), refer to the software components that send and monitor packets, respectively. The client is responsible for generating the port sequences, and the server is responsible for passively collecting the sequences and reconfiguring the packet filter to allow connections to protected services upon receipt of a valid sequence.
The typical port knocking scenario is for a port knocking server to configure a packet filter to block all access to a service, such as SSH, until a specific port knock sequence is sent by a port knocking client. For example, the server could require the client to send TCP SYN packets to the following ports in order:
If the server monitors this knock sequence, the packet filter reconfigures to allow an SSH connection from the IP address that sent it. By making use of a connection tracking mechanism provided by the packet filter (such as the conntrack system in Netfilter), an SSH session can remain established after the initial rule created by the knock server is removed after a timeout. Port knock sequences can be encrypted, and there are many implementations listed at www.portknocking.org. For a graphical representation of port knocking in action, see Figure 1.
Port knocking offers some real benefits for limiting access to services, but where do the limitations lurk? First, it is clear that encrypting knock sequences is important, and this in turn implies that several bytes of information must be transmitted. For symmetric crypto systems, the encrypted data will be at least as large as the block size (128 bits for the Rijndael symmetric block cipher chosen for the Advanced Encryption Standard). For asymmetric crypto systems, the encrypted data will be substantially larger.
For instance, the raw ElGamal algorithm used by GnuPG doubles the plain-text size when encrypting data. Even though GnuPG also utilizes compression (which can sometimes reduce the size of the cipher text to below the original size of the plain text), the typically large key size of GnuPG keys implies that the cipher text for even the smallest messages will be in the hundreds of bytes.
This has important implications for port knocking. Each packet within a port knock sequence can send only two bytes of information due to the 16-bit-wide port fields in the TCP and UDP headers. (This assumes that other fields within packet headers are not also used to transmit data. However, even if other fields are used, this still cannot result in nearly as much data transmission as using packet payloads.) Hence, for a block cipher, an encrypted sequence must contain at least B/(2*8) packets, where B is the block size in bits. This by itself would not be so bad when considering the general speed and reliability of today's networks, but the real issue is out-of-order delivery.
Decrypting garbled data results in garbled data, and because there is no notion of a “connection” (in the TCP sense) between the port knock client and server, the server has no ability to re-order out-of-order packets.
Packets may take different routing paths, some of which may be slow. Hence, the client must resort to an artificial mechanism to try to reduce the potential for out-of-order delivery: time. By introducing a time delay between each packet in a knock sequence, say on the order of a half second, packet order usually can be maintained by the time the packets reach the server. Now, for a block size of 128 bits, the corresponding port knock sequence is 128/(2*8) = 8 packets. By factoring in the half-second delay, it takes four seconds just to transmit the sequence. For a much larger message, such as those that would be generated by an asymmetric cipher, this data transmission rate is simply not practical.
Having a limited ability to transmit data introduces another limitation in port knocking schemes. It is difficult to guard against a replay attack effectively. Anyone who can monitor a knock sequence as it is sent from the client to the server is free to replay the sequence against the server in an effort to gain the same access. This is an especially important issue if the sequence is sent through a NAT device, and the source IP that is allowed through the packet filter at the server side is the external NAT address. For example, if the port knock client is on an RFC 1918 subnet, say 10.10.1.0/24, and the port knock server is on a remote network that is accessible only over the open Internet, the server must allow access to the NAT IP address. Anyone on the same subnet who can replay the sequence will be granted the same level of access. Also, anyone on the same subnet has the same level of access once a rule is instantiated to accept connections from the NAT address as long as the rule exists (no sequence replay is required in this case, and this remains true for SPA as well).
There have been variations made on traditional port knocking to try to provide a solution for the replay problem, such as making time a significant factor, using S/Key-style hash function iteration and even simply changing the encryption key after each use. However, each of these methods requires some state to be maintained by both the port knock client and server and does not scale very well when multiple users become involved.
An additional port knocking limitation is that it is extremely easy for a malicious third party to bust a knock sequence just by spoofing an additional packet into the port sequence as it is sent over the wire by the client. The attacker would simply set the source address on the packet to be the same as that of the real client and choose the same port number as the last packet sent by the client. This extra packet would break the knock sequence, so the server would not allow the legitimate client any additional access. Although the chances that people would actually do this are relatively small (they still need to be able to monitor packets emanating from the client), the main issue is that such an attack is so trivially easy to perform. A single packet is all that is required, and the attacker doesn't even need to be inline to the original packet data path.
Finally, knock sequences are easily detectable as port scans by any intrusion detection system (IDS) that is able to monitor traffic between the client and server. This is particularly true for encrypted knock sequences, which tend to be longer than simple shared sequences. To an IDS, port knocking looks just like a series of probes to various ports from a single IP address within a relatively short period of time, and this fits the definition of a port scan quite nicely.