---
title: "Ten-Year-Old OpenSSH Bug Lets a 257-Character Password Open Alpine Linux"
description: "A 2012 musl quirk and a 2016 OpenSSH timing fix collided to turn any long password into a master key"
author: "Luis Goa"
published: 2026-11-09T19:41:34Z
modified: 2026-11-09T23:17:31Z
url: https://rews.cc/a/ten-year-old-openssh-bug-lets-a-257-character-password-open--c9ff64
language: en
tags: ["cybersecurity", "open-source", "linux", "ssh", "vulnerability", "tech"]
publisher: "Rews (https://rews.cc)"
---

# Ten-Year-Old OpenSSH Bug Lets a 257-Character Password Open Alpine Linux

*A 2012 musl quirk and a 2016 OpenSSH timing fix collided to turn any long password into a master key*

By Luis Goa · November 9, 2026 · https://rews.cc/a/ten-year-old-openssh-bug-lets-a-257-character-password-open--c9ff64

## In brief

- CVE-2026-123158 (“sshole”) lets a 257–1024 byte password bypass SSH auth on musl Linux without PAM, CVSS 8.1
- Bug stems from a 2012 musl crypt() quirk colliding with a 2016 OpenSSH timing-attack fix, both individually correct
- Researcher Özgün Kültekin of Wakefield found it via ~17,600 automated login tests; OpenSSH fixed it Nov 5 in 10.6p2
- Previdian logged 20 exploitation attempts from 13 IPs in 9 countries by Nov 8; watchTowr saw botnets and crypto miners first
- CISA added the bug to its KEV catalog on Nov 9 with a Nov 12 deadline for US federal agencies

