regreSSHion (CVE-2024-6387) — what every homelab operator should know
OpenSSH's most serious public bug since 2006: a signal-handler
race condition in sshd that allows unauthenticated
remote code execution as root on glibc-based Linux. Disclosed
by Qualys on 2024-07-01, patched in OpenSSH 9.8. If your homelab
runs Linux and you SSH into it, this is the post.
The TL;DR
- What it is: a race condition in
sshd's SIGALRM handler that ends up calling async-signal-unsafe functions, leaving the heap in an inconsistent state. With patience, an attacker can convert that into pre-auth RCE as root. - Who's exposed: any glibc Linux box running
sshd8.5p1 through 9.7p1 with the default configuration. Not affected: OpenBSD (different libc, the relevant code path doesn't race), pre-8.5p1 versions (the bug had been fixed in 4.4p1 — it was *reintroduced* in 8.5p1, hence the "regression" naming). - What it costs an attacker: 6–8 hours on a 32-bit no-ASLR system per Qualys's PoC; ~10× harder on 64-bit with ASLR; not yet demonstrated on modern hardened distros but the theoretical path is open.
- The fix: upgrade to OpenSSH 9.8 or your distro's backport. Per-distro fix versions are below.
- If you can't patch: set
LoginGraceTime 0insshd_config. Mitigates this specific bug at the cost of opening a separate DoS vector — fine as a stopgap on a homelab box, not great for production.
Why it matters for a homelab
Every Linux box you own runs sshd by default.
Most homelabbers expose SSH on the LAN at minimum, and a
surprising number expose it to the public internet — port 22
forwarded for remote access, jump boxes on a VPS, Tailscale
relay nodes. Any of those scenarios means a vulnerable
sshd sits between attackers and root.
The "homelabs are too small to attack" argument doesn't apply here. Pre-auth RCE on a public-facing service gets harvested by mass scanners within hours of disclosure — your Pi running Pi-hole on a residential WAN is statistically just as attractive as a Fortune 500 jump box for an internet-wide crawler looking for shells.
The technical mechanism (one paragraph)
sshd uses LoginGraceTime (default 120
seconds) to kill connections that haven't authenticated. When
the timer fires, the kernel sends SIGALRM, and
sshd's signal handler runs. That handler calls
syslog(3) to log the timeout — but
syslog calls malloc and
free internally, neither of which is
async-signal-safe. If SIGALRM fires while the
main process happens to be inside a different
malloc call, the heap is left half-mutated. With
careful timing — controlling when in malloc the
signal lands — the attacker can convert that heap corruption
into a write-what-where primitive and ultimately a control-flow
hijack. This *exact* bug pattern was identified and fixed in
OpenSSH 4.4p1 in 2006 (CVE-2006-5051), and reintroduced by an
unrelated refactor in OpenSSH 8.5p1.
For the deep technical write-up, Qualys's disclosure document is the authoritative source. It's long but worth reading once if you want to understand modern memory-corruption exploitation under hardening.
Detect: is my sshd vulnerable?
Three checks, in order from cheapest to most thorough:
1. Banner check (cheapest)
$ ssh -V
OpenSSH_9.6p1 Ubuntu-3ubuntu13.3, OpenSSL 3.0.13 30 Jan 2024
If the version is between 8.5p1 and
9.7p1 inclusive, the upstream code is vulnerable.
But the distro string after the dash is the important part —
Ubuntu's 9.6p1-3ubuntu13.3 includes the security
backport even though the upstream version (9.6p1) sits in the
vulnerable range.
2. Distro security tracker
Authoritative answer for any major distro. The distro maintainers know exactly which package version contains the backport. As of writing:
- Ubuntu 24.04: fixed in
openssh-server 1:9.6p1-3ubuntu13.3. - Ubuntu 22.04 LTS: fixed in
1:8.9p1-3ubuntu0.10. - Debian 12 (bookworm): fixed in
1:9.2p1-2+deb12u3. - Rocky / RHEL 9: fixed in
openssh-8.7p1-38.el9_4.1. - Alpine: fixed in
openssh 9.7_p1-r4.
The live CVE feed dashboard lists the fix version per distro it covers; cross-check there for the latest values.
3. Live scan
For a fleet of more than two hosts, banner-checking by hand
stops scaling. Tools that audit installed package versions
against published CVE feeds (including Noxen) report
CVE-2024-6387 directly when a vulnerable openssh-server
version is on disk. A scan today should see this finding clear
automatically once you patch — that's the diff-from-yesterday
signal that the fix actually landed.
Fix per distro
# Ubuntu / Debian
sudo apt-get update
sudo apt-get install --only-upgrade openssh-server
# Rocky / RHEL / AlmaLinux
sudo dnf upgrade openssh-server
# Alpine
sudo apk upgrade openssh
# Verify (compare output to the fix versions above)
ssh -V
sshd -V 2>&1 | head -1 # some distros print to stderr
Restart the service so the new binary takes over existing listening sockets:
sudo systemctl restart sshd # systemd
sudo service ssh restart # upstart / sysvinit
sudo rc-service sshd restart # OpenRC (Alpine)
Existing established SSH sessions survive the restart (they're
handled by their own forked-off sshd children;
systemctl restart only re-execs the listener).
But to be safe, log into the box from a second window before
restarting, so a misconfiguration in the upgraded
sshd_config doesn't lock you out.
Defence in depth — what actually buys you something
Patch first, harden second. But once the patch is in, these mitigations narrow the window for the next sshd RCE:
Don't expose port 22 to the public internet
The single highest-leverage move. If sshd only
listens on the LAN (or a Tailscale interface, or a WireGuard
tunnel), an internet-wide pre-auth RCE has nowhere to land.
Most homelab SSH access can route via mesh VPN with no UX
penalty. Cloudflare Access + Tailscale Funnel are two
zero-config options.
Set LoginGraceTime 0 if you can't patch yet
Disables the SIGALRM-driven kill that this specific bug
exploits. Trade-off: a malicious or buggy client can hold a
pre-auth connection forever, opening a slow-loris-style DoS
against your sshd. Fine for ~24 hours while you
schedule the patch; bad as a permanent state.
Rate-limit + ban brute-forcers
fail2ban with default rules will lock out an IP
after a handful of failed attempts. Doesn't prevent the
regreSSHion attack itself (which is pre-auth, no failed
passwords logged), but it keeps the *general* SSH attack
surface small enough that the relevant log entries are easier
to spot.
Disable password auth, require keys
# in /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin prohibit-password # or `no` if you don't need root SSH at all
Independent of regreSSHion, this is the single biggest reduction in your homelab's attack surface — nearly all automated SSH attacks rely on password brute-forcing. SSH key hygiene for homelabs covers the broader practice.
What this incident taught us
Three durable lessons:
- Regressions happen even in audited code. OpenSSH is some of the most-reviewed C code in the open source world. The 4.4p1 fix held for 15 years; an unrelated refactor in 8.5p1 silently undid it. No amount of code review catches every interaction; CI-driven security regression tests + memory-safety tooling matter more than auditor headcount.
- Async-signal-unsafe code in signal handlers is a
loaded weapon. The list of POSIX-safe functions in
a signal handler is short on purpose. Anything that calls
malloc— including the standard library'ssyslog,printf, andstrerror— is not on it. Static analysis can catch most of these; some compilers ship attribute-based annotations to enforce signal-safety at the call site. - Distro backports are the actual fix surface for
most users. Upgrading to OpenSSH 9.8 from upstream
is rarely how this gets patched on real fleets — it's
apt-get update && apt-get upgradepulling in the distro's backport. That's the cadence you actually need to instrument and monitor; tracking upstream OpenSSH releases is interesting but operationally secondary.
How Noxen handles it
regreSSHion appears as a critical CVE finding in any scan of a
vulnerable Linux host. Noxen reads the host's
openssh-server package version (via
dpkg -l or rpm -qa over SSH), matches
it against the
signed CVE feed, and
surfaces the finding with a one-line remediation
(apt-get install --only-upgrade openssh-server or
the distro equivalent). The
severity scoring
respects the distro's own triage label first — Ubuntu rates
this high, Debian rates it high urgency; both
bucket as critical / high in Noxen's UI.
The scheduled-scan agent catches this within 24 hours of the next feed rebuild — so a newly-disclosed equivalent CVE will show up in your dashboard the morning after disclosure rather than on whatever cadence you remember to run a manual scan.