CVE-2024-6387 — regreSSHion OpenSSH unauth RCE
TL;DR: A signal handler race in OpenSSH’s pre-authentication code (sshd) lets an attacker race
SIGALRMagainstcleanup_exit()and call async-signal-unsafe functions (syslog → malloc → free) from inside the handler — a classic heap-state corruption. Reachable unauthenticated against glibc Linux distros running OpenSSH 8.5p1 to 9.7p1. Exploitation is slow (8000 connections, ~6-8 hours on default sshd), but reliable on 32-bit and proven on x86_64 by Qualys. The lesson is to audit signal handlers in security-critical daemons, never to trust “this code path is exit-only.”
What it is
OpenSSH limits authentication time via LoginGraceTime (default 120s). When the timer fires, sshd raises SIGALRM. The handler — installed in 2006 and quietly racy since 8.5p1 when an unrelated commit removed a guard — calls syslog(3) to log the timeout, then _exit(). syslog internally calls localtime_r, malloc, free. Any of those mutating a glibc internal data structure mid-call can race the interrupted allocator state in the main thread. The race is on the heap arena lock and on __nss_database. Win the race at the right moment and an attacker-controlled username (handled in userauth_request) can corrupt heap metadata → glibc free-list manipulation → arbitrary write → RCE.
Affected versions
- Vulnerable: OpenSSH 8.5p1 through 9.7p1 on glibc-based Linux (Debian, Ubuntu, RHEL, Alpine if glibc).
- Not vulnerable: OpenBSD (different signal model), musl libc (Alpine default), OpenSSH ≥ 9.8p1.
- Pre-8.5p1: Also “vulnerable” to the original 2006 bug (CVE-2006-5051) but exploitation has not been demonstrated.
Reachability
- TCP/22 reachable (or whatever port sshd binds).
- Default
LoginGraceTime 120(lower = shorter window per connection but more rounds). - Default
MaxStartups 10:30:100. - Glibc.
Tradecraft (red-team)
The Qualys PoC is not publicly released as a working exploit; multiple researchers have rebuilt it. Realistically, in a pentest scenario you confirm version + glibc + reachability, then leave exploitation to a documented PoC (rule of engagement permitting):
1
2
3
4
5
6
7
8
9
10
# Version probe (banner)
nc -w3 target 22 | head -1
# OpenSSH_9.6p1 Ubuntu-3ubuntu13.4 <-- vulnerable
# Distro fingerprint to confirm glibc
curl -s https://shodan.io/host/<ip> # or scan banners
# Test connection without auth — verify LoginGraceTime
time ssh -o PreferredAuthentications=none -o BatchMode=yes user@target
# Should hang ~120s then close
A practical exploit runs O(8,000) concurrent connections sustained for hours, racing the SIGALRM precisely as syslog is mid-malloc. Defenders observe a massive flood of connection attempts well below an obvious DoS — sshd[NNN]: Timeout before authentication repeatedly. That signature alone justifies blocking IPs.
Several public exploits exist of unclear quality (acrono/CVE-2024-6387-exploit, xaitax/CVE-2024-6387_Check); for defensive validation, treat them as probes only and patch instead of trying to reproduce RCE.
Patch / mitigation (the actual response)
- Patch: openssh-9.8p1 introduced a strict async-signal-safe handler that no longer calls
syslog/free. Distro backports: Ubuntu USN-6859-1, Debian DSA-5724-1, RHEL CVE-2024-6387 errata. - Mitigation if patching delayed: set
LoginGraceTime 0insshd_config(disables the bug at the cost of allowing slow auth DoS). Restart sshd. - Network defence: rate-limit inbound TCP/22 to ≤ 10 conn/min per source IP; the exploit needs sustained flood.
- Detection: alert on > 100
sshd: Timeout before authenticationevents per minute from a single source.
Source-code lesson
The bug demonstrates the limits of an “exit path is safe” intuition. Audit checklist for any signal handler in a security daemon:
1
2
3
4
5
6
7
void handler(int sig) {
// ONLY async-signal-safe operations (man 7 signal-safety).
// NO malloc, NO free, NO syslog, NO printf, NO gettimeofday on glibc.
// The interrupted thread holds locks you don't see.
write(STDERR_FILENO, "msg\n", 4); // OK
_exit(1); // OK
}
man 7 signal-safety lists the ~120 safe functions; syslog is conspicuously absent. The 2006 bug was caught and patched specifically for syslog; the 2024 regression came when someone reintroduced it during refactor.
Detection and defence (broader)
- Patch every Linux box running sshd to ≥ 9.8p1 or vendor-backport.
- Default-deny inbound 22; expose via jump host with VPN/Bastion.
fail2banrule onsshd: Timeout before authenticationrepeated > 5x in 60s.- For high-value targets: switch to
Match Address+ key-only auth and shortenLoginGraceTimeto 30s — narrows the window even pre-patch. - Consider running sshd under musl distro (Alpine) for exposed jump hosts.
OPSEC pitfalls (for the attacker)
- A successful exploit chain takes hours; the connection flood is visible in any IDS.
- The exploit leaves the sshd process crashed or in a strange state; the next admin login often sees
coredumpctlartifacts. - AppArmor profiles on sshd restrict post-exploit lateral; expect to need a privilege chain.
References
- Qualys — RegreSSHion advisory — full technical writeup
- OpenSSH 9.8 release notes — patch details
- NIST NVD — CVE-2024-6387 — official record
- man 7 signal-safety — async-signal-safe function list
- Ubuntu USN-6859-1 — distro patch
See also: cve-2024-3094-xz-utils-backdoor, cve-2024-23897-jenkins-arbitrary-file-read, kernel-syscall-source-review, ssh-execution