1. Overview

Security researchers publicly disclosed a cryptographic integrity degrading attack on SSH named Terrapin in December 2023. This attack affected many SSH libraries and their dependent tools, such as OpenSSH and scp. Consequently, the majority of devices became vulnerable and needed to be secured.

In this tutorial, we demonstrate how to mitigate the Terrapin SSH attack. Initially, we’ll study the attack and the vulnerability scanning process. Then, we’ll learn the scenarios behind a successful exploit. After that, we’ll eliminate the underlying vulnerability by configuring SSH parameters and cryptographic policies. Lastly, we’ll see the adopted patch and libraries that implemented it.

We used Debian 12 (Bookworm) OS with Bash 5.2.15 for a client-server pair and a CentOS Stream 8 server with Bash 4.4.20 for running scripts modifying cryptographic policies. Both servers had OpenSSH 9.5, the last vulnerable version, whereas the client machine had a patched version 9.2p1-2+deb12u2. We ran a Terrapin vulnerability scanner from the client to validate the mitigation steps on the servers.

2. Terrapin Attack

Terrapin is a MitM (man-in-the-middle) attack manipulating the sequence numbers during an SSH handshake by sending one or more arbitrary SSH messages to either end, say n messages to the client and m to the server. Hence, the client and server sequence numbers go out of sync. When the encrypted communication begins, the MitM drops the initial authentic packets originating at either end until both ends are in sync.

This prefix-truncation attack (one where an attacker deletes initial packets) degrades the integrity of the encrypted channel because the dropped packets go unnoticed. Furthermore, the MitM could degrade the cryptographic strength under specific circumstances, like forcing user authentication via a weaker public key algorithm.

2.1. Scanning the Server for the Vulnerability

Let’s install the Terrapin vulnerability scanner through the go command:

$ sudo apt update
...
$ sudo apt -y install golang
...
$ go install github.com/RUB-NDS/Terrapin-Scanner@latest
...

Now, we’ll run the scanner on our server having the IP address 34.50.100.92 and format the output in JSON using the –json option:

$ ~/go/bin/Terrapin-Scanner --json --connect 34.50.100.92
{
    "RemoteAddr": "34.50.100.92:22",
    "IsServer": true,
    "Banner": "SSH-2.0-OpenSSH_9.5",
    "SupportsChaCha20": true,
    "SupportsCbcEtm": true,
    "SupportsStrictKex": false,
    "Vulnerable": true
}

The output shows the scanned details and the result under the Vulnerable flag. The server is vulnerable if SupportsStrictKex is false and SupportsChaCha20 or SupportsCbcEtm is true.

Mitigation changes aren’t necessary for a non-vulnerable server.

3. Mitigating the Attack

Terrapin affects only two encryption modes:

  • [email protected] cipher
  • EtM (encrypt-then-mac) based MAC (Message Authentication Code) with CBC (Cipher Block Chaining) or CTR (Counter) ciphers

On the other hand, GCM (Galois/Counter Mode) ciphers and EaM (encrypt-and-mac) modes aren’t vulnerable. Therefore, disabling the vulnerable encryption modes is the initial preventive remediation step.

Furthermore, the researchers found two root causes behind Terrapin:

  1. During the handshake, SSH doesn’t prevent arbitrary SSH messages.
  2. Sequence numbers don’t reset after establishing the encrypted channel.

Patched software eliminates these causes by introducing a strict key exchange feature.

4. Configuring SSH Parameters

A successful SSH handshake requires a common encryption mode on both ends. Thus, disabling the vulnerable modes on the server prevents the attack on connections with any client. On the other hand, it’s essential to configure the client when connecting to an untrusted server that could still be vulnerable.

We’ll modify the system-wide config files on the client and server: /etc/ssh/ssh_config and /etc/ssh/sshd_config, respectively. Editing these files requires root privileges. Alternatively, a client user can edit their own ~/.ssh/config file and it will take precedence over /etc/ssh/ssh_config.

*Essentially, we’ll remove the chacha20-based cipher and turn off EtM MAC algorithms in both config files*. It’s crucial to set the Ciphers and MACs directives and place them before any Match directive to apply these changes unconditionally.

4.1. Removing the chacha20-Based Cipher

