# SSHole (CVE-2026-123158) - OpenSSH on musl-based Linux oversized password authentication bypass, exploited in the wild

> CVE-2026-123158 ('SSHole' / '*sshole') is an authentication bypass in OpenSSH sshd before 10.6p2 on musl libc systems without PAM (notably Alpine Linux): an oversized password (>256 bytes) authenticates to accounts whose shadow hash is '*'. Exploitation began within hours of the 2026-11-05 disclosure, GreyNoise has observed post-exploitation chains including SSH key implantation and a Python C2 agent ('TAC Agent'), and CISA added the CVE to KEV on 2026-11-09.

- **Published:** 2026-11-10T18:58:14Z
- **Last reviewed:** 2026-11-10T18:58:14Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-5672
- **Card image:** https://intel.threadlinqs.com/og/threat/TL-2026-5672.png
- **ID:** TL-2026-5672
- **Severity:** CRITICAL (CVSS 8.1)
- **Category:** VULNERABILITY
- **Status:** ACTIVE
- **Detections:** 9 (1 shown free below) · **IOCs:** 21 (3 shown free below)
- **CVEs:** CVE-2026-123158

## Description

CVE-2026-123158 is a logic flaw in the interaction between OpenSSH's password authentication and musl libc's crypt(). Accounts that must never accept a password store '*' in the /etc/shadow hash field. Since a 2016 change (to mitigate username enumeration, CVE-2016-6210), when the target account has no usable hash OpenSSH borrows the salt/settings of another account and hashes the supplied password anyway. musl's crypt() refuses SHA-256/SHA-512 inputs longer than 256 bytes and returns the failure string '*', which then string-compares equal to the locked account's stored '*' and sshd accepts the login. NVD describes the condition as any password of 256 to 1024 characters succeeding for some account configurations. The flaw is not memory corruption; it is an unexpected return-value handling issue (CWE-394).

Exploitation conditions: sshd built without PAM (or Alpine openssh-server-pam with UsePAM no), PasswordAuthentication enabled (the OpenSSH default), at least one account with '*' in its password field (root in the Alpine base image when PermitRootLogin permits it, key-only deploy users, directory-service users, or the default 'alpine' user in tiny-cloud images), and at least one other local account with a real $5$/$6$ hash. The attacker must know a valid password-disabled account name. Alpine's default cloud 'alpine' user has passwordless doas, so bypass of that account leads directly to root. Not affected: glibc systems (Debian, Ubuntu, Fedora), PAM-based password authentication, PasswordAuthentication no, accounts with '!' instead of '*', Dropbear, and OpenBSD. Other musl-based platforms named by researchers include OpenWrt, Buildroot, Yocto and many Docker base images. The issue was reported to OpenSSH by Ozgun Kultekin of Wakefield. Fixed in OpenSSH 10.6p2 (2026-11-05); Alpine backported fixes to branches 3.16 through edge.

Exploitation timeline (GreyNoise, UTC): a public exploit appeared on GitHub on 2026-11-05 13:16, about 3 hours before the NVD record was published; GreyNoise tagged the first CVE-specific exploit attempt on 2026-11-05 18:34 and the first successful exploitation on 2026-11-07 00:46. Previdian separately reported eight attempts from 89.116.89.18 beginning under nine hours after CVE publication, including root access on an Alpine honeypot followed by id/uname/hostname reconnaissance. By 2026-11-10 GreyNoise reported 23 confirmed post-exploitation chains from 7 attacker IPs against its sensors, against a background of roughly 41.2M TCP/22 SYN scans and 30.5M SSH connection attempts. Public proof-of-concept repositories exist and defenders are warned that unverified PoCs may contain malware.

Observed post-exploitation (GreyNoise sensor victims): discovery (id, uname, os-release, /etc/passwd, mount/container checks, route and interface enumeration, virtualization checks), credential access attempts (doas cat /etc/shadow, reading root authorized_keys and ssh keys), cloud metadata probing (169.254.169.254, 100.100.100.200), connectivity tests, planting SSH public keys in /root and /home/alpine authorized_keys (comments 'fleet-access' and 'SSHHOLE-HIT'), creating a 'server_manager' account with a passwordless doas rule, and staging a Python runtime plus the 'TAC Agent' implant with an OpenRC init script. GreyNoise groups two intrusions across seven addresses as cluster 'GT10'; no named threat actor is attributed in any source. TAC Agent is a single-file Python 3 (stdlib-only) implant (/opt/py3/tac_agent.py, 89,559 bytes, v0.1.1) that beacons over HTTPS to tac.vpnla.org (Cloudflare Worker, port 8443) with GET /agent/poll every ~150s, supports sysinfo recon, file preview/download/upload, unsigned self-update and arbitrary /bin/sh -c execution, and uses User-Agent TAC-Agent/1.0. Enrollment failed on the first victim and no tasking was observed. Note: Safe Security's 2026-11-06 write-up stated no confirmed exploitation, which predates GreyNoise's observations. BeaconBeagle lookups for 89.116.89.18 and tac.vpnla.org returned HTTP 502 and could not be completed.

