Safeguard
Vulnerability Analysis

Terrapin SSH protocol downgrade attack explained

Terrapin (CVE-2023-48795) lets an on-path attacker silently strip packets from SSH handshakes. Here's how the downgrade works and how to check exposure.

Hritik Sharma
Security Engineer
6 min read

On December 18, 2023, three researchers from Ruhr University Bochum — Fabian Bäumer, Marcus Brinkmann, and Jörg Schwenk — disclosed a flaw in the SSH transport protocol itself, not in any single implementation. Tracked as CVE-2023-48795 and nicknamed Terrapin, the attack lets a network-positioned adversary strip messages from the start of an encrypted SSH session without either endpoint detecting it. It affects OpenSSH, PuTTY, libssh, AsyncSSH, Paramiko, and dozens of other clients and servers when specific cipher modes are negotiated. The researchers published a working proof of concept, a public scanner at terrapin-attack.com, and a coordinated disclosure that pushed OpenSSH to ship 9.6 the same day. This post breaks down what Terrapin actually does, which configurations are exposed, and how to confirm whether your fleet is still running vulnerable SSH negotiation settings months or years after the initial patch cycle.

What is the Terrapin attack?

Terrapin is a prefix-truncation attack against the SSH binary packet protocol that lets a man-in-the-middle attacker silently delete an attacker-chosen number of packets at the very start of a secured SSH channel. SSH negotiates keys and then transitions into an encrypted channel using per-packet sequence numbers to detect tampering. Terrapin exploits the fact that, in certain cipher modes, an attacker sitting between client and server can inject extra packets during the unauthenticated handshake phase and then delete an equal number of real packets later, keeping the sequence-number bookkeeping consistent so neither side raises an integrity error. The result isn't decryption of traffic — the attacker never reads plaintext — but silent removal of specific early messages, which is enough to downgrade security-relevant negotiation that happens right after the handshake completes.

Which SSH configurations are actually vulnerable?

Only two cipher/MAC combinations are exploitable: ChaCha20-Poly1305 (chacha20-poly1305@openssh.com) and any CBC cipher combined with Encrypt-then-MAC (*-cbc with -etm@openssh.com MACs). Both were popular defaults — ChaCha20-Poly1305 in particular was OpenSSH's preferred cipher starting with OpenSSH 6.5 in 2014 because it doesn't depend on AES-NI hardware acceleration. AES-GCM is not affected, because GCM binds authentication to the cipher itself rather than relying on the outer sequence-number scheme Terrapin abuses. The researchers' internet-wide scan found that roughly 77% of SSH servers reachable on the public internet supported at least one vulnerable algorithm combination at disclosure time, which is why this generated a coordinated multi-vendor patch rather than a single-vendor advisory.

How does the prefix-truncation attack actually work?

The attack works by exploiting the gap between the unauthenticated key-exchange phase and the authenticated encrypted phase of the SSH handshake. During key exchange, an attacker on the network path injects extra, unauthenticated packets with sequence numbers the server or client hasn't validated yet — these get silently accepted because the connection isn't fully keyed. Once encryption keys are derived, the attacker deletes exactly as many packets from the real, encrypted stream as they injected earlier. Because SSH's per-packet integrity check is derived from a running sequence number rather than a cryptographic transcript hash of everything sent so far, the counters still line up and the receiving side has no way to detect that packets are missing. The net effect: the first N packets sent immediately after the encrypted channel opens can be deleted by the attacker, with N bounded only by how many packets they injected during key exchange.

What can an attacker actually do with a deleted packet?

The primary confirmed impact is stripping the SSH extension negotiation message (SSH_MSG_EXT_INFO), which is normally the first packet sent after encryption begins and advertises which authentication algorithms and protocol extensions each side supports. Deleting it forces a downgrade to older, weaker signature algorithms during authentication in some client/server combinations. Researchers also demonstrated that in specific configurations of AsyncSSH (tracked separately as CVE-2023-46445 and CVE-2023-46446), an attacker could redirect a victim's authenticated session or inject a spoofed extension message, effectively hijacking the shell session before the user typed a single command. Terrapin does not recover passwords, private keys, or session plaintext — it's a downgrade and message-suppression primitive, not a decryption break — but chained with weak-algorithm fallback or a vulnerable client library, it becomes a session-hijacking vector.

Which SSH implementations were affected and patched?

Every major SSH implementation using ChaCha20-Poly1305 or CBC-EtM by default was affected, including OpenSSH (up to and including 9.5), PuTTY, libssh, Paramiko, AsyncSSH, Dropbear, and the Go golang.org/x/crypto/ssh package. OpenSSH's fix landed in version 9.6, released December 18, 2023, the same day as public disclosure — a sign of how far ahead of the announcement the coordinated disclosure process ran. The fix isn't a cipher removal; it's a new "strict KEX" mode (kex-strict-c-v00@openssh.com and kex-strict-s-v00@openssh.com) that both sides advertise during negotiation, resetting sequence numbers and aborting the connection on any unexpected packet during key exchange, which closes the injection window Terrapin depends on. Because strict KEX requires both peers to support it, mixed old/new environments — a patched OpenSSH 9.6 client talking to an unpatched OpenSSH 9.3 server, for example — remain exploitable until both ends are upgraded.

How do you check if your infrastructure is still exposed?

Run ssh -Q kex against a patched client and check for kex-strict-c-v00@openssh.com in the output, and separately verify with the researchers' public scanner or nmap --script ssh2-enum-algos against each server to confirm it doesn't offer bare ChaCha20-Poly1305 or CBC-ETM without strict KEX support. In practice this means auditing every SSH-speaking asset individually: bastion hosts, CI runners that pull over git+ssh, container base images with stale OpenSSH packages, network appliances and IoT/embedded devices running old Dropbear builds that vendors may never patch, and third-party SaaS integrations that connect over SSH. Because Terrapin requires an active on-path attacker rather than a passive listener, the realistic exposure is highest on shared networks, compromised routers, and cloud environments where east-west traffic isn't otherwise segmented — but "requires MITM" has repeatedly proven to be a weaker bar than teams assume once an adversary already has a foothold.

How Safeguard Helps

Safeguard's SBOM generation and ingest pipeline catalogs every OpenSSH, libssh, Paramiko, and Dropbear component across your containers, VMs, and dependency trees, so you get a definitive inventory of which build versions still predate the strict-KEX fixes instead of guessing from package manager metadata. Griffin AI correlates that inventory against CVE-2023-48795 and the AsyncSSH-specific CVEs to flag which findings sit on assets actually exposed to untrusted network paths, using reachability analysis to separate an internet-facing bastion host from an air-gapped internal tool that poses negligible real-world risk. For confirmed exposures, Safeguard opens auto-fix PRs that bump the vulnerable SSH library or base image to a patched, strict-KEX-capable version, so remediation ships as a reviewable code change rather than a manual ticket queue item that stalls for months.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.