Back 1dayexploit.com CVE-2026-123158 Exploit: sshhole Auth Bypass 1dayexploit / 42min OpenSSH before version 10.6p2, when built against musl libc without PAM, accepts any password between 257 and 1024 bytes for accounts whose shadow password field is exactly (disabled, key-only accounts). sshhole (CVE-2026-123158) is a pre-auth authentication bypass in OpenSSH that affects sshd on musl libc systems.
sshhole (CVE-2026-123158) is a pre-auth authentication bypass in OpenSSH that affects sshd on musl libc systems. OpenSSH before version 10.6p2, when built against musl libc without PAM, accepts any password between 257 and 1024 bytes for accounts whose shadow password field is exactly * (disabled, key-only accounts). This allows an unauthenticated remote attacker to take over the targeted account with no valid credential. CVSS 8.1 HIGH.
Affected: OpenSSH portable = 10.6p2
Distributions: Alpine Linux, OpenWrt, Buildroot, Yocto, and other systems using musl libc
Not affected: glibc-based systems, builds compiled with PAM enabled, distributions that have backported the fix
Default configuration: affected (PasswordAuthentication yes is the default)
Access needed: unauthenticated network access to SSH port 22 (or configured custom port)
Output from a vulnerable system:
Output from patched 10.6p2+:
If the version is 10.6p2 or later, you are patched. Note that on Alpine Linux and some other distributions, the package version may be older but the binary is patched: check the actual build with sshd -V rather than apk info openssh .
# Configuration check
Verify that the build does not use PAM:
If no output, PAM is not linked and the system is vulnerable (assuming version to lock accounts properly, which sets the field to ! .
Set PasswordAuthentication no in /etc/ssh/sshd_config and restart sshd. SSH key authentication is not affected by this vulnerability.
Alternatively, set PermitRootLogin no (if root is the targeted account) or use firewall rules to restrict SSH access to trusted source IPs.
Ensure all disabled accounts have a password field of ! or !! instead of * . Use usermod -L to lock accounts properly, which sets the field to ! .
Detection: Monitor sshd logs for the distinctive pattern of a Failed password immediately followed by Accepted password for the same user on the same connection. This is the signature of the bypass in action. On Alpine: tail -f /var/log/auth.log .
# Root cause analysis
# Vulnerable code path
The vulnerability lives in OpenSSH's non-PAM password authentication path ( sys_auth_passwd() in auth-passwd.c ):
The guard if (authctxt->valid && pw_password[0] && pw_password[1]) checks that the stored password field has at least 2 characters. For an account with field * (1 character), pw_password[1] is null and this condition fails. With salt == NULL , the crypt layer calls pick_salt() , which borrows the salt prefix from another account's hash - typically a $5$ (sha256crypt) or $6$ (sha512crypt) salt.
# How the password reaches the crypt sink
When musl libc's crypt function receives a key longer than 256 bytes (its KEY_MAX limit), the SHA-crypt code path returns the single-character error token "*" instead of a hash. OpenSSH then runs the comparison strcmp("*", "*") == 0 , which is true, and accepts the login.
The two preconditions that enable this:
The account's shadow password field must be exactly * (disabled account with no real hash).
At least one other account must have a $5$ or $6$ hash, so pick_salt() selects a SHA-family salt (if the only hash available is DES, the attack does not work the same way).
Passwords outside the 257-1024 byte range do not trigger it:
256 bytes or less: hashed normally against the borrowed salt, does not match *
1025 bytes or more: rejected by sshd before reaching crypt, MAX_PASSWORD_LEN == 1024
# Why musl + no PAM is necessary
musl libc specific: glibc's crypt() returns NULL for a length error, not "*" . With NULL , the comparison never succeeds.
No PAM: the PAM authentication path in OpenSSH branches before sys_auth_passwd() is called. PAM-enabled builds skip this code entirely.
The fix in OpenSSH 10.6p2 (commit 4353fdc43ef646c43a8dda7025cc1a898caf1482 ) adds a minimum-length floor:
With this guard, a stored field of length 1 (like * ) can never satisfy the authentication condition, regardless of what crypt() returns. The patch also added cleanup with freezero() to clear sensitive password strings from memory.
The minimum-length floor ensures that only plausible password hashes (at least 4 characters, the minimum for any standard crypt format) are accepted as successful authentication. A single * or ! will always fail, preventing the attack even if musl returns an error token that coincidentally matches the stored field.
# exploit.py - OpenSSH sshhole Auth Bypass PoC
Run against the default account (root) on the default SSH port:
Run against a custom account and port:
Run against root to demonstrate full account takeover:
Batch scan a list of targets:
where targets.txt contains one target per line ( with # and blank lines are ignored):
# Vulnerable target output
# Patched target output
Target runs OpenSSH sshd before version 10.6p2
Built against musl libc (not glibc) and without PAM
PasswordAuthentication yes in sshd_config (the default)
Target account exists, has a valid login shell, and its /etc/shadow password field is exactly *
At least one other account on the host has a $5$ (sha256crypt) or $6$ (sha512crypt) hash to donate the salt
The exploit must send the over-long password twice on a single SSH connection. The first attempt primes sshd's borrowed-salt cache (and is rejected); the second attempt on the same connection is accepted. The exploit uses NumberOfPasswordPrompts=2 with an askpass helper to deliver both attempts without user interaction.
# Reliability and impact
The exploit is deterministic and non-destructive. It only performs authentication and a single command execution; it does not modify target state and can be re-run unlimited times. On success, the attacker obtains a shell as the targeted user with full privilege. If the targeted account is root (and PermitRootLogin yes ), the attacker gains uid 0 control of the system.
Authentication bypass to uid 0 is the terminal impact for this CVE. However, in a real attack scenario, the authenticated shell can be used to:
Exfiltrate sensitive data
Install persistence mechanisms
Pivot to other accounts or systems
Disrupt service availability
Alpine Security Advisory:
OpenSSH Release Notes:
Fix Commit:
sshhole reference:
NVD:
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