## MITRE ATT&CK

- T1595.002 Vulnerability Scanning
- T1190 Exploit Public-Facing Application
- T1078.003 Local Accounts
- T1059.004 Unix Shell
- T1059.006 Python
- T1098.004 SSH Authorized Keys
- T1136.001 Local Account
- T1543 Create or Modify System Process
- T1548 Abuse Elevation Control Mechanism
- T1690 Prevent Command History Logging
- T1003.008 /etc/passwd and /etc/shadow
- T1552.004 Private Keys
- T1552.005 Cloud Instance Metadata API
- T1082 System Information Discovery
- T1033 System Owner/User Discovery
- T1071.001 Web Protocols

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**SSHole CVE-2026-123158 - Password Login Accepted for Passwordless/Key-Only Account (sshd)** (`TL-2026-5672-SPL-001`)

Detects the exploitation signature of CVE-2026-123158 (SSHole) on musl-based Linux (Alpine, OpenWrt, Buildroot): sshd logs 'Accepted password for' an account that normally has no usable password (alpine, root, key-only deploy users, the attacker-created server_manager). The oversized-password (>256 bytes) bypass succeeds only against accounts whose shadow hash is '*', so a password-based success for these accounts is a high-fidelity compromise indicator. Also flags sources matching GreyNoise/Previdian-reported SSHole attacker IPs.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1190, T1078.003
- **Data sources:** linux_syslog (index=linux sourcetype=syslog), sshd authentication logs (/var/log/messages)
- **Severity:** critical
- **Confidence:** high

### Splunk SPL

```spl
index=linux sourcetype=syslog sshd "Accepted password for" earliest=-24h
| rex field=_raw "Accepted password for (?<auth_user>[^ ]+) from (?<src_ip>[0-9.]+) port (?<src_port>[0-9]+)"
| where isnotnull(auth_user) AND in(auth_user,"alpine","root","server_manager")
| eval ioc_match=if(in(src_ip,"89.116.89.18","183.220.91.15","20.255.63.133","20.2.81.241","209.248.50.17","47.80.65.43","152.175.65.88","202.155.94.33","79.116.138.30","196.128.138.201","43.224.227.158","213.86.169.133","31.59.220.26"),"known_sshole_ip","none")
| stats count as logins min(_time) as first_seen max(_time) as last_seen values(auth_user) as auth_users values(ioc_match) as ioc_match by host src_ip
| convert ctime(first_seen) ctime(last_seen)
| table host src_ip auth_users logins ioc_match first_seen last_seen
```

### Microsoft KQL

```kql
Syslog
| where TimeGenerated > ago(24h)
| where ProcessName =~ 'sshd' and SyslogMessage has 'Accepted password for'
| extend AuthUser = extract(@'Accepted password for ([^ ]+) from', 1, SyslogMessage), SrcIp = extract(@'from ([0-9.]+) port', 1, SyslogMessage)
| where AuthUser in~ ('alpine', 'root', 'server_manager')
| extend KnownAttackerIp = SrcIp in ('89.116.89.18','183.220.91.15','20.255.63.133','20.2.81.241','209.248.50.17','47.80.65.43','152.175.65.88','202.155.94.33','79.116.138.30','196.128.138.201','43.224.227.158','213.86.169.133','31.59.220.26')
| summarize Logins = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Users = make_set(AuthUser) by Computer, SrcIp, KnownAttackerIp
| project Computer, SrcIp, Users, Logins, KnownAttackerIp, FirstSeen, LastSeen
```

### Sigma

```yaml
title: SSHole CVE-2026-123158 - Password Login Accepted for Passwordless Account
id: 3f7a9c1e-5b2d-4e68-9a41-7c0d8e2b6f11
status: experimental
description: Detects sshd accepting a password login for accounts that normally have no usable password (alpine, root, server_manager), the signature of the CVE-2026-123158 SSHole oversized-password authentication bypass on musl-based Linux.
references:
    - https://nvd.nist.gov/vuln/detail/CVE-2026-123158
    - https://www.greynoise.io/blog/global-event-sshole-cve-2026-123158-live-activity-report
author: Threadlinqs Team
date: 2026-11-10
tags:
    - attack.initial-access
    - attack.t1190
    - attack.t1078.003
    - cve.2026.123158
logsource:
    product: linux
    service: sshd
detection:
    keywords:
        - 'Accepted password for alpine from'
        - 'Accepted password for root from'
        - 'Accepted password for server_manager from'
    condition: keywords
falsepositives:
    - Administrators who legitimately set a password on root or alpine and log in with it
    - Break-glass console-style password access on lab systems
level: critical
```

