SSH Flashcards
SSH architecture
It is a three layer architecture made of the following protocols:
* Transport Layer Protocol: it takes care of the channel set-up, of the key re-exchange, of the server authN, of confidentiality and integrity (with perfect forward secrecy)
* Client AuthN Protocol: it takes care of client authN (compulsory ≠ TLS) that can be made using various methods. It is built on top of the Transport Layer Protocol and it is protected by it; it runs temporarily
* Connection Protocol: it allows to have multiple connections in the same SSH channel at the same time (≠ TLS) + it enables SSH’s tunneling capabilities, allowing multiple transmissions within one secure session
SSH TLP
The client asks for a SSH connection by contacting the server that listens, by default, on port 22 of TCP.
The client, after the TCP setup, sends to the server the SSH Version String Exchange that is in the format SSH_ProtocolVersion_SWVersion SP comments CR LF.
The server responds with another SSH Version String message.
From now on packets are exchanged using the SSH binary packet protocol.
At this point crypto parameters have to be negotiated and this is done in three phases:
- first they exchange the SSH_KEXINIT message
- then the chosen key exchange method is run
- then the cryptographic keys are derived
SSH Binary Packet Potocol
Each packet exchanged between two parties after the SSH String Version is protected using the SSH Binary Packet Protocol.
It protects exchanged data with integrity and encryption following an authenticate-and-encrypt schema, meaning that both computations are done over data in clear (can be compressed).
-
packet_length
: The first 4 bytes specify the packet length, excluding the MAC and the packet length field itself. -
padding_length
: The next 1 byte specifies the padding length. Padding is used in cases where a block cipher requires it. -
payload
: This section contains the actual payload, which may be compressed. Its size is defined as: size = packet_length − padding_length − 1
with a maximum uncompressed size of 32 KB (32,768 bytes). -
random_padding
: Between 4 and 255 bytes of random padding are added to ensure that the total packet length, excluding the MAC, is a multiple of max(8,cipher_block_size). This alignment is required even when a stream cipher is used, making padding alignment unique to SSH. -
MAC
: After the key exchange and algorithm negotiation, a 4-byte MAC is added to each packet to ensure integrity. The MAC is calculated over the cleartext packet and an implicit sequence number, similar to TLS.S
Upon receiving a packet, decryption must be performed before the MAC can be verified. -> potential Denial of Service (DoS) vulnerabilities
SSH TLP key exchange
Both parties send the SSH_KEXINIT with the following data:
- cookie
(nonce)
- enc algos list client to server and server to client
- mac algos list client to server and server to client
- compression methods list client to server and server to client
- host_key_algos
- key exchange algos: the server will respond with the chosen algorithm starting from the beginning of the list (the first one is the preferred one)
- languages
- first_kex_packet_follows
flag to say that the following packetwill be protected with the guessed algorithms
The SSH_KEXINIT is used to perform key re-exchanged too and that’s why the flag is useful.
SSH algorithms
SSH DH key agreement
C: K_c = g^y sent to the client sent to the server
S: K_s = g^x
K = K_s * K_c
H = hash (client_version_string | server_version_string | client_ssh_kexinit |server_ssh_kexinit | server_host_PK | K_s | K_c | K)
signature = sig(H, server_private_key)
K_s, server public key and Signature sent to the client
C: computes K, computes H and checks signature
It verifies the server signature without a X.509 certificate!
H will be the session_id for the whole connection.
SSH key derivation when using DH for key agreement
Keys are derived with the same. hash used during the exchange:
IV
* From client to server: IV = HASH(K∥H∥”A”∥session_id)
where K is the negotiated key and “A” is simply an ASCII character.
* From server to client: IV = HASH(K∥H∥”B”∥session_id)
Encryption keys :
* From client to server: Encryption Key = HASH(K∥H∥”C”∥session_id)
* From server to client: Encryption Key = HASH(K∥H∥”D”∥session_id)
Integrity keys is generated as follows:
* From client to server: Integrity Key = HASH(K∥H∥”E”∥session_id)
* From server to client: Integrity Key = HASH(K∥H∥”F”∥session_id)
SSH server authentication
Server authentication in SSH uses an asymmetric challenge-response mechanism, where the server proves its identity by signing the key exchange hash H. Since SSH does not use a Public Key Infrastructure (PKI), the client must locally store the public keys of trusted servers. Typically, each user maintains these keys in the ~/.ssh/known_hosts file, which maps server names to their public keys.
To securely initialize this file, it is recommended to obtain server keys through a trusted method, such as directly from a system administrator. When the client connects to a server, the SSH software compares the server’s public key to the one stored in known_hosts. If no matching key is found, SSH prompts the user with the server’s fingerprint, allowing the user to confirm and store the key for future connections (TOFU - Trust On First Use, which is risky).
This setup, however, poses a security risk since anyone with access to the known_hosts file can alter its contents. Best practices for managing known_hosts include protecting the file to ensure authentication and integrity and conducting regular audits to quickly detect any unauthorized changes in stored server keys.
SSH client authentication
It is compulsory and it can be done using various methods:
- password based authN
- X.509 certificate: The public key of the client is stored on the server in the ~/local_user/.ssh/authorized_keys file, providing both authentication and authorization.
SSH port forwarding (generic)
It is a way to forward traffic using a SSH connection.
TLP is used when there is a direct connection between the client and the server. However, if the channel is a tunnel, we have TLP encapsulating the Connection Protocol.
The Connection Protocol is not autonomously protected; it is protected only because it is encapsulated within TLP. This means that the Connection Protocol is not a channel with inherent encryption, authentication, or integrity guarantees but simply a TCP channel inside TLP. Consequently, multiple active sub-channels can exist simultaneously within TLP since they are all TCP channels.
It can be:
- local
- remote
SSH local port forwarding
Forward traffic from a local machine (your computer) to a remote server via an SSH tunnel.
You specify a local port on your computer, and any traffic sent to that port is forwarded through the SSH connection to a specified remote host and port.
Example:
You want to access a service (e.g., a database) running on a remote server, but it’s only accessible from within the server’s network. You can use local port forwarding to access it by forwarding traffic from a local port to the remote service.
ssh -L 8080:localhost:3306 user@remote-server.com
SSH remote port forwarding
Forward traffic from a remote machine to your local machine.
You specify a port on the remote server, and any traffic sent to that port is forwarded through the SSH tunnel to a port on your local machine.
Example:
You want to allow someone on a remote server to access a service running on your local machine.
ssh -R 8080:localhost:80 user@remote-server.com
This command forwards traffic from port 8080 on the remote server to port 80 (e.g., a web server) on your local machine.
Attacks against SSH
BothanSpy
BothanSpy is a tool targeting Xshell, a Windows SSH client.
The attack involves injecting a malicious DLL into an Xshell process to steal:
* Username and password for password-authenticated connections.
* Username, private key file name, and passphrase for public-key authenticated connections.
This attack highlights the risks of using applications with shared libraries.
Gyrfalcon
Gyrfalcon is another tool targeting OpenSSH on enterprise Linux distributions. It preloads a malicious shared library to intercept plaintext traffic—both before encryption and after decryption—allowing it to collect:
* Usernames and passwords.
* Actual session data transmitted over SSH.
Brute Force Attacks
A common misconception is that using a secure channel eliminates the need for robust authentication mechanisms. This can lead to insecure practices, such as using weak, reusable passwords. A typical brute- force attack involves attempting passwords from a dictionary of common or well-known credentials.
SSH insecurities
- One significant problem is the direct trust in public keys since X.509 certificates are not used. Although some commercial versions implement certificates, and OpenSSH supports SSH certificates, most implementations rely on direct trust.
- Users often ignore warnings and blindly accept new server public keys when they are not listed in the known_hosts file. This behavior exposes the connection to Man-in-the-Middle (MITM) attacks.
- Weak server or client platform security is another issue. Malware can alter or read the known_hosts file or the authorized keys, compromising the integrity of SSH connections.
- A notable risk with local port forwarding is that any connection to the forwarded port will be tunneled, even if it originates from another node. This means that local forwarding might inadvertently allow unauthorized users to utilize the connection. To mitigate this, it is crucial to specify the local bind address, ensuring that port forwarding is restricted to localhost.
For example:ssh -L 127.0.0.1:1234:mail_server:25 user@ssh_server
By doing so, only processes originating from localhost can access the tunnel, preventing external
exploitation.
SSH protections from brute force attack
- Account lockout after N authentication failures and automatically blacklist attackers after detecting N authentication failures in the logs.
- Use techniques to permit or deny access from specific hosts or networks.
- Implement SSH rate control with iptables, for example, limiting connections to 5 per minute. This slows down brute force attempts trying multiple passwords.
- Deny direct root access via SSH: this is a compulsory measure. Users must connect with their own username and use sudo to obtain root privileges.
- Consider changing the default port number from 22 to another port. Note that this offers limited protection as the new port can still be discovered through port scanning.
- Enable two-factor authentication (2FA), for instance, by adopting Google Authenticator.
- The best security measure is to disable password-based client authentication entirely and configure the server to accept only challenge-response authentication.
Differences between TLS and SSH
TLS
- level 4.5
- optional client authN
- optional encryption
- authN-then-encrypt
- use of X.509 certificates
- In TLS, you must open a new connection in the same session or start a new session to exchange keys again
SSH
- level 7
- compulsory client authN
- compulsory encryption
- authN-and-encrypt
- X.509 certificates only in OpenSSH implementations
- connection not closed when key-re exchange
SSH main applications
The main applications of SSH include:
* Remote interactive access with a text-based interface.
* Execution of commands on remote systems without accessing the shell.
* Creation of tunnels for various applications, utilizing the security provided by SSH, as discussed earlier.
SSH clients and servers are now natively available on Linux, MacOS, and Windows, making secure remote communication widely accessible across platforms.