This is a burglar trying to pick a lock during a two-second power flicker instead of walking through an open door
CVE-2024-6387 is the regreSSHion bug: a signal-handler race in sshd that reintroduced the old CVE-2006-5051 flaw. Upstream Portable OpenSSH is affected in versions 8.5p1 through 9.7p1 inclusive, plus very old pre-4.4p1 builds if they were never patched years ago; OpenBSD is not affected, and many Linux vendors fixed or backported patches without changing the obvious upstream banner string.
The vendor's HIGH 8.1 rating is basically fair, but the scary part needs context. This is *unauthenticated network-to-root* in a ubiquitous daemon, which keeps it out of MEDIUM territory, yet exploitation is not clean commodity RCE: Qualys described thousands of attempts, tight timing around LoginGraceTime, target-specific heap behavior, and practical success on glibc/Linux lab targets rather than broad one-shot internet exploitation.
4 steps from start to impact.
Find a reachable sshd that only looks patchless
OpenSSH_8.5p1 to 9.7p1. Typical tooling is nmap, masscan-derived banner collection, or internet datasets like Censys; public scanner/exploit repos such as l0n3m4n/CVE-2024-6387 fold this recon into one workflow.- TCP/22 or alternate SSH port reachable from the attacker
- Target runs
sshd, not just the SSH client - Version truly vulnerable rather than distro-backported
- Banner strings are a poor truth source on Debian/Ubuntu/RHEL-style backports
- Many enterprises hide SSH behind VPN, bastion, allowlists, or internal-only routing
- OpenBSD is unaffected and some distro builds are not exploitable the way upstream lab targets were
Race LoginGraceTime with heap grooming
SIGALRM during sensitive memory operations. The goal is to corrupt heap state so that async-signal-unsafe work in the alarm path, notably logging via syslog() on glibc systems, runs in the wrong state.- Unauthenticated remote access to
sshd - Target uses a susceptible glibc/Linux execution path
- Default or permissive
LoginGraceTimeand enough concurrent startups to make repeated attempts practical
- Qualys reported roughly 10,000 attempts on average in lab conditions
- Network jitter, host load, ASLR, and architecture differences make remote timing unreliable
- Rate limiting, connection controls,
fail2ban, lowMaxStartups, or upstream filtering reduce attempt volume
Win the race in the privileged parent
sshd code before authentication completes, giving a path to memory corruption and potential code execution as root. Qualys demonstrated this against glibc-based Linux targets and noted the parent process is privileged and not sandboxed at that point.- Precise timing success on the target build
- Heap layout and libc behavior compatible with the exploit strategy
- No crash or connection exhaustion stops the run before code execution
- Public evidence is strongest for lab-grade and 32-bit-style demonstration paths; broad 64-bit reliability is much less convincing
- Many attempts will just fail or crash the daemon rather than yield code execution
- A single host compromise does not automatically imply domain-wide blast radius unless SSH trust or automation keys are poorly segmented
Turn root on one box into something that matters
root is obtained, the attacker can drop persistence, steal keys, pivot to internal management networks, or tamper with automation and backup paths. The weaponization here is standard Linux post-exploitation, not something unique to this CVE.- Useful follow-on credentials, secrets, or trust relationships on the compromised server
- Outbound access or lateral paths from the host
- Modern EDR, PAM/auditd telemetry, egress controls, and key hygiene can contain impact after the initial foothold
- Hardened bastions often have lower business blast radius than app or orchestration nodes
The supporting signals.
| In-the-wild status | No official confirmed active exploitation found in the sources reviewed. It is not listed in CISA KEV at the time of this assessment. |
|---|---|
| Proof-of-concept availability | Public PoCs exist on GitHub, including scanner/exploit projects such as l0n3m4n/CVE-2024-6387; Qualys published the technical advisory but explicitly withheld exploit code. |
| EPSS | 0.63835 (*user-supplied*). That is materially high; comparable public dashboards place it roughly in the 97th-98th percentile band. |
| KEV status | Not in CISA KEV as checked against the current catalog; no KEV add date applies. |
| CVSS vector reality check | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H is directionally right. The AC:H is doing real work here because this is not point-and-click RCE. |
| Affected versions | Upstream Portable OpenSSH <4.4p1 may be affected if never patched for the older bug; the modern regression window is 8.5p1 through 9.7p1 inclusive. OpenBSD is not affected. |
| Fixed versions | Upstream fix is 9.8p1. Examples of vendor backports include Ubuntu 22.04 1:8.9p1-3ubuntu0.10, Ubuntu 24.04 1:9.6p1-3ubuntu13.3, Debian 12 1:9.2p1-2+deb12u3, RHEL/Rocky/Oracle 9 8.7p1-38.el9_4.1, and Amazon Linux 2023 8.7p1-8.amzn2023.0.11. |
| Exposure data | Exposure is large wherever SSH is internet-facing. Censys published hunt queries for public-facing vulnerable OpenSSH and Qualys characterized the issue as affecting internet-facing Linux estates at scale, but apparent counts are inflated by banner/backport mismatches. |
| Exploit friction | Qualys reported about 10,000 attempts on average in lab testing, with ~3-4 hours for their Debian 12 i386 path and ~6-8 hours once ASLR guessing is included. That is serious, but it is not a clean single-request exploit. |
| Disclosure and reporter | Disclosed 2024-07-01 by the Qualys Threat Research Unit as a regression of CVE-2006-5051. |
noisgate verdict.
The decisive factor is that this remains unauthenticated remote code execution in sshd, a service that often sits directly on enterprise edges and yields root if it lands. What keeps it out of CRITICAL is the unusually heavy exploit friction: thousands of timed attempts, target-specific heap behavior, and weak evidence of broad reliable exploitation across modern 64-bit Linux fleets.
Why this verdict
- Starts high because this is pre-auth network reachability to
rootin one of the most common remote admin daemons on Linux. - Adjusted downward for exploit friction because the attacker must win a timing race repeatedly; Qualys described about
10,000attempts on average plus architecture/libc-specific constraints, which is a major real-world brake on mass exploitation. - Adjusted downward again for reachable population because many enterprises do not expose SSH broadly, and even when banners look vulnerable, distro backports, OpenBSD immunity, and vendor-specific quirks cut the truly exploitable set.
Why not higher?
It is not CRITICAL because the current evidence does not show broad in-the-wild exploitation or a dependable one-shot exploit path across mainstream 64-bit enterprise Linux. This is a high-value bug, but the attack chain is noisy, slow, and sensitive to target and timing conditions.
Why not lower?
It is not MEDIUM because if a host is genuinely vulnerable and reachable, the payoff is root before authentication with no user interaction. Public PoCs and integrated scanners reduce attacker setup cost, and SSH exposure is still common enough that defenders cannot treat this as lab-only trivia.
What to do — in priority order.
- Restrict SSH exposure — Put internet-facing SSH behind VPN, bastion hosts, IP allowlists, or management network segmentation. For a HIGH verdict, deploy this within 30 days wherever patching is not already complete, because attacker reachability is the single biggest amplifier for this CVE.
- Set
LoginGraceTime 0on exposed stragglers — If you cannot patch immediately, setLoginGraceTime 0insshd_configto remove the vulnerable alarm path used by the published research. Do this only on genuinely exposed or high-value hosts and complete it within 30 days; understand you are trading RCE risk for easier connection-exhaustion DoS. - Rate-limit and cap pre-auth connection volume — Lower
MaxStartups, enforce network rate limits, and use controls likefail2banor upstream firewall throttling to reduce the thousands of attempts an exploit run wants. This should be in place within 30 days on exposed Linux SSH services that cannot be remediated immediately. - Hunt for pre-auth SSH churn — Alert on repeated incomplete handshakes, auth timeouts, and bursts of simultaneous unauthenticated SSH sessions to the same host. Stand this up within 30 days so you catch exploit rehearsals, not just successful post-exploitation behavior.
- MFA on SSH does not help because the bug is triggered *before* authentication succeeds.
- Version-banner checks alone do not reliably separate vulnerable from patched on distro-backported systems.
- EDR alone is not sufficient prevention; it may catch payload execution after compromise, but it does not stop the race in the privileged daemon path.
Crowdsourced verification payload.
Run this on the target Linux host as a local audit check: sudo bash ./check-cve-2024-6387.sh. Root is not strictly required for the package checks, but sudo helps if sshd -V or package metadata access is restricted; the script prints exactly VULNERABLE, PATCHED, or UNKNOWN and exits 0, 1, or 2 respectively.
#!/usr/bin/env bash
# check-cve-2024-6387.sh
# Purpose: best-effort local assessment for CVE-2024-6387 (regreSSHion)
# Output: VULNERABLE | PATCHED | UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
say() { printf '%s\n' "$1"; }
patched() { say 'PATCHED'; exit 0; }
vulnerable() { say 'VULNERABLE'; exit 1; }
unknown() { say 'UNKNOWN'; exit 2; }
if ! command -v sshd >/dev/null 2>&1 && ! command -v dpkg-query >/dev/null 2>&1 && ! command -v rpm >/dev/null 2>&1; then
unknown
fi
OS_ID=""
OS_VER=""
OS_CODE=""
if [ -r /etc/os-release ]; then
# shellcheck disable=SC1091
. /etc/os-release
OS_ID="${ID:-}"
OS_VER="${VERSION_ID:-}"
OS_CODE="${VERSION_CODENAME:-}"
fi
dpkg_ge() {
dpkg --compare-versions "$1" ge "$2"
}
sortv_ge() {
# Loose fallback comparator for RPM-ish version-release strings.
[ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]
}
is_glibc() {
if command -v ldd >/dev/null 2>&1; then
ldd --version 2>&1 | head -n1 | grep -Eqi 'glibc|gnu libc'
return $?
fi
return 1
}
check_deb() {
local ver
ver="$(dpkg-query -W -f='${Version}' openssh-server 2>/dev/null || true)"
[ -n "$ver" ] || return 1
case "$OS_ID:$OS_CODE" in
ubuntu:focal|ubuntu:bionic|ubuntu:xenial|ubuntu:trusty)
patched ;;
ubuntu:jammy)
if dpkg_ge "$ver" '1:8.9p1-3ubuntu0.10'; then patched; else vulnerable; fi ;;
ubuntu:mantic)
if dpkg_ge "$ver" '1:9.3p1-1ubuntu3.6'; then patched; else vulnerable; fi ;;
ubuntu:noble)
# Canonical notes noble's socket-activation patch likely blocks the Qualys exploitation approach,
# but use the fixed package as the safe line.
if dpkg_ge "$ver" '1:9.6p1-3ubuntu13.3'; then patched; else unknown; fi ;;
debian:bullseye)
patched ;;
debian:bookworm)
if dpkg_ge "$ver" '1:9.2p1-2+deb12u3'; then patched; else vulnerable; fi ;;
debian:trixie|debian:sid|debian:forky)
patched ;;
esac
return 2
}
check_rpm() {
local vr
vr="$(rpm -q --qf '%{VERSION}-%{RELEASE}\n' openssh-server 2>/dev/null || true)"
[ -n "$vr" ] || return 1
case "$OS_ID:$OS_VER" in
rhel:9*|rocky:9*|almalinux:9*|ol:9*|centos:9*)
if sortv_ge "$vr" '8.7p1-38.el9_4.1'; then patched; else vulnerable; fi ;;
amzn:2023)
if sortv_ge "$vr" '8.7p1-8.amzn2023.0.11'; then patched; else vulnerable; fi ;;
sles:*|opensuse-leap:*|opensuse-tumbleweed:*)
unknown ;;
esac
return 2
}
check_upstream_banner() {
local banner ver
banner="$(sshd -V 2>&1 || true)"
ver="$(printf '%s' "$banner" | sed -n 's/.*OpenSSH_\([0-9][0-9.]*p[0-9][0-9]*\).*/\1/p' | head -n1)"
[ -n "$ver" ] || unknown
# Normalize a little for sort -V comparisons.
if printf '%s\n%s\n' "$ver" '4.4p1' | sort -V | head -n1 | grep -qx "$ver"; then
if [ "$ver" = '4.4p1' ] || printf '%s\n%s\n' "$ver" '4.4p1' | sort -V | tail -n1 | grep -qx "$ver"; then
:
fi
fi
# Old versions below 4.4p1 may be vulnerable unless separately backport-patched.
if [ "$(printf '%s\n%s\n' "$ver" '4.4p1' | sort -V | head -n1)" = "$ver" ] && [ "$ver" != '4.4p1' ]; then
unknown
fi
# 8.5p1 <= version < 9.8p1 => vulnerable upstream on glibc-based Linux.
if [ "$(printf '%s\n%s\n' "$ver" '8.5p1' | sort -V | head -n1)" = '8.5p1' ] || [ "$ver" = '8.5p1' ]; then
if [ "$(printf '%s\n%s\n' "$ver" '9.8p1' | sort -V | head -n1)" = "$ver" ] && [ "$ver" != '9.8p1' ]; then
if is_glibc; then vulnerable; else unknown; fi
fi
fi
patched
}
if command -v dpkg-query >/dev/null 2>&1; then
check_deb
rc=$?
[ $rc -eq 2 ] || unknown
fi
if command -v rpm >/dev/null 2>&1; then
check_rpm
rc=$?
[ $rc -eq 2 ] || unknown
fi
check_upstream_banner
unknown
If you remember one thing.
sshd, separate true package versions from misleading banners, and patch the real vulnerable set first. Because this is HIGH, the noisgate mitigation SLA is ≤30 days—use that window to restrict SSH exposure, deploy LoginGraceTime 0 only on exposed stragglers, and add detection for repeated pre-auth SSH churn—while the noisgate remediation SLA is ≤180 days for applying the actual vendor-fixed package everywhere in scope.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.