top of page

OpenSSH Password Authentication Bypass: Hunt Key-Only Logins

Writer: Inception Security
Inception Security
4 minutes ago
7 min read
Key-only intent versus password acceptance on a qualifying musl Linux non-PAM account; preserve logs, patch, restart sshd and review linked actions.

What this means for your clients: If you manage an affected server for a client, an account meant to require a key could still accept a password.


Your key-only account should not accept a password. Finding a public key in authorized_keys tells you how someone intended to administer an account. The effective sshd policy determines whether another authentication method remains available. For a company, that difference can expose deployment identities and the management access used to maintain production.


How the password check fails


The OpenSSH password authentication bypass affects a specific authentication path. The OpenSSH release and MITRE CNA record describe CVE-2026-123158 on unpatched portable OpenSSH before 10.6p2, on Linux using musl without PAM in this password-check path. This does not break public-key cryptography or SSH transport encryption, and it does not affect OpenBSD itself.


In Alpine's explanation, a password-check error returns a marker that can equal the target account's literal * password field. Another local account must have a SHA-256 or SHA-512 password hash, and effective PasswordAuthentication must permit passwords. A literal ! locked field and an empty field are different account states. Keep those distinctions without copying credential material into the investigation.


Alpine Linux's default openssh-server lacks PAM. Its openssh-server-pam package remains exposed with UsePAM no; UsePAM yes on that variant is listed as unaffected. Adding a PAM setting to a binary without PAM does not supply protection. Account eligibility, AuthenticationMethods, Allow/Deny restrictions and per-source or per-user Match/Include rules still determine access. Default PermitRootLogin prohibit-password protects direct root password login. An eligible non-root account might separately have doas privileges.


An Alpine container without running sshd has no entry through this service. Reachability matters, and cloud-init can disable password authentication. Do not infer exposure for every directory identity or cloud image from its operating-system label.


The key file can stay unchanged while the password path stays open, so compare the account owner's provisioning record with the sshd policy that applied to this user and connection.


What access could mean


On November 6, Ryan Dewhurst told Help Net Security that Previdian confirmed successful root access on its Alpine honeypot. That establishes a honeypot observation. Previdian's November 8 snapshot reports 19 attempts across four sensors, first observed November 6 and last observed November 7. Previdian explicitly says attempts do not establish vulnerability or success. These reports establish no customer victim count or exact exploitation-start time.


A service identity may reach deployment files or credentials without being root. Establish its permissions, then investigate actual privilege use and changes. An upgrade cannot remove an added key or explain what an earlier session accessed.


Replace the running vulnerable service


Preserve authentication logs, configuration, account-policy history, package records and daemon restart evidence before cleanup. Upstream 10.6p2 avoids the failure in sshd; distro backports carry the fix in lower-looking Alpine versions. Use branch package ordering rather than a banner comparison.


Alpine branch

Fixed openssh package

edge

10.6_p2-r0

3.24

10.3_p1-r2

3.23

10.2_p1-r1

3.22

10.0_p1-r11

3.21

9.9_p2-r1

3.20

9.7_p1-r6

3.19

9.6_p1-r3

3.18

9.3_p2-r4

3.17

9.1_p1-r7

3.16

9.0_p1-r6


Alpine releases 3.21.10, 3.22.8, 3.23.8 and 3.24.4 include the fix. Emergency packages for 3.21 and older do not restore normal support. Update the relevant package and restart sshd; Alpine specifies rc-service sshd restart. If delayed, disable PasswordAuthentication effectively and restart. Validate configuration and applicable Match/Include contexts first. Confirm key and recovery access, keep an administrator session open, and test a fresh legitimate login before closing it.


Establish the evidence before hunting


These reference hunts have not been run against a live environment. They support manual investigation, not automatic inventory correlation or novelty detection. Replace uppercase placeholders with verified fields and escaped values.


Prepare the evidence


Identify each collector, integration/version and retention period for auth, inventory/history and available Linux audit/process/file sources. Repeat blocks per deployed source.


