This is a locksmith slipping one warning card out of the handshake, not a burglar kicking the door in
CVE-2023-48795 is the *Terrapin* SSH prefix-truncation weakness: an on-path attacker can manipulate SSH sequence numbers during the initial key exchange, then remove early encrypted messages without either side noticing. In practice it affects SSH stacks that offer [email protected] or CBC plus Encrypt-then-MAC (*[email protected]) without the newer strict kex countermeasure; for OpenSSH the upstream fixed release is 9.6, while enterprise distros often backported the fix into older package versions.
Tenable calling this MEDIUM is defensible in a lab, but for a 10,000-host patch queue I would *downgrade* the finding to LOW unless you have hostile-network admin paths, jump hosts on shared Wi-Fi, or high-value SSH sessions crossing untrusted segments. The decisive friction is attacker position: this is not unauthenticated internet-to-host compromise, it is a live MITM requirement with mostly downgrade-level impact on baseline OpenSSH servers.
4 steps from start to impact.
Get on-path
bettercap or Ettercap, a rogue access point, or upstream network control. Without that packet-path control, Terrapin does not start.- Attacker can intercept and modify packets between client and server
- SSH traffic traverses a segment the attacker can influence
- This implies a prior network compromise, rogue Wi-Fi, or hostile ISP/router position
- Modern enterprise admin traffic often rides VPNs, private WAN links, or segmented management networks
187315 cannot see this prerequisite; it only identifies servers that *could* be affected if a MITM exists.Confirm a vulnerable algorithm mix
[email protected] or CBC plus *[email protected], combined with no strict kex support.- Server or client offers vulnerable algorithms
- Both peers do not negotiate
strict kex
- Some vendors backported
strict kexinto older package versions, so banner-based assumptions can be wrong - Removing vulnerable ciphers from
sshd_configkills the attack even before patching
187315 and the official RUB-NDS scanner both test algorithm support; version-only checks are weaker because of distro backports.Inject and trim handshake messages
SSH_MSG_IGNORE messages during key exchange, then deletes the same number of encrypted packets immediately after NEWKEYS. That preserves sequence-number expectations while stripping security-relevant early messages.- Live packet injection and deletion is possible
- Handshake timing is stable enough to manipulate
- Reliable inline manipulation is harder than passive sniffing
- For Encrypt-then-MAC, practical exploitation needs CBC; CTR/stream cases generally collapse at the application layer
Realize the downgrade impact
SSH2_MSG_EXT_INFO, which can disable a subset of keystroke-timing obfuscation and other extension-negotiated protections. Stronger outcomes require a second bug in a specific SSH implementation; the researchers demonstrated that with AsyncSSH, not with stock OpenSSH server compromise.- Target implementation actually relies on stripped extension negotiation
- Or a separate implementation flaw is present for weaponized follow-on impact
- Upstream OpenSSH says there is no discernible effect on session secrecy or integrity beyond the limited early-message deletion case
- No direct RCE or auth bypass is inherent to the OpenSSH server case
The supporting signals.
| In-the-wild status | I found no CISA KEV entry for CVE-2023-48795, and Palo Alto says it is *not aware of malicious exploitation* in its product advisory. That argues against panic patching for generic SSH servers. |
|---|---|
| Proof-of-concept availability | Public tooling is available: RUB-NDS/Terrapin-Scanner for exposure testing and RUB-NDS/Terrapin-Artifacts with PoC attack proxies. |
| EPSS | Observed EPSS is ~0.58 / 98th percentile in widely mirrored feeds, meaning researchers and defenders care about it, but EPSS overstates patch urgency here because the live-MITM prerequisite is severe friction. |
| KEV status | Not KEV-listed in the CISA Known Exploited Vulnerabilities Catalog. |
| CVSS vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N = the score is held down by High attack complexity, which is the right instinct here because attacker path position is the whole story. |
| Affected range | OpenSSH is affected before 9.6 upstream; the NVD record also tracks many other SSH libraries and clients. Tenable plugin 187315 does not verify package version — it checks whether the remote SSH peer offers vulnerable algorithms and lacks strict kex. |
| Fixed versions | Upstream OpenSSH fix: 9.6. Example distro backports: Ubuntu fixed openssh-server in 1:8.2p1-4ubuntu0.10 (20.04), 1:8.9p1-3ubuntu0.5 (22.04), 1:9.0p1-1ubuntu8.6 (23.04), and 1:9.3p1-1ubuntu3.1 (23.10); Debian fixed bullseye/bookworm in 1:8.4p1-5+deb11u7 and 1:9.2p1-2+deb12u9; Red Hat shipped a moderate fix in openssh-8.7p1-30.el9_2.3 for RHEL 9.2 EUS. |
| Scanning / exposure data | The Terrapin paper's internet-wide scan found 71.6% of SSH servers supported a vulnerable encryption mode and 63.2% preferred one. That means exposure is broad, but broad exposure does not equal easy exploitation. |
| Disclosure | Publicly disclosed 2023-12-18 with OpenSSH 9.6 released the same day. |
| Researchers | Reported by Fabian Bäumer, Marcus Brinkmann, and Jörg Schwenk. |
noisgate verdict.
The single biggest suppressor is the active MITM requirement: the attacker must already control the packet path, which usually implies a prior compromise stage or a very specific hostile-network scenario. Once you remove that assumption, this stops looking like a broad server-compromise emergency and starts looking like SSH hardening debt.
Why this verdict
- Start at vendor 5.9: SSH is everywhere, the protocol flaw is real, and public scanner/PoC code exists.
- -1.3 for attacker position: exploitation requires unauthenticated *on-path* control, which implies rogue Wi-Fi, network compromise, or upstream routing/control — not direct internet-to-service reachability.
- -0.5 for impact limits on OpenSSH: upstream OpenSSH says the most serious identified effect is stripping
EXT_INFOand disabling a subset of keystroke-timing obfuscation, not direct RCE or auth bypass. - -0.2 for exposure ambiguity: many enterprise Linux builds fixed this with backports, so version age alone exaggerates risk; Tenable's remote check is stronger than banner parsing, but still cannot prove exploit consequences for your exact client/server pair.
Why not higher?
There is no strong evidence here of broad in-the-wild exploitation, no KEV listing, and no inherent server-side code execution path. A vulnerability that requires network-path control plus protocol-shaping plus a downgrade-friendly implementation is not a top-tier patch fire for most enterprises.
Why not lower?
This is still a real protocol weakness with public research-grade tooling and very wide algorithm exposure across the SSH ecosystem. If you run bastions, admin access over shared networks, contractor VPNs, or sensitive keyboard-interactive sessions, the downgrade is meaningful enough that it should not be ignored.
What to do — in priority order.
- Disable vulnerable algorithms on exposed SSH servers — Remove
[email protected]and avoid CBC plus*[email protected]where operationally possible, favoring AES-GCM or other unaffected suites. For a LOW verdict there is no SLA; treat this as backlog hygiene and apply during the next normal SSH hardening cycle, prioritizing bastions and internet-facing admin endpoints first. - Patch both sides of managed SSH paths — Terrapin's
strict kexprotection only activates when both peers support it, so patching just servers leaves legacy clients negotiating the old behavior. For a LOW verdict there is no SLA; fold server and admin-client updates into routine maintenance, with jump hosts and privileged operator workstations first. - Constrain admin traffic to trusted paths — Put SSH administration behind VPN, private WAN, ZTNA, or segmented management networks so the live-MITM prerequisite becomes much harder to satisfy. For a LOW verdict there is no SLA; handle this as architecture hardening rather than emergency mitigation.
- Validate with an algorithm-aware scanner — Use Nessus
187315and/or the official Terrapin-Scanner to verify whether the server still offers affected algorithms and lacksstrict kex. For a LOW verdict there is no SLA; use this to clean the backlog and suppress false positives from version-only logic.
- Patching only the server does not fully solve negotiation risk if your managed clients still lack
strict kex, because the countermeasure only helps when both ends support it. - MFA, SSH keys, and PAM hardening do not address this flaw, because Terrapin targets handshake integrity before authentication decisions matter.
- A generic host firewall does not stop a successful MITM once legitimate SSH connectivity is already allowed.
Crowdsourced verification payload.
Run this on the target Linux SSH server as root or with sudo so it can read the effective sshd configuration. Save it as terrapin_check.sh, then run sudo bash terrapin_check.sh; it uses local package metadata plus sshd -T to return VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# terrapin_check.sh
# Purpose: assess likely Terrapin exposure on a Linux SSH server
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
patched() { echo "PATCHED: $1"; exit 0; }
vulnerable() { echo "VULNERABLE: $1"; exit 1; }
unknown() { echo "UNKNOWN: $1"; exit 2; }
have_cmd() { command -v "$1" >/dev/null 2>&1; }
if ! have_cmd sshd; then
unknown "sshd not found on this host"
fi
# Collect effective algorithms when possible
CIPHERS=""
MACS=""
SSHD_T_OUTPUT="$(sshd -T 2>/dev/null)"
if [ -n "$SSHD_T_OUTPUT" ]; then
CIPHERS="$(printf '%s\n' "$SSHD_T_OUTPUT" | awk '/^ciphers /{sub(/^ciphers /,""); print; exit}')"
MACS="$(printf '%s\n' "$SSHD_T_OUTPUT" | awk '/^macs /{sub(/^macs /,""); print; exit}')"
fi
# Helper: see whether config still exposes Terrapin-prone algorithms
config_exposes_vuln="unknown"
if [ -n "$CIPHERS" ] || [ -n "$MACS" ]; then
has_chacha="no"
has_cbc="no"
has_etm="no"
printf '%s' "$CIPHERS" | grep -q '[email protected]' && has_chacha="yes"
printf '%s' "$CIPHERS" | grep -Eq '(^|,)[^,]*cbc($|,)' && has_cbc="yes"
printf '%s' "$MACS" | grep -q -- '[email protected]' && has_etm="yes"
if [ "$has_chacha" = "yes" ] || { [ "$has_cbc" = "yes" ] && [ "$has_etm" = "yes" ]; }; then
config_exposes_vuln="yes"
else
config_exposes_vuln="no"
fi
fi
# Parse upstream OpenSSH version if possible
raw_ver="$(sshd -V 2>&1 | head -n1)"
up_major=""
up_minor=""
if printf '%s' "$raw_ver" | grep -q 'OpenSSH_'; then
ver_part="$(printf '%s' "$raw_ver" | sed -n 's/.*OpenSSH_\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1 \2/p' | head -n1)"
up_major="$(printf '%s' "$ver_part" | awk '{print $1}')"
up_minor="$(printf '%s' "$ver_part" | awk '{print $2}')"
fi
if [ -n "$up_major" ] && [ -n "$up_minor" ]; then
if [ "$up_major" -gt 9 ] || { [ "$up_major" -eq 9 ] && [ "$up_minor" -ge 6 ]; }; then
patched "upstream OpenSSH version is >= 9.6 ($raw_ver)"
fi
fi
# Distro-specific backport checks
if [ -r /etc/os-release ]; then
. /etc/os-release
else
ID=""
VERSION_ID=""
VERSION_CODENAME=""
fi
# Debian/Ubuntu package comparisons
if have_cmd dpkg-query && have_cmd dpkg; then
pkg_ver="$(dpkg-query -W -f='${Version}' openssh-server 2>/dev/null || true)"
if [ -n "$pkg_ver" ]; then
if [ "${ID:-}" = "ubuntu" ]; then
case "${VERSION_CODENAME:-}" in
focal)
dpkg --compare-versions "$pkg_ver" ge '1:8.2p1-4ubuntu0.10' && patched "Ubuntu focal openssh-server $pkg_ver includes Terrapin fix"
;;
jammy)
dpkg --compare-versions "$pkg_ver" ge '1:8.9p1-3ubuntu0.5' && patched "Ubuntu jammy openssh-server $pkg_ver includes Terrapin fix"
;;
lunar)
dpkg --compare-versions "$pkg_ver" ge '1:9.0p1-1ubuntu8.6' && patched "Ubuntu lunar openssh-server $pkg_ver includes Terrapin fix"
;;
mantic)
dpkg --compare-versions "$pkg_ver" ge '1:9.3p1-1ubuntu3.1' && patched "Ubuntu mantic openssh-server $pkg_ver includes Terrapin fix"
;;
esac
fi
if [ "${ID:-}" = "debian" ]; then
case "${VERSION_CODENAME:-}" in
bullseye)
dpkg --compare-versions "$pkg_ver" ge '1:8.4p1-5+deb11u7' && patched "Debian bullseye openssh-server $pkg_ver includes Terrapin fix"
;;
bookworm)
dpkg --compare-versions "$pkg_ver" ge '1:9.2p1-2+deb12u9' && patched "Debian bookworm openssh-server $pkg_ver includes Terrapin fix"
;;
esac
fi
fi
fi
# RHEL 9.2 EUS example from official advisory
if have_cmd rpm; then
rpm_ver="$(rpm -q --qf '%{VERSION}-%{RELEASE}' openssh-server 2>/dev/null || true)"
if [ -n "$rpm_ver" ]; then
case "${ID:-}" in
rhel|redhat|rocky|almalinux|centos)
if [ "${VERSION_ID:-}" = "9.2" ] || printf '%s' "$rpm_ver" | grep -q '\.el9_2'; then
# String compare is unreliable for RPM EVR; use rpm itself.
if rpm -q --quiet --whatprovides 'openssh-server >= 8.7p1-30.el9_2.3' 2>/dev/null; then
patched "RHEL-family 9.2 openssh-server package includes Terrapin fix"
fi
fi
;;
esac
fi
fi
# Config-only mitigation verdicts
if [ "$config_exposes_vuln" = "no" ]; then
patched "effective sshd config does not expose ChaCha20-Poly1305 or CBC+EtM combinations used by Terrapin"
fi
if [ "$config_exposes_vuln" = "yes" ]; then
vulnerable "server still offers Terrapin-prone algorithms and no trusted package-level fix was confirmed"
fi
unknown "could not confirm a fixed package level or determine effective algorithm exposure; verify with Nessus 187315 or RUB-NDS Terrapin-Scanner"If you remember one thing.
strict kex-capable patching of both servers and managed SSH clients into your normal maintenance cycle rather than your break-glass window.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.