Send an SSH server more than 256 characters as a password, and on the right configuration it will let you in as root, with no password at all. That is CVE-2026-123158, nicknamed “sshole,” rated 8.1 out of 10 on the CVSS 3.1 scale and tracked by Red Hat as [bug 2567690](https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2026-123158). The exploitable range is precise: a password of 257 to 1,024 bytes, against an account whose /etc/shadow entry is a single asterisk. OpenSSH fixed it on November 5 in version [10.6p2](https://www.openssh.org/txt/release-10.6p2). By November 9, security firm [Previdian](https://arstechnica.com/security/2026/11/vulnerability-that-lets-hackers-ssh-into-linux-devices-is-under-active-exploitation/) had logged 20 exploitation attempts from 13 unique IP addresses in 9 countries, and the US Cybersecurity and Infrastructure Security Agency had added the bug to its [Known Exploited Vulnerabilities catalog](https://www.cisa.gov/news-events/alerts/2026/11/09/cisa-adds-four-known-exploited-vulnerabilities-catalog), giving federal agencies until November 12 to patch.

## Two sentinel values, ten years apart

The bug is a collision between two pieces of code that were each individually correct, written a decade apart, by people who had never heard of each other. musl, the small C library used by Alpine Linux and other lightweight distributions in place of glibc, changed its crypt() function in 2012. Before that change, a failed hash computation returned NULL; after it, per [commit b3c4cc12](https://sshhole.com/), musl returns the string “\*“ instead, on the theory that an unmatchable sentinel is safer than a null pointer a caller might mishandle. Twenty days later, a second musl commit (88bf5a8a) added SHA-512 password hashing with a hard cap: no key longer than 256 bytes, to stop an attacker from burning CPU with an absurdly long password. Feed crypt() a 257-byte password and it fails that cap check, and per the first commit, failure now means returning “\*“.

Separately, Unix has stored “\*“ in /etc/shadow for password-less accounts since 3BSD in 1980, because a literal asterisk can never be a valid hash output and so can never match. Both conventions are individually sound. The problem is that OpenSSH, since a 2016 fix for [CVE-2016-6210](https://www.openssh.org/txt/release-10.6p2), a username-enumeration bug, hashes every submitted password against some salt even when the target account has no real hash to check against, specifically so that guessing a nonexistent username takes the same amount of time as guessing a real one. That salt-borrowing call is what reaches musl’s crypt() with an attacker-controlled, over-length password, and gets back “*“ as the result. sshd then compares that “*“ to the “\*“ already sitting in /etc/shadow, finds a match, and lets the connection through. Neither side intended to produce a password hash. Both produced the identical punctuation mark.

**How a long password becomes a master key** The collision between musl's 2012 crypt() fix and OpenSSH's 2016 timing fix

| From | To | How |
| --- | --- | --- |
| musl 2012: failures return "\*" *(commit b3c4cc12)* | sshd calls musl crypt() on the password |  |
| musl 2012: SHA-512 capped at 256 bytes *(commit 88bf5a8a, 20 days later)* | sshd calls musl crypt() on the password |  |
| OpenSSH 2016 fix for CVE-2016-6210 *(sshd hashes anyway to equalise timing)* | sshd calls musl crypt() on the password | forces the call |
| Attacker sends a 257–1024-byte password | sshd calls musl crypt() on the password |  |
| sshd calls musl crypt() on the password | crypt() exceeds cap, returns "\*" |  |
| crypt() exceeds cap, returns "\*" | "\*" equals "\*": login accepted |  |
| /etc/shadow already stores "\*" *(convention since 3BSD, 1980)* | "\*" equals "\*": login accepted |  |
| "\*" equals "\*": login accepted | Attacker gets a shell, often as root |  |

Based on [sshhole.com and the OpenSSH 10.6p2 release notes](https://sshhole.com/)

The bypass only fires under a specific set of conditions, which is why it sat unnoticed for a decade: sshd must be linked against musl, not glibc; PAM, the pluggable-authentication framework most distributions route logins through, must be disabled, which is Alpine’s default for its openssh-server package but not the default everywhere; password authentication must be turned on, which it is by default; and the target account’s shadow field must already be “\*“. OpenSSH’s own test suite runs mainly on OpenBSD and glibc and never exercises musl. musl’s own maintainers don’t test sshd. Distributions that route authentication through PAM never reach the vulnerable crypt() call at all, since PAM’s own backends don’t share this quirk. Alpine, built specifically to be small, skips PAM by default, which is exactly the one configuration where all the pieces line up.

Özgün Kültekin, a researcher at the security firm Wakefield, found the bug, according to the OpenSSH 10.6p2 release notes quoted in a disclosure email that developer [Jan Schaumann posted](https://www.openwall.com/lists/oss-security/2026/11/05/3) to the oss-security mailing list on November 5. Kültekin’s own technical writeup, [published at sshhole.com](https://sshhole.com/), says he built sshd across every combination of glibc, musl, PAM and no-PAM he could construct and threw roughly 17,600 unusual login attempts at the resulting builds, using what he describes as “agent swarms” of AI systems to generate and run the tests. Only the musl-without-PAM build accepted logins it should have refused. Kültekin’s writeup also notes an irony: an unrelated OpenSSH patch landed on October 30, 2026, fixing a different bug in the same salt-generation function, four lines away from the vulnerable code, four days before he found it.

## Who is exposed, and who got there first

Alpine’s official cloud images carry the clearest exposure. On AWS and Azure builds from version 3.18.11 through 3.24.3, the default “alpine” user has no shadow password and runs doas, Alpine’s sudo equivalent, without one either, which the writeup at sshhole.com calls an effective root compromise once any other account on the box has a real password hash to pair it with. Beyond Alpine, the same conditions can occur on OpenWrt, Buildroot and Yocto-based systems, and on any musl-linked container image that runs its own sshd rather than relying on the host. [Testing of public Docker Hub images](https://www.helpnetsecurity.com/2026/11/06/openssh-sshole-cve-2026-123158-exploitation/) found that widely used ones, including Gitea, Gogs, the Jenkins SSH agent and the linuxserver openssh-server image, ship with password logins off by default, closing the hole unless an operator explicitly re-enables them.

Exploitation moved fast once the OpenSSH advisory and Kültekin’s writeup made the mechanism public. [watchTowr Intel reported on November 6](https://x.com/watchtowrcyber/status/2118636513739317525) that it was already seeing the bug used by botnets and cryptocurrency miners, the usual first wave for any newly disclosed, trivially scriptable bug, since mining and botnet recruitment monetize blind scanning without needing a specific target. Previdian’s telemetry tells a story that grew with the observation window: founder Ryan Dewhurst told Help Net Security on November 6 that the firm’s first attempt arrived under nine hours after the CVE’s publication, traced at that point to a single sensor and a single Japan-based IP address, 89.116.89.18, running reconnaissance commands like id, uname and hostname over non-interactive sessions. By the time Ars Technica checked in on November 9, Previdian’s count across its wider sensor network had grown to 20 attempts from 13 distinct IPs across 9 countries, collected between November 6 and 8 — the same underlying campaign, counted over three more days and a larger set of sensors, not a contradiction so much as a wider net.

**Previdian's exploitation count grew with its observation window** Same campaign, measured at two points after disclosure

| Report date | Attempts observed | Unique attacker IPs | Countries |
| --- | --- | --- | --- |
| Nov 6, via Help Net Security | 8 | 1 | 1 (Japan) |
| Nov 9, via Ars Technica | 20 | 13 | 9 |

Source: [Previdian telemetry](https://arstechnica.com/security/2026/11/vulnerability-that-lets-hackers-ssh-into-linux-devices-is-under-active-exploitation/)

Security firm GreyNoise separately clocked the first confirmed successful exploitation in the wild at 00:46 UTC on November 7, roughly 40 hours after OpenSSH shipped the fix, a gap that measures how long a patch can sit unapplied before someone finds the unpatched instance, not how long the bug has existed. The vulnerability itself, by Kültekin’s own dating of the colliding commits, had been live since 2016; the forty-hour number only describes the race between publication and the first observed exploit, a race defenders are losing by design, since any Alpine box exposed to the internet with password login left on is scannable by anyone who has read the same advisory. CISA’s three-day remediation deadline, issued under [Binding Operational Directive 26-04](https://www.cisa.gov/news-events/alerts/2026/11/09/cisa-adds-four-known-exploited-vulnerabilities-catalog), applies only to US federal civilian agencies, though the agency’s advice not to wait applies to anyone running musl without PAM.

The remedy is the one line every advisory repeats: upgrade to OpenSSH 10.6p2, or Alpine’s backported equivalent for branches 3.16 through edge, restart sshd, and if upgrading has to wait, set PasswordAuthentication to no in sshd\_config, which closes the hole regardless of which libc is underneath. Alpine has already shipped patched packages for every supported branch, which is one more data point than the 2019 episode, when CVE-2019-5021 left Alpine’s Docker image with a literally empty root password for three years before anyone noticed, an episode that rhymes with [the earlier asterisk story](https://rews.cc/a/on-alpine-linux-the-asterisk-that-locked-an-account-also-ope-834e1d) about how Alpine’s shadow-file conventions have twice now turned a safety marker into a skeleton key. The open question is the one watchTowr flagged on day one: crypto miners are always first, because they monetize blind scanning without caring what they land on. The move from miners to anyone running a targeted intrusion against a specific Alpine fleet is usually a matter of weeks, not months, and nobody yet has a count for how many internet-facing musl boxes are still unpatched.

## See also

- [CISA Known Exploited Vulnerabilities catalog entry](https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-123158) — cisa.gov · official US government exploitation status and remediation deadline
- [GitHub Security Advisory GHSA-4fcc-vm97-gx3x](https://github.com/advisories/GHSA-4fcc-vm97-gx3x) — github.com · CVE record, CWE classification and affected version ranges