Tenant isolation requires authoritative tenant and stable asset IDs, not hostnames. Preserve account namespace, case and rename history. Compare policy using tenant, asset, account, evidence reference and inclusive-start/exclusive-end validity. Conflicting, overlapping or missing history stays UNKNOWN. Keep event identity separate from inventory annotations.


Before each search, check its fields are present, single-valued and correctly typed. Resolve gaps first; filters do not enforce these checks. Analyzed text or multivalue fields can mislead or miss matches. Replace illustrative lowercase accepted/password with exact, case-matched parser values verified against raw records.


Platform

Verify before substituting fields and selecting records

Splunk

Map YOUR_INDEX/YOUR_SOURCE_TYPE and extracted user/src/result/method against _raw. CIM does not guarantee method. Verify _time as event time; quote dotted fields in where and encompass the interval with native selectors.

Elastic

Use the actual system/auth or custom data view. Map event.original/message, source.ip, user.name and stable asset. Require scalar keyword identities/method/result, an IP client and one date @timestamp. Set the global picker to encompass the interval, with UTC display.

CrowdStrike

Select imported auth syslog in the actual repository/view; endpoint deployment does not imply ingestion. Verify @rawstring, @timestamp and its ingestion-time fallback. Select the full interval. Linux process/file coverage depends on agent/platform/policy.

Microsoft KQL

Use deployed Sentinel Syslog or a Linux evidence table. Map SyslogMessage, EventTime and required aliases; substitute other event-time columns. SecurityEvent/DeviceLogonEvents do not guarantee Alpine evidence. Set the TimeGenerated picker to include the TimeGenerated value of every record whose EventTime falls in the interval.


Preserve original messages/records, source address/port, record IDs, hostname aliases, collector and original/ingestion timestamps with timezone. Check forwarder conversion. Historical backfill can rewrite TimeGenerated or other selection clocks. Validate retention, exports and jobs without truncation.


Set the interval and follow a candidate


Bound

UTC query value

America/Phoenix (MST)

Acquisition start, inclusive

2026-10-09T16:42:00Z

October 9, 9:42 AM

Triage start, inclusive

2026-11-05T07:00:00Z

November 5, midnight

End, exclusive

2026-11-08T16:42:00Z

November 8, 9:42 AM


November 5 is an analyst floor, not the exploitation start; preserve older evidence. Move the end bound to search time. Update ISO/MST times, Splunk epoch seconds (selectors and filters) and CrowdStrike epoch milliseconds to match. Replace the illustrative November 8, 9:30 AM MST seed (2026-11-08T16:30:00Z) with an actual accepted session. End follow-on searches at min(seed + 1 hour, your end bound). This right-censored example's incomplete hour is unreviewed, not quiet.


Coverage test: reconcile raw records, then retrieve the interval


Acquire raw evidence and collector/rejection records independently before any time or event-class filter. Reconcile every raw record against ingestion and extraction, retaining missing times, method, user, host and unparsed records separately. Inventory silent hosts and collectors independently; explicitly account for unavailable endpoint families even if omitted from collection. Then inspect these interval results for auth extraction and available audit/process/file evidence. Counts after filtering cannot establish completeness.


Splunk


index=YOUR_INDEX sourcetype=YOUR_SOURCE_TYPE earliest=1791564120 latest=1794156120
| where _time >= 1791564120 AND _time < 1794156120
| where TENANT_FIELD="PIVOT_TENANT"

Elastic


@timestamp >= "2026-10-09T16:42:00Z" AND @timestamp < "2026-11-08T16:42:00Z"
AND TENANT_FIELD: "PIVOT_TENANT"

CrowdStrike Falcon CQL


TENANT_FIELD="PIVOT_TENANT"
| test(@timestamp >= 1791564120000)
| test(@timestamp < 1794156120000)

Microsoft KQL


YOUR_SOURCE
| where EventTime >= datetime(2026-10-09T16:42:00Z) and EventTime < datetime(2026-11-08T16:42:00Z)
| where TENANT_FIELD == "PIVOT_TENANT"

Keep the reconciliation ledger outside the filtered search. Record expected originals, matches, unexplained losses and extra copies per source. Check timestamp fallback and parsing against raw text. Preserve originals when reconciling retries, without merging separate logins.


