Threat reportVulnerabilityTL-2026-5338
OpenSSH on musl libc (Alpine Linux) authentication bypass via overly long password ("*sshole")
OpenSSH prior to 10.6p2 on musl-based Linux systems built and run without PAM allows password login to accounts whose password field is an asterisk (such as root or key-only users) when the attacker supplies a password of 257-1024 characters. The flaw, dubbed *sshole and reported by Özgün Kültekin of Wakefield, is fixed in OpenSSH 10.6p2 (2026-11-05); no in-the-wild exploitation has been reported.
Key facts for OpenSSH musl password bypass
| Identifiers | TL-2026-5338, CVE-2016-6210, CVE-2026-123158 |
|---|---|
| Also known as | *sshole, sshhole |
| Severity | HIGH |
| CVSS | 8.1 |
| First disclosed | |
| Exploitation status | Public proof-of-concept exploit |
| Affected products | OpenBSD / OpenSSH OpenSSH (portable) on musl libc without PAM; Alpine Linux Alpine Linux (musl libc) including cloud and Docker images; OpenWrt / Buildroot / Yocto musl-based embedded Linux builds running OpenSSH without PAM |
| Weaknesses (CWE) | CWE-287, CWE-754, CWE-394 |
| Tools | sshhole.com compromise-check CLI command |
| MITRE ATT&CK techniques | T1021.004 Remote Services: SSH, T1078.003 Valid Accounts: Local Accounts, T1098.004 Account Manipulation: SSH Authorized Keys, T1133 External Remote Services, T1136.001 Create Account: Local Account, T1190 Exploit Public-Facing Application |
| Motivation | UNKNOWN |
| Target sectors | cloud, technology, embedded-iot, containers |
| Target regions | Global |
| Detection rules | 9 (1 shown free) |
| Sources | 7 cited sources |
Detection coverage for OpenSSH musl password bypass
As of 2026-11-05, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-5338 across Splunk SPL, Microsoft KQL and Sigma, covering 28 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.
Free detection: *sshole OpenSSH musl Password Login to Locked/Key-Only Account — Exploitation (SPL)
Detects successful sshd password authentication for accounts that should never accept a password (root, the default cloud user alpine, key-only deploy/admin users). On musl libc systems running OpenSSH older than 10.6p2 without PAM, a 257-1024 character password makes crypt() return * which matches the * in the locked account's password field (*sshole, TL-2026-5338, T1190/T1078.003). Behaviour-first: the over-long password is not logged, so the successful password login to a locked account is the observable.
- Languages: Splunk SPL, Microsoft KQL, Sigma
- ATT&CK: T1190, T1133, T1078.003, T1021.004
- Data sources: linux_secure, syslog, sshd authentication logs
- Severity: high
- Confidence: high
Splunk SPL
index=linux (sourcetype=linux_secure OR sourcetype=syslog) earliest=-24h "sshd" "Accepted password for" ```*sshole TL-2026-5338: musl crypt() returns * for 257-1024 byte passwords, so sshd without PAM accepts password login for locked accounts``` | rex "Accepted password for (?<auth_user>\S+) from (?<src_ip>\S+) port (?<src_port>\d+)" | where in(auth_user,"root","alpine","admin","deploy","ubuntu","ec2-user") | eval src_scope=if(cidrmatch("10.0.0.0/8",src_ip) OR cidrmatch("172.16.0.0/12",src_ip) OR cidrmatch("192.168.0.0/16",src_ip),"internal","external") | stats count min(_time) as first_seen max(_time) as last_seen values(src_scope) as src_scope by host, auth_user, src_ip | convert ctime(first_seen) ctime(last_seen)Microsoft KQL
// *sshole TL-2026-5338: password login to locked/key-only accounts on musl sshd without PAM (T1190, T1078.003)
Syslog
| where TimeGenerated > ago(24h)
| where ProcessName =~ "sshd" and SyslogMessage startswith "Accepted password for"
| parse SyslogMessage with "Accepted password for " AuthUser " from " SrcIp " port " SrcPort " " *
| where AuthUser in~ ("root", "alpine", "admin", "deploy", "ubuntu", "ec2-user")
| extend SrcScope = iff(ipv4_is_private(SrcIp), "internal", "external")
| summarize Logins = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by Computer, AuthUser, SrcIp, SrcScope
| order by LastSeen descSigma
title: OpenSSH musl sshole Password Login to Privileged Account
id: 7c1b2f64-5d3a-4e8b-9a41-2f6c0d8e1a01
status: experimental
description: Detects successful sshd password authentication for root or key-only default accounts. On musl libc hosts running OpenSSH before 10.6p2 without PAM, an over-long password of 257 to 1024 characters bypasses authentication for accounts whose password field is an asterisk (sshole, TL-2026-5338).
references:
- https://sshhole.com/
- https://www.openssh.org/releasenotes.html#10.6p2
- https://www.theregister.com/security/2026/11/05/get-root-on-a-musl-linux-system-by-slamming-it-with-an-overly-long-password/5307910
author: AII-Detector — ThreadLinqs Intelligence
date: 2026/11/05
tags:
- attack.initial-access
- attack.t1190
- attack.t1133
- attack.t1078.003
- attack.lateral-movement
- attack.t1021.004
logsource:
product: linux
service: sshd
detection:
keywords:
- 'Accepted password for root from'
- 'Accepted password for alpine from'
- 'Accepted password for admin from'
- 'Accepted password for deploy from'
- 'Accepted password for ubuntu from'
- 'Accepted password for ec2-user from'
condition: keywords
falsepositives:
- Administrators legitimately using password login for root on hosts where root has a real password hash
- Break-glass or console-recovery logins from a management network
level: highKnown false positives:
- Administrators legitimately using password login for root on hosts where root has a real password hash
- Break-glass or console-recovery logins from a management network
Tuning notes: Adjust the account list to the key-only or locked accounts in your estate. Restrict to hosts inventoried as musl (Alpine, OpenWrt, Buildroot, Yocto) running OpenSSH older than 10.6p2 without PAM. Exclude known bastion/management source ranges. Alpine logs to /var/log/messages, so confirm the sourcetype your forwarder assigns (syslog vs linux_secure). Remove the alert once PasswordAuthentication is disabled or openssh 10.6p2+ is deployed.
- *sshole [indicator] musl Password Login to Locked/Key-Only Account — Exploitation (KQL) · unlock with TL Creds
- *sshole Root Password Login Followed by Post-Exploitation Activity — Post-Exploitation (KQL) · unlock with TL Creds
- *sshole Source Sweeping Hosts With Privileged Password Logins or Failures — Lateral Movement (KQL) · unlock with TL Creds
- *sshole [indicator] musl Password Login to Locked/Key-Only Account — Exploitation (Sigma) · unlock with TL Creds
- *sshole Root Password Login Followed by Post-Exploitation Activity — Post-Exploitation (Sigma) · unlock with TL Creds
- *sshole Source Sweeping Hosts With Privileged Password Logins or Failures — Lateral Movement (Sigma) · unlock with TL Creds
- *sshole Root Password Login Followed by Post-Exploitation Activity — Post-Exploitation (SPL) · unlock with TL Creds
- *sshole Source Sweeping Hosts With Privileged Password Logins or Failures — Lateral Movement (SPL) · unlock with TL Creds
Indicators of compromise for OpenSSH musl password bypass
As of 2026-11-05, Threadlinqs Intelligence tracks 28 indicators of compromise for TL-2026-5338.
How OpenSSH musl password bypass works
*sshole is an authentication bypass arising from the chaining of three behaviors. First, musl libc's crypt() returns the string "*" instead of NULL when it cannot compute a hash (behavior dating to August 2012, musl commit b3c4cc12). Second, musl's SHA-512 crypt implementation caps passwords at 256 bytes (added 2012-08-29), so a longer password makes crypt() fail and return "*". Third, since the July 2016 fix for the OpenSSH user-enumeration timing attack (CVE-2016-6210), sshd hashes the supplied password for accounts with no usable hash using a salt borrowed from another account, and then compares the crypt() output against the stored password field. Accounts locked for password login conventionally carry an asterisk in that field (a convention dating to 1980).
When an attacker supplies a password between 257 and 1,024 characters, musl's crypt() fails and returns "*", which matches the "*" stored for the target account, so authentication succeeds without knowing any password. Accounts normally protected from password login, such as root, key-only deployment users, and LDAP-backed users, can therefore be logged into. Exploitation requires all of: a musl libc system (not glibc), sshd built or run without PAM (UsePAM no, the Alpine default), PasswordAuthentication enabled (the default), at least one other account with a valid password hash (the source of the borrowed salt), and a target account with an asterisk in its password field. Alpine Linux is the primary affected distribution, notably its official AWS and Azure cloud images with the default alpine user and its Docker images; other musl-based environments such as OpenWrt, Buildroot and Yocto-based embedded systems are also exposed. Alpine 3.16 (2022) changed the root password field from "!" to "*", which made root reachable. Debian, Ubuntu, Fedora and other glibc systems, PAM-enabled builds, OpenBSD and Dropbear are not affected.
The root cause lies in musl's crypt() behavior, but OpenSSH 10.6p2, released 2026-11-05, implements a workaround inside sshd; the release note says it avoids a password authentication bypass exploitable through sshd(8) that affects some Linux systems built and run with PAM support disabled. The issue was found via fuzzing after an OpenSSH security review on 2026-10-30 patched nearby code. Mitigation before patching is to set PasswordAuthentication no and restart sshd. The researcher site sshhole.com offers a check for whether a system was compromised, and recommends auditing access logs for unauthorized sessions. No CVE ID or CVSS score has been stated in the sources reviewed; severity is an analyst estimate. The Register reports no documented exploitation of vulnerable systems.
MITRE ATT&CK techniques by tactic:
Lateral Movement
T1021.004 Remote Services: SSH
Initial Access
T1078.003 Valid Accounts: Local Accounts; T1133 External Remote Services; T1190 Exploit Public-Facing Application
Privilege Escalation
T1078.003 Valid Accounts: Local Accounts
Defense Evasion
T1078.003 Valid Accounts: Local Accounts
Persistence
T1078.003 Valid Accounts: Local Accounts; T1098.004 Account Manipulation: SSH Authorized Keys; T1136.001 Create Account: Local Account
Remediation for OpenSSH musl password bypass
Patches
- Upgrade to OpenSSH 10.6p2 or newer (on Alpine: apk upgrade openssh)
Immediate actions
- Set PasswordAuthentication no in sshd_config and restart sshd on musl-based hosts
- Run the researcher's compromise check from sshhole.com on exposed Alpine/musl hosts
- Review sshd authentication logs for successful password logins to accounts with an asterisk password field (e.g. root) and for unusually long password attempts
Workarounds
- Disable SSH password authentication (PasswordAuthentication no) and restart the SSH daemon
Longer-term hardening
- Prefer key-based SSH authentication and keep password authentication disabled on musl-based systems
- Audit /etc/shadow for accounts with an asterisk password field on musl systems running OpenSSH without PAM
- Rebuild base images (Alpine cloud and container images) with patched OpenSSH
Affected and fixed versions
- OpenBSD / OpenSSH — OpenSSH (portable) on musl libc without PAM
Vulnerable versions: prior to 10.6p2
Fixed in: 10.6p2 - Alpine Linux — Alpine Linux (musl libc) including cloud and Docker images
Vulnerable versions: OpenSSH packages prior to 10.6p2
Fixed in: openssh 10.6p2 or newer - OpenWrt / Buildroot / Yocto — musl-based embedded Linux builds running OpenSSH without PAM
Vulnerable versions: OpenSSH prior to 10.6p2
Fixed in: OpenSSH 10.6p2 or newer
Timeline of OpenSSH musl password bypass
Last updated · 2 updates · revalidated 2× · latest source
- The asterisk in the password field is introduced as the BSD Unix "no login" marker (credited by The Register to Bill Joy); year per the researcher's timeline.
- locked-ioc-20 (commit b3c4cc12, August 2012) makes crypt() return "*" instead of NULL when it fails to compute a hash.
- musl adds a 256-byte password cap to its SHA-512 crypt implementation, so longer passwords make crypt() fail.
- locked-ioc-24's fix for the CVE-2016-6210 user-enumeration timing attack (July 2016) makes sshd hash passwords for accounts without a usable hash using a salt borrowed from another account.
- NVD publishes CVE-2016-6210 (locked-ioc-24 timing-based username enumeration), the origin of the salt-borrowing logic.
- locked-ioc-18 3.16 (2022, exact date not stated) changes the root password field from "!" to "*".
- locked-ioc-24 10.6 is released with several security hardening changes (LZ77 compression disabled, stricter SFTP path and username validation).
- An locked-ioc-24 security review patches code adjacent to the vulnerable salt-selection logic, per the researcher's timeline.
- NVD record for CVE-2026-123158 published (CVSS 3.1 8.1, CWE-394, status Received); earlier sources had stated no CVE was assigned.
- locked-ioc-18 publishes its advisory and fixed locked-ioc-24 packages for branches 3.16 through edge, plus point releases 3.21.10, 3.22.8, 3.23.8 and 3.24.4.
- Ozgun Kultekin (locked-ioc-22), who used AI agents running about 17,600 authentication tests, is credited with reporting the flaw to locked-ioc-24 and locked-ioc-26.
- locked-ioc-26 fixed locked-ioc-24 packages identified: 10.6_p2-r0 (edge), 10.3_p1-r2 (3.24), 10.2_p1-r1 (3.23), 10.0_p1-r11 (3.22), 9.9_p2-r1 (3.21), 9.7_p1-r6 (3.20).
- Orca Research Pod publishes its own *sshole write-up, including reproduction methodology and log-hunting guidance for 'locked-ioc-12' on locked/key-only accounts.
- *sshole is publicly disclosed at sshhole.com and reported by The Register, which notes no documented exploitation of vulnerable systems.
- locked-ioc-24 10.6p2 is released, avoiding a password authentication bypass in sshd on Linux systems built and run without PAM; the issue is credited to locked-ioc-17 of locked-ioc-22.
Update history
- 2026-11-05 — locked-ioc-24 'sshole' password authentication bypass on musl-based Linux without PAM (CVE-2026-123158): What changed CVSS score unset - 8.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, per NVD). Severity (HIGH), exploitability (POC_PUBLIC) and status (PATCHED) are unchanged. The trigger report lists status MONITORING, which would be a downg
- 2026-11-05 — *sshole: locked-ioc-24 Password Authentication Bypass Gives Attackers Root on locked-ioc-18 and Other locked-ioc-20 Systems (no CVE assigned): What changed No severity, exploitability or status change. Newer report restates HIGH / POC_PUBLIC; its status ACTIVE refers to the report, not an escalation, and the existing PATCHED status is kept. New indicators (11) Indicator values are
Sources cited for OpenSSH musl password bypass
- OpenSSH 10.6p2 release notes entry openssh.org · Advisory · 2026-11-05
- CVE-2016-6210: OpenSSH user enumeration timing attack (origin of the borrowed-salt workaround) NVD (NIST) · Advisory · 2016-07-01
- *sshole - OpenSSH musl password authentication bypass (researcher site) sshhole.com · Research · 2026-11-05
- OpenSSH Release Notes (10.6p2 and 10.6) openssh.org · Vendor report · 2026-11-05
- sshhole.com compromise check sshhole.com · Research · 2026-11-05
- Alpine Linux security tracker security.alpinelinux.org · Vendor report · 2026-11-05
- Get root on a musl Linux system by slamming it with an overly long password (The Register) The Register · News · 2026-11-05
Further reading
Drafted by the Threadlinqs research pipeline from 7 sources; published ; last updated .