**Known false positives:**

- Accounts (root/alpine) that intentionally have a real password and use password login
- Legacy automation that authenticates to root with a password

**Tuning notes:** Extend the account list with your key-only/service/deploy users and directory-service users that carry '*' in /etc/shadow. Add known-good admin source CIDRs to an exclusion. Any hit on a host running OpenSSH < 10.6p2 without PAM should be treated as compromise. Adjust the index/sourcetype to where Alpine /var/log/messages is ingested.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- SSHole CVE-2026-123158 - sshd Activity from Known SSHole Attacker Infrastructure (locked: unlock with TL Creds)
- SSHole Post-Exploitation - server_manager Account Creation with Passwordless doas Rule (locked: unlock with TL Creds)
- SSHole C2 - TAC Agent Python Implant Files and OpenRC Persistence (locked: unlock with TL Creds)
- SSHole CVE-2026-123158 - Internet-Sourced Password Login to Default Cloud 'alpine' User (locked: unlock with TL Creds)
- SSHole Post-Exploitation - Credential Access and Discovery (shadow, root SSH keys, cloud metadata, id/uname) (locked: unlock with TL Creds)
- SSHole C2 - TAC Agent Spawning Shell Commands (/bin/sh -c) from Python Implant (locked: unlock with TL Creds)
- SSHole Post-Exploitation - Attacker SSH Key Planted in authorized_keys (fleet-access / SSHHOLE-HIT) (locked: unlock with TL Creds)
- SSHole C2 - TAC Agent Beacon to [indicator] (TAC-Agent/1.0, /agent/poll ~150s) (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sample indicators (3 of 21)

Defanged, TLP:CLEAR.

- IP address: `89.116.89[.]18`
- Domain: `tac[.]vpnla[.]org`
- File hash: `55e6384f6d1648be9b48fb899e46623e9c05eb0df2cbf95f6701680d4e7cbc2a`

Full set of 21 indicators unlocks with TL Creds: https://threadlinqs.com/tl-creds

## Sources

- [GreyNoise: Global Event: SSHole (CVE-2026-123158) Live Activity Report](https://www.greynoise.io/blog/global-event-sshole-cve-2026-123158-live-activity-report)
- [GreyNoise SSHole live event tracker](https://sshole.events.greynoise.io/)
- [NVD: CVE-2026-123158](https://nvd.nist.gov/vuln/detail/CVE-2026-123158)
- [Alpine Linux security advisory: OpenSSH password authentication bypass](https://alpinelinux.org/posts/2026-11-05-openssh-password-authentication-bypass/)
- [OpenSSH 10.6p2 release notes](https://www.openssh.org/releasenotes.html#10.6p2)
- [OpenSSH portable fix commit](https://github.com/openssh/openssh-portable/commit/4353fdc43ef646c43a8dda7025cc1a898caf1482)
- [CISA Known Exploited Vulnerabilities Catalog entry](https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-123158)
- [Help Net Security: OpenSSH flaw exploited in the wild just hours after disclosure](https://www.helpnetsecurity.com/2026/11/06/openssh-sshole-cve-2026-123158-exploitation/)
- [OX Security: OpenSSH Password Authentication Bypass on Alpine Linux (*sshole)](https://www.ox.security/blog/openssh-authentication-bypass-cve-2026-123158/)
- [Horizon3.ai: CVE-2026-123158 OpenSSH musl Bypass (*sshole)](https://horizon3.ai/attack-research/vulnerabilities/cve-2026-123158/)
- [BleepingComputer: OpenSSH flaw lets attackers log into password-disabled Linux accounts](https://www.bleepingcomputer.com/news/security/openssh-flaw-lets-attackers-log-into-password-disabled-linux-accounts/)
- [The Hacker News: Hackers exploited OpenSSH SSHole flaw](https://thehackernews.com/2026/11/hackers-exploited-openssh-sshole-flaw.html)
- [sshhole.com research site](https://sshhole.com/)
- [oss-security: CVE-2026-123158 posting](http://www.openwall.com/lists/oss-security/2026/11/09/27)
- [Safe Security: SSHole high-severity OpenSSH vulnerability](https://safe.security/resources/blog/sshole-high-severity-openssh-vulnerability-turns-disabled-passwords-into-unauthorized-access/)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-5672