Hunt 1: password acceptance against historical key-only intent


Retrieve accepted password logins for each exact identity from the raw-first inventory. Check contemporaneous intent, account state and effective configuration. Hold unknown-policy and missing-field records for separate review. Current inventory cannot prove historical policy. Acceptance is a lead, not proof this CVE was used.


Splunk


index=YOUR_INDEX sourcetype=YOUR_SOURCE_TYPE earliest=1793862000 latest=1794156120
| where _time >= 1793862000 AND _time < 1794156120
| where TENANT_FIELD="PIVOT_TENANT" AND ASSET_FIELD="PIVOT_ASSET" AND ACCOUNT_FIELD="PIVOT_ACCOUNT" AND RESULT_FIELD="accepted" AND METHOD_FIELD="password"

Elastic


@timestamp >= "2026-11-05T07:00:00Z" AND @timestamp < "2026-11-08T16:42:00Z"
AND TENANT_FIELD: "PIVOT_TENANT" AND ASSET_FIELD: "PIVOT_ASSET" AND ACCOUNT_FIELD: "PIVOT_ACCOUNT" AND RESULT_FIELD: "accepted" AND METHOD_FIELD: "password"

CrowdStrike Falcon CQL


TENANT_FIELD="PIVOT_TENANT"
| ASSET_FIELD="PIVOT_ASSET"
| ACCOUNT_FIELD="PIVOT_ACCOUNT"
| RESULT_FIELD="accepted"
| METHOD_FIELD="password"
| test(@timestamp >= 1793862000000)
| test(@timestamp < 1794156120000)

Microsoft KQL


YOUR_SOURCE
| where EventTime >= datetime(2026-11-05T07:00:00Z) and EventTime < datetime(2026-11-08T16:42:00Z)
| where TENANT_FIELD == "PIVOT_TENANT" and ASSET_FIELD == "PIVOT_ASSET" and ACCOUNT_FIELD == "PIVOT_ACCOUNT" and RESULT_FIELD == "accepted" and METHOD_FIELD == "password"

Hunt 2: assess client novelty against a retained baseline


For the same identity, compare successful client sources before November 5 with triage results, or use independently approved administrative-source history. Preserve raw connection context. Missing or truncated baseline makes novelty unknown. NAT, jump hosts, VPN egress and automation can change or share addresses; a new IP does not identify an attacker.


Splunk


index=YOUR_INDEX sourcetype=YOUR_SOURCE_TYPE earliest=1791564120 latest=1794156120
| where _time >= 1791564120 AND _time < 1794156120
| where TENANT_FIELD="PIVOT_TENANT" AND ASSET_FIELD="PIVOT_ASSET" AND ACCOUNT_FIELD="PIVOT_ACCOUNT" AND RESULT_FIELD="accepted"

Elastic


@timestamp >= "2026-10-09T16:42:00Z" AND @timestamp < "2026-11-08T16:42:00Z"
AND TENANT_FIELD: "PIVOT_TENANT" AND ASSET_FIELD: "PIVOT_ASSET" AND ACCOUNT_FIELD: "PIVOT_ACCOUNT" AND RESULT_FIELD: "accepted"

CrowdStrike Falcon CQL


TENANT_FIELD="PIVOT_TENANT"
| ASSET_FIELD="PIVOT_ASSET"
| ACCOUNT_FIELD="PIVOT_ACCOUNT"
| RESULT_FIELD="accepted"
| test(@timestamp >= 1791564120000)
| test(@timestamp < 1794156120000)

Microsoft KQL


YOUR_SOURCE
| where EventTime >= datetime(2026-10-09T16:42:00Z) and EventTime < datetime(2026-11-08T16:42:00Z)
| where TENANT_FIELD == "PIVOT_TENANT" and ASSET_FIELD == "PIVOT_ASSET" and ACCOUNT_FIELD == "PIVOT_ACCOUNT" and RESULT_FIELD == "accepted"

Hunt 3: follow privilege use from an accepted session


