brl / obfuscated-openssh

Other
421 stars 121 forks source link

Handshake Obfuscation

Handshake obfuscation strengthens the initial SSH handshake against systems that identify or classify various network protocols by examining data in transit for static signatures. Such automatic classification of traffic is often used to provide different levels of network service for each protocol and sometimes used to implement policies which prohibit certain uses of a network.

When an SSH connection is initiated, the client and server exchange several packets to configure the cryptographic parameters for the session. Since the encryption algorithms and keys have not yet been determined, this exchange of messages is not encrypted and is vulnerable to analysis which can conclusively identify the connection as SSH protocol traffic no matter what port the server is listening on. For most users this is of no concern, because merely being able to identify a connection as an SSH session does not introduce any security vulnerabilities in the protocol itself.

Some users may have special security needs where they would prefer not to disclose that they are using the SSH protocol to somebody who may be monitoring the network. Handshake obfuscation prevents automatic identification of SSH protocol traffic by encrypting the entire handshake with a stream cipher, and is designed to make it difficult to implement an automated analysis tool even understanding how the obfuscation protocol works.

The obfuscation encryption key is generated in a way which is deliberately slow to make it difficult to implement on the type of high performance network hardware which is usually used for classifying protocol traffic. Additionally an option is provided for the client and server to share a 'keyword' which is a simple kind of password that is used only for securing the handshake. No connection can be initiated to a server which has keyword obfuscation enabled without knowing the keyword, and the obfuscation keyword is used to derive the keys that encrypt the handshake in order prevent decrypting the handshake traffic without knowing the keyword.

Configuration

Server:

The server configuration for obufscated handshakes adds two new keywords which may be used in a sshd_config file to enable obfuscation.

ObfuscatedPort
       This option is similar to the Port option and specifies one or more ports
       on which to listen for obfuscated handshake connections.  Both this option
       and the Port option may be used in the same configuration file to create a
       configuration with both regular and obfuscated listening ports.

ObfuscateKeyword
       Enables the keyword protected obfuscated handshake which prevents initiating
       a handshake to the server without knowing the keyword.

Client:

The OpenSSH client can be configured to use the obfuscated handshake protocol by passing command line options as well as through configuration file options.

-z             Initiate an obfuscated handshake to the remote server.
-Z keyword     Initiate a keyword protected obfuscated handshake to the remote server.

Two new client configuration file options hve been added.

ObfuscateHandshake
       Requests that the client use the obfuscated handshake protocol.  The default is 'no'

ObfuscateKeyword
       Enables keyword protected obfuscated handshake.  The server and client must be
       configured with the same keyword in order to initiate a connection.

Protocol Description

The first step in the obfuscation protocol is that the client connects to a port running the protocol and sends a seed message which is used to derive the keys for obfuscating the handshake.

define OBFUSCATE_MAGIC_VALUE 0x0BF5CA7E

define OBFUSCATE_SEED_LENGTH 16

define OBFUSCATE_MAX_PADDING 8192

[ 16 byte random seed ][ magic ][ plength ][ .. plength bytes of random padding ... ] ___ __
        Plaintext                                Encrypted with key derived from seed 

To create the seed message the client first generates 16 pseudo random bytes from which the handshake obfuscation keys will be derived. The client also runs the key derivation algorithm (described below) to initialize the obfuscation cipher.

The 'magic' field and the 'plength' field are 32 bit unsigned values transfered in network byte order (MSB first).

The magic field must contain the constant OBFUSCATE_MAGIC_VALUE and the 'plength' field must contain a randomly selected value between 0 and OBFUSCATE_MAX_PADDING. Then 'plength' bytes of pseudo randomly generated data is appended after the length field.

The purpose of the padding is to prevent a trivial traffic analysis attack which allows the protocol to be identified my merely observing the size of the first message.

Upon receiving the seed message from the client, the server must extract the seed bytes and perform the key derivation algorithm (described below) before decrypting the rest of the message. Then the server must verify that the magic value is correct and also that the padding length is below OBFUSCATE_MAX_PADDING.

If these checks fail the server will continue reading and discarding all data until the client closes the connection without sending anything in response.

Key Derivation

The key derivation produces a pair of keys (one for each direction) by performing an iterated hash function over the random seed value concatenated with a constant value.

A different constant value is used for each direction to guarantee that the two stream ciphers instances are initialized with unique keys.

define OBFUSCATE_HASH_ITERATIONS 6000

define OBFUSCATE_KEY_LENGTH 16

h = SHA1(seed || constant)

for(i = 0; i < OBFUSCATE_HASH_ITERATIONS; i++)
    h = SHA1(h);

key = [first OBFUSCATE_KEY_LENGTH bytes of h]

For traffic from the client to the server the constant is the string "client_to_server"

For traffic from the server to the client the constant is the string "server_to_clint"

Passworded Key Derivation

A configuration option is provided which allows specification of a password which must be specified by a client in order to initiate a handshake with the server. This feature should not be considered as strong authentication as it is only for preventing casual portscanning and fingerprinting of your ssh server.

h = SHA1(seed || password || constant)