 |
|
 |
by Cappella and Tan Chew Keong
8 June 2004
POC implementation to be released soon.
Port knocking is a technique that can be used to hide services that are running on a hardened server. This
is achieved by not opening the service port until a correct sequence of "knock" packets are received
by the server. There are currently many implementations of port knocking and most of them require the client
to send a fixed pre-defined sequence of port knocks to the server. The problem with this approach is that once
the adversary got knowledge of the knock sequence, it would be trivial for him to replay the sequence in order
to gain access to the service port.
In our previous paper [1], we presented an implementation of port knocking that does not require the use of
fixed pre-defined sequences. However, the technique that we proposed in [1] may be susceptible to cryptographic
computation resource starvation attacks. In this paper, we present an improved port-knocking technique that
uses One-Time Port-Knocking (OTPK). This technique improves upon our previous method and addresses its limitations.
The implementation that we proposed in [1] suffers from a number of limitations. These limitations
are highlighted below.
- Cryptographic Computation Resource Starvation Attacks
In Step One of the proposed technique, the port-knock client sends an encrypted UDP packet (P1) to the
server to declare the proposed port-knock sequences. Upon receiving the packet, the port-knock daemon will decrypt
the packet using the user's password hash to determine the knock sequences. Despite careful filtering of packets
prior to decryption, it is still possible for the adversary to flood the server with an excessive number of
P1 packets that are captured when a valid user is performing the port-knock. This would cause the server to perform
an excessive amount of decryption, potentially leading to resource starvation.
- Information Gathering
UDP packet (P1) contains the user name in clear, this is required so that the port-knock daemon can retrieve
the corresponding user's password hash to decrypt the packet. Having the user name in clear may allow the
adversary to monitor usage patterns.
- No Control Over Client's Choice of Port-Knock Parameters
In the technique proposed in [1], the client generates the port-knock parameters (i.e. ISN and port number)
using a random number generator, encrypts them, and sends them to the port-knock daemon. The daemon has no
control over the parameters that are chosen by the client. Hence, weak port-knock parameters may be chosen if the
random generator on the client system fails for some reason.
- Anti-Replay Using TimeStamp is Not Ideal
To prevent replay, the technique proposed in [1] requires the use of a time-stamp in packets P1, P2 and P3.
The use of time-stamps is not ideal since it is affected by time skew on the user's system. It is also affected
by time zone differences if the user travels to other countries.
In this paper, we propose an improved port-knocking technique that addresses the issues mentioned above. The
new technique uses One-Time Port-Knocking (OTPK).
In this technique, the server assigns each client a random port-knock sequence. The client uses the server
assigned sequence only once. Upon receiving the correct knock sequence from a client, the server will generate a
new knock sequence and sends it to the client in an encrypted packet. This new knock sequence will be used by the
client for its next request.
The client uses the server assigned knock sequence only once, and thus, this approach is very similar to the concept
of one-time password (OTP).
The following sequence of steps gives a high-level overview of how our proposed technique works.
- When a new user is added to the system, the Administrator must generate a random port-knock sequence for the
new user and sends it to the new user by email or other means. This port-knock sequence is encrypted using
the user's password hash. The Administrator must also let the new user know his username and password using some
offline means.
- The user starts the port-knock client and inputs his username and password. The user's password hash is
generated from the username and password.
- The client program retrieves the current knock sequence from disk, decrypts it using the user's password hash,
and plays the knock sequence to the daemon.
- Upon receiving the correct knock sequence, the daemon opens a random port for the client.
- The daemon generates a new knock sequence and sends it to the client together with the assigned port number
in an UDP packet that is encrypted using the user's password hash. This packet shall be called P1.
- The client program receives and saves the new knock sequence to disk, and uses it for the next request.
The following diagram depicts this.
Figure 1 - Our One-Time Port-Knocking (OTPK) Implementation
Design Considerations
- Encryption
The UDP packet P1 is encrypted using the user's password hash. This means that the server
must have a copy of each user's password hash to perform decryption. Compromise of the server will also
lead to the disclosure of the hashes and will allow the adversary to forge packets P1. Hence, the
file that stores all users' password hashes must be well protected on the server. Similarly, the file that
stores all users' current knock sequences must also be properly protected on the server.
The advantage of using the user's password hash for encryption is that there is no need to store any
encryption keys on the client.
- Dynamic Knock Sequences
Our proposed technique do not require the client to send a fixed pre-defined sequence of port knocks to
the server.
Instead, the client will use the server assigned port-knock sequence only once. The
port-knocks in our implementation are a sequence of TCP SYN packets with specific Destination Port Numbers and
Initial Sequence Numbers (ISNs). When the user runs our port-knock client program, it retrieves the server assigned
knock sequence from local storage. The knock sequence consists of three TCP destination port numbers and three
ISNs, which the client will send to the server using three TCP SYN packets.
The decision to use three SYN packets is a trade-off between the ease of guessing the knock sequence and the
difficulty of sending large number of SYN packets in sequence. When the SYN packets travel through the Internet,
there is no guarantee that they will arrive in the same sequence they were sent. Hence, we decide not to rely on
sending a large number of SYN packets to make the random knock sequence difficult to guess.
We make use of the ISN field in each SYN packet to store a 4-byte (32-bit) random number that must match with
the ones that assigned by the server using encrypted packet P1. Three SYN knocks will give us 12 bytes (96 bits) of
randomness. This is combined with the randomly chosen destination port number in each SYN packet, giving
us a total of 12 bytes + (3 * 2-byte destination port number) = 18 bytes (144 bits) of randomness. This is
shown in the following diagram.