Hunts 3 and 4 deliberately repeat this host-window retrieval. Reuse it when source, tenant, asset and bounds match. Review doas, sudo or su evidence with boot-aware audit/session IDs or process ancestry. A reused PID, IP or nearby host/user event cannot prove linkage. Keep unrelated concurrent sessions separate; label timing-only associations weak. Do not invent doas command fields. Privilege use can be legitimate.


Splunk


index=YOUR_INDEX sourcetype=YOUR_SOURCE_TYPE earliest=1794155400 latest=1794156120
| where _time >= 1794155400 AND _time < 1794156120
| where TENANT_FIELD="PIVOT_TENANT" AND ASSET_FIELD="PIVOT_ASSET"

Elastic


@timestamp >= "2026-11-08T16:30:00Z" AND @timestamp < "2026-11-08T16:42:00Z"
AND TENANT_FIELD: "PIVOT_TENANT" AND ASSET_FIELD: "PIVOT_ASSET"

CrowdStrike Falcon CQL


TENANT_FIELD="PIVOT_TENANT"
| ASSET_FIELD="PIVOT_ASSET"
| test(@timestamp >= 1794155400000)
| test(@timestamp < 1794156120000)

Microsoft KQL


YOUR_SOURCE
| where EventTime >= datetime(2026-11-08T16:30:00Z) and EventTime < datetime(2026-11-08T16:42:00Z)
| where TENANT_FIELD == "PIVOT_TENANT" and ASSET_FIELD == "PIVOT_ASSET"

Hunt 4: investigate persistence and authentication changes


Retrieve the same bounded host evidence, including account creation, authorized_keys, sshd configuration and service/credential-policy changes. Read actual audit/file/process records and tie changes to the session. Auth logs cannot supply file contents or all execution; an sshd child or familiar path alone proves little. Preserve distinct sessions and multiplicity; remove transport retries only with record evidence. Normal firewall telemetry cannot reveal encrypted SSH passwords. Never enable password logging or export shadow contents.


Splunk


index=YOUR_INDEX sourcetype=YOUR_SOURCE_TYPE earliest=1794155400 latest=1794156120
| where _time >= 1794155400 AND _time < 1794156120
| where TENANT_FIELD="PIVOT_TENANT" AND ASSET_FIELD="PIVOT_ASSET"

Elastic


@timestamp >= "2026-11-08T16:30:00Z" AND @timestamp < "2026-11-08T16:42:00Z"
AND TENANT_FIELD: "PIVOT_TENANT" AND ASSET_FIELD: "PIVOT_ASSET"

CrowdStrike Falcon CQL


TENANT_FIELD="PIVOT_TENANT"
| ASSET_FIELD="PIVOT_ASSET"
| test(@timestamp >= 1794155400000)
| test(@timestamp < 1794156120000)

Microsoft KQL


YOUR_SOURCE
| where EventTime >= datetime(2026-11-08T16:30:00Z) and EventTime < datetime(2026-11-08T16:42:00Z)
| where TENANT_FIELD == "PIVOT_TENANT" and ASSET_FIELD == "PIVOT_ASSET"

Interpret findings and record the outcome


Password acceptance against confirmed historical key-only intent warrants investigation. If you cannot rule out a login, treat the machine as compromised. Unknown historical policy remains unresolved. Client novelty adds context, while unexpected privilege or configuration changes need a demonstrated session link and comparison with approved administration.


An empty result cannot clear a host with missing collection, policy history or follow-on visibility. Record the exposed host, identity and interval, package remediation and daemon restart evidence, linked actions, unresolved gaps and the next responsible owner before closure.


Carry the investigation into operations


Inception Protection can support the continuing review of authentication and endpoint evidence as teams remediate exposed access. Request your free Inception Foresight M365 Assessment to identify visibility and detection gaps in your Microsoft environment.


bg-map-white.png

INCEPTION SECURITY™

A cybersecurity company with in depth knowledge of the threat landscape and security controls.

NAVIGATION

GET IN TOUCH

© 2025 All Rights Reserved by INCEPTION SECURITY™ .

bottom of page