Upon opening each config file, we’ll first search for the Ciphers directive. If it’s present with a list of values including [email protected], removing this cipher is necessary.

However, if Ciphers is absent, let’s add it:

Ciphers -chacha20*

Here, the ‘-‘ character prefix inverts the match, excluding values matching the pattern chacha20* from the directive’s default values.

4.2. Turning Off the EtM MAC Algorithms

Similarly, we’ll search for an existing MACs directive in each config file. If we find it, let’s ensure that we remove the values matching the pattern *-etm*:

If the directive is absent, let’s add it by negating the pattern:

MACs -*-etm*

Thus, we excluded EtM MAC algorithms.

4.3. Verifying the Server Configuration

The client’s config file changes will automatically apply for future SSH connections. However, let’s verify the configuration on the server via sshd with the -T option:

$ sudo sshd -T
...
ciphers aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected]
macs [email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1
...

As shown above, none of the values in these two lines match the corresponding patterns we specified.

Now, we’ll apply these changes by restarting sshd using systemctl:

$ sudo systemctl restart sshd

Thus, new connections to the server are now secure.

5. Modifying Cryptographic Policies

RHEL (Red Hat Enterprise Linux) based distros have system-wide cryptographic policies or crypto-policies enforced with the update-crypto-policies tool since RHEL 8. These policies override the values defined in the system-wide config files.

Let’s check the current policy on our CentOS Stream 8 server by passing a –show option to update-crypto-policies:

$ update-crypto-policies --show
DEFAULT

Now, let’s add a modifier to this policy by creating the file /etc/crypto-policies/policies/modules/TERRAPIN.pmod:

$ sudo vi /etc/crypto-policies/policies/modules/TERRAPIN.pmod

In this file, let’s enter these lines to turn off the vulnerable modes:

cipher@SSH = -CHACHA20*
ssh_etm = 0

The first line removes the chacha20 cipher from the previously applied list of ciphers. The second line turns off EtM. Since RHEL 9.4, ssh_etm has been deprecated in favor of a newly introduced etm directive:

etm@SSH = DISABLE_ETM

Thus, the above line will replace the modifier file’s second line in RHEL 9.4 and newer systems.
Now, let’s enable our modifier by appending ‘*:TERRAPIN’* to the existing policy using the –set option:

$ sudo update-crypto-policies --set DEFAULT:TERRAPIN
Setting system policy to DEFAULT:TERRAPIN
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.

The system will apply all modifications after we reboot it, thus securing our CentOS server.

6. Strict Key Exchange

In response to Terrapin, OpenSSH implemented a strict key exchange or ‘strict KEX’ feature starting from version 9.6 to eliminate the attack’s root causes. However, strict KEX works only if both client and server support it, thus ensuring backward compatibility.

In this feature, either end resets its sequence number after sending or receiving an SSH2_MSG_NEWKEYS message – the last message before establishing an encrypted channel. Moreover, either party will close the connection if it receives any unexpected or out-of-order message that isn’t strictly required during the key exchange flow of the SSH handshake. These measures overcome both root causes and secure the system from Terrapin.

6.1. Upgrading Software

Most of the affected SSH libraries shipped patched versions implementing strict KEX since the public disclosure, such as libssh (0.10.6 and 0.9.8), OpenSSH (9.6/9.6p1), PuTTY (0.80), Golang x/crypto/ssh (0.17.0), AsyncSSH (2.14.2) and Apache MINA SSHD (2.12.0). Upgrading the system or specific software to a patched version will eliminate the vulnerability.

The Windows SSH tool Win32-OpenSSH has a beta version that won’t automatically upgrade with system updates as of May 2024. Hence, it’s important to configure the SSH parameters for the current user in the %USERPROFILE%\.ssh\config file or manually install the beta version.

7. Conclusion

In this article, we learned how to mitigate the Terrapin SSH attack by making system-wide configurations to turn off vulnerable encryption modes or by upgrading software to a patched version supporting strict KEX.

Initially, we examined the attack, the vulnerability scanner, and the vulnerable modes and causes behind Terrapin. Then, we saw SSH config file changes for securing the client and server. Later, we understood the changes in RHEL-based distros supporting crypto-policies. Lastly, we studied the strict KEX patch and libraries that published patched versions.