- Replay Attacks
Replaying the TCP knock sequence is not feasible since it is used only once. Further, the
probability of knock sequence collision is low if the daemon uses a secure random number generator to
generate 144-bit numbers as new knock sequences for the clients. To prevent replay of the UDP packet P1, our
proposed technique uses the packet content shown in the following diagram. P1 is encrypted using the user's
password hash, which is known only to the user and the daemon. We include the current knock-sequence within P1
so that the client can differentiate it from a replayed packet.

- Computation Resource Starvation Attacks
Our port-knock implementation listens for all incoming packets in promiscuous mode. Hence, there is the
danger that any port-scans on the server would generate additional load due to the processing being
performed by our port-knock daemon.
To protect the server against such attacks, our implementation performs several checks to weed out
invalid packets as early as possible in the processing loop. In addition, we permit each client to have at
most one outstanding port-knock request at any one time. This prevents a user from generating an
excessive number of port-knock requests.
Encrypting and sending of P1 is performed by the daemon only after receiving the correct knock sequence from
a client. Hence, unlike our previous proposed technique [1], the adversary cannot send packets to cause the daemon to
perform unncessary encryption/decryption.
- Information Gathering Attacks
Our improved technique no longer requires the username to be sent in clear. This prevents information gathering
attacks.
- Connection from Unauthorized IP Addresses
Instead of opening a fixed port for the client after receiving the correct knock sequences, our implementation
opens a randomly chosen port. This has an advantage since it makes it harder for the adversary to guess
the correct open port. The daemon also perform IP address checks to prevent connections to the assigned
port from unauthorized IP addresses. In addition, our implementation also integrates with iptables (Linux)
and pktfilter (Win32)
to further block connections from unauthorized IP addresses.
Forwarding of connection from the random port to the actual service port is done in our daemon code. This makes
it possible to run SSHD on 127.0.0.1 instead of running it on the public IP interface. Our port-knocking
daemon can then be used to forward connections from the random port to the SSHD service.
In this paper, we presented an improved port-knocking technique that addresses the issues in [1]. The
technique uses One-Time Port-Knocking (OTPK) in which the client uses the server assigned port-knock
sequence only once. Upon receipt of the correct knock sequence from a client, the server will generate a
new knock sequence and sends it to the client in an encrypted packet. The client will use this new knock sequence for
the next request.
Our implementation also uses dynamic port forwarding where each client is assigned a random port number to access
the same service. Further work is still possible in this area, for example, the implementation of port-knock TCP
wrappers that do not require the Administrator to pre-configure allowed IP addresses. Asymmetric cryptography can
also be used in our proposed technique to sign and encrypt P1. This has several advantages including not having
to store users' password hashes on the server.
- Cappella and Tan Chew Keong,
Remote Server Management using Dynamic Port Knocking and Forwarding
- Krzywinski, M. 2003. Port Knocking:
Network Authentication Across Closed Ports. SysAdmin Magazine 12: 12-17.
- CMN, SAdoor A non listening remote shell and execution server
- FX, cd00r.c
For further enquries, comments or bug reports, email them to the following.
Tan Chew Keong
webmaster@security.org.sg
|
 |