CVE-2026-73430
Executive Summary
CVE-2026-73430 is a pre-authentication denial-of-service vulnerability in the Russh SSH client/server library for Rust, affecting all server deployments prior to version 0.62.4. An unauthenticated, network-reachable attacker can send a malformed SSH_MSG_KEX_ECDH_INIT message containing a 32-byte all-zero Q_C value during Curve25519 key exchange, which triggers an out-of-bounds index panic in the server's key-exchange task and terminates it before authentication. The result is an availability impact (CVSS 3.1 base score 5.3) on the SSH service, with no confidentiality or integrity impact. The fix is claimed to be released in Russh 0.62.4; currently there is no known public exploit and no CISA KEV inclusion.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Russh is a pure-Rust implementation of the SSH protocol and is used to build SSH servers, clients, and jump/management infrastructure. The flaw resides in the server-side handling of the Curve25519 ECDH key-exchange step.
In a normal SSH transport handshake, the client and server negotiate the key-exchange algorithm. If a Curve25519-based algorithm such as curve25519-sha256 is negotiated, the client sends SSH_MSG_KEX_ECDH_INIT containing its ephemeral public key Q_C — a 32-byte value per the X25519 encoding. The server-side handler Curve25519Kex::server_dh (located in russh/src/kex/curve25519.rs) is responsible for combining this peer public value with the server's own private key to derive the shared secret.
The bug is the acceptance of a special invalid input: a 32-byte all-zero Q_C. In X25519 arithmetic, an all-zero input corresponds to the identity point, and the resulting shared secret is also all zeros. The cryptography literature and RFC 7748 explicitly require implementations to detect an all-zero shared-secret output and abort the handshake, because such a value can never be produced by an honest peer and indicates a protocol-level attack or misbehavior. Russh does not perform this check — this missing validation of an exceptional condition is the root cause, classified under CWE-754 (Improper Check for Unusual or Exceptional Conditions).
After the all-zero shared secret is accepted, the code continues into the exchange hash computation. In compute_exchange_hash (russh/src/kex/mod.rs), the shared secret must be serialized into SSH mpint format (RFC 4251). The helper encode_mpint is designed to strip leading zero bytes so that the integer is represented minimally. When operating on a 32-byte all-zero input, every byte is zero; the loop that skips leading zeros advances beyond the end of the slice. The subsequent indexing operation on the now-exhausted slice is out of bounds. In Rust, out-of-bounds slice indexing panics by design. This panic is not caught in the key-exchange task, so the task terminates and the SSH connection is torn down before authentication is ever reached.
Notably, the malformed message is not a parse error — it is a well-formed SSH message whose semantic content (an all-zero elliptic-curve point) is invalid. This means generic parser/garbage-detection defenses do not block it; the gap is a missing semantic validation after parsing. The entire attack surface is the pre-authentication SSH key-exchange state machine, reachable by any TCP client that can connect to a targeted SSH port. Because the failure is a panic, there is no memory corruption; the impact is limited to availability. Repeated connections can allow an attacker to indefinitely deny service to legitimate clients, including administrative SSH access.
Exploitation Scenarios
No public PoC or exploit code is currently known. The following attack chain is inferred strictly from the NVD description and protocol semantics.
Reconnaissance / target identification: An attacker scans for SSH services reachable from the network. A banner-based fingerprint (e.g., an
SSH-2.0-...russhsoftware version string) or service behavior allows identification of hosts likely running a Russh-based server. Applications embedding the Russh library on an alternate port are equally exposed. No credentials or prior access are required at any stage.Flaw trigger: The attacker opens a TCP connection to the SSH port and drives the transport layer to the key-exchange phase. Once the server advertises Curve25519 key exchange, the attacker completes the KEXINIT negotiation and sends
SSH_MSG_KEX_ECDH_INITwhoseQ_Cfield is a 32-byte all-zero value. The message is structurally valid, so it passes normal parsing.Payload / execution at the vulnerability class level: The server's
server_dhroutine accepts the invalid point and computes an all-zero shared secret instead of rejecting it (CWE-754: missing check for exceptional condition). The exchange-hash serialization path then callsencode_mpint, whose leading-zero-skipping loop indexes past the end of the all-zero byte array and panics. The panic occurs in the pre-authentication server task, causing the task — and the SSH session — to terminate.Post-exploitation impact: The affected SSH connection is dropped; legitimate users cannot complete key exchange on that connection. The attacker can repeat this sequence to create sustained service disruption, effectively denying remote administration of the host. There is no evidence of privilege escalation, code execution, or data exposure — the vulnerability is purely an availability issue.
Given the absence of public exploit code, defenders should treat the attack chain as inferred from the vulnerability class and the protocol-required message sequence above.
Impact Assessment
CVSS 3.1 base score: 5.3, vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L. The vector reflects a network-reachable, low-complexity, unauthenticated attack with no user interaction. Scope is unchanged, and there is no confidentiality or integrity impact. The availability subscore is Low (A:L), consistent with a per-session/task failure rather than full host compromise.
Affected systems: All software embedding or running Russh as an SSH server with versions prior to 0.62.4. The NVD description names no additional vendors or downstream products, so the true deployment footprint is unknown. Russh client functionality is not vulnerable in this scenario; the flaw is in server-side handling of client-supplied data. The vendor is listed as "Russh / Unknown," indicating uncertainty about the full ecosystem of products that consume the library.
Business impact: For enterprises, the practical consequence is remote-management outage on SSH-exposed hosts. If an SSH bastion, network device, or automation host uses a vulnerable Russh version, a single low-skill attacker (or a scripted scan-and-panic loop) can block legitimate administrative access. Because the attack happens pre-authentication, firewall authentication layers provide no protection. However, the probability of near-term exploitation is currently low: EPSS is 0.00332 (26.2nd percentile of exploited CVEs), the CVE is not in the CISA Known Exploited Vulnerabilities catalog, and no public PoC or exploit code is known.
Detection Guidance
The rules below are intended to be adapted to local log formats, thresholds, and network topologies. Detection is two-pronged: (a) network-level detection of the malformed key-exchange payload, and (b) host-level detection of Russh panic messages or SSH daemon crash behavior.
Sigma Rule
title: Russh SSH Server Panic During Key Exchange - CVE-2026-73430
id: 8b4c1a10-0000-4a00-9a00-cve202673430
status: experimental
description: >
Detects Russh SSH server panic log entries referencing the KEX code path
and an out-of-bounds index. Correlates with unauthenticated SSH KEX attempts.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-73430
author: Valters IT Threat Intelligence
date: 2026/06/01
logsource:
product: linux
service: sshd
category: application
detection:
selection_panic:
message|contains|all:
- 'panicked at'
- 'index out of bounds'
selection_russh:
message|contains|any:
- 'russh/src/kex/mod.rs'
- 'russh/src/kex/curve25519.rs'
- 'encode_mpint'
condition: selection_panic and selection_russh
level: high
falsepositives:
- Russh server code with unrelated panics (low likelihood)
tags:
- attack.t1499
- cve.2026-73430
- denial-of-service
YARA Rule
This YARA rule targets packet captures or memory captures containing the on-wire encoding of SSH_MSG_KEX_ECDH_INIT with a 32-byte all-zero Q_C: message ID 0x1E, followed by the 4-byte string length 0x00000020, followed by 32 zero bytes.
rule ssh_kex_ecdh_init_all_zero_qc {
meta:
author = "Valters IT Threat Intelligence"
description = "Detects SSH KEX ECDH INIT payloads with all-zero Q_C (CVE-2026-73430)"
reference = "CVE-2026-73430"
cve = "CVE-2026-73430"
date = "2026-06-01"
hash = "unknown"
strings:
$kex_init_zero = { 1E 00 00 00 20
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 }
$russh_banner = "russh" ascii nocase
condition:
uint16(0) != 0x4D5A and any of them
}
Limitations: the byte pattern is only visible if the KEX payload arrives unfragmented and uncompressed; SSH packet boundaries may not align with TCP segment boundaries in a raw capture. Use with a reassembled stream (e.g., after tcpflow or similar extraction).
Suricata IDS Rule
alert tcp any any -> any 22 (
msg:"ET DOS Russh SSH KEX ECDH INIT all-zero Q_C (CVE-2026-73430)";
flow:to_server,established;
content:"|1e|";
content:"|00 00 00 20|"; distance:0; within:4;
content:"|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|"; distance:0; within:32;
classtype:attempted-dos;
reference:cve,2026-73430;
sid:202673430;
rev:1;
)
Note: the rule assumes Suricata stream reassembly and that the SSH binary packet (message ID + string length + 32 zero bytes) is contiguous in the reassembled TCP stream. Test against local Russh traffic before deployment; consider filtering by destination port if SSH runs on a non-standard port.
Elastic Detection
EQL rule to detect Russh server process/task termination or panic markers in application and syslog data:
any where
(log.file.path == "/var/log/auth.log" or log.file.path == "/var/log/messages" or log.file.path == "/var/log/syslog") and
message like "*panicked at*" and
(message like "*russh*" or message like "*encode_mpint*")
Secondary EQL rule for SSH daemon process crash/abnormal exit (to be correlated with the above):
process where event.category == "process" and event.type == "end" and
process.name == "sshd" and process.exit_code != 0
Note: adjust index patterns (e.g., logs-*, filebeat-*, auditbeat-*) and event field names to the local Elastic deployment. The panic occurs in a library task, so the host may continue running; log-based detection is the most reliable signal.
Splunk SPL Query
Search for Russh panic indicators in SSH/application logs:
index=* (sourcetype=linux_secure OR sourcetype=syslog OR sourcetype=ssh*)
("panicked at" OR "index out of bounds")
AND ("russh" OR "kex/mod.rs" OR "encode_mpint")
| eval cve="CVE-2026-73430"
| stats count min(_time) max(_time) by host, source, cve
| sort - count
Network-side SPL (if Zeek/Bro SSH logs are available) to identify repeated pre-auth disconnects during key exchange:
index=network sourcetype=zeek:ssh:json OR sourcetype=bro:ssh:json
auth_success=false
| stats count by id.orig_h, id.resp_h, id.resp_p
| where count > 5
| eval cve="CVE-2026-73430"
Note: tune thresholds to the environment. The panic log message content depends on the embedding application's log verbosity; if the app suppresses Rust panic messages, rely on connection-teardown analytics (abrupt KEX failures before authentication).
Wazuh OSSEC Rule
Add to the local rules file (e.g., /var/ossec/etc/rules/local_rules.xml):
<group name="ssh,attack,attempted_dos,">
<rule id="100734" level="10">
<if_sid>5700</if_sid>
<match>panicked at|index out of bounds</match>
<regex>russh|kex|encode_mpint</regex>
<description>Russh SSH server panic detected - possible CVE-2026-73430 exploitation</description>
<group>ssh,attack,attempted_dos,</group>
<mitre>
<id>T1499</id>
</mitre>
</rule>
</group>
Note: if_sid>5700 anchors the rule to the standard sshd authentication failure group; adjust or remove if the local SSH logging format differs. Rule IDs above 100000 are reserved for local rules in Wazuh.
Mitigation & Patch Guidance
Patch confidence: 2/4 (CLAIMED). A fix is claimed via OSV for russh 0.62.4, but this has not been independently confirmed by a second authoritative source. Validate against the official russh repository/release before treating the fix as definitive.
Immediate mitigations (before patching):
- Restrict network access to SSH ports (default 22, plus any alternate ports) using firewall allowlists if the SSH service is only needed from trusted administrative networks.
- Apply connection rate-limiting or fail2ban-style throttling to slow scripted reconnection attempts. Note: throttling reduces the rate of a sustained attack but does not prevent a single-crafted-packet DoS.
- Deploy the Suricata/YARA rules above on network monitoring sensors and the host-level log rules on SSH-facing hosts.
- Monitor for anomalous pre-authentication KEX init messages and abrupt session teardowns during the key-exchange phase.
Patch / upgrade steps:
- Upgrade russh to version 0.62.4 or later. In Rust projects, run
cargo update -p russh(or update the version constraint inCargo.toml) and rebuild/redeploy all binaries that embed the library. - Because the affected-versions list is currently empty in the advisory data, treat the entire
0.xline prior to 0.62.4 as vulnerable based on the NVD description ("Prior to 0.62.4"). - After upgrading, verify the fix by sending
SSH_MSG_KEX_ECDH_INITwith an all-zeroQ_Cduring internal testing and confirming the server now aborts the handshake cleanly without a panic.
- Upgrade russh to version 0.62.4 or later. In Rust projects, run
Long-term hardening:
- Add fuzzing for SSH protocol-message parsing — especially semantic validation of key-exchange parameters — to the development pipeline. This bug would be caught by fuzzing that generates structurally valid but semantically invalid public values (e.g., identity points, all-zero scalars).
- Ensure upstream libraries implement the RFC 7748 requirement to abort when the X25519 shared-secret output is all zeros; adopt a security policy that treats such outputs as fatal handshake errors.
- For production SSH infrastructure, consider supervision/auto-restart at the service level so that a panicking key-exchange task cannot leave the service permanently unavailable.
- Track the CVE in vulnerability-management workflows; re-assess urgency if the EPSS score (currently 0.00332) rises or if exploitation is observed.
References
- NVD — CVE-2026-73430: https://nvd.nist.gov/vuln/detail/CVE-2026-73430
- OSV vulnerability entry (patch source/claim): https://osv.dev/vulnerability/CVE-2026-73430
- CVE.org record: https://www.cve.org/CVERecord?id=CVE-2026-73430
- RFC 7748 (Elliptic Curves for Security; all-zero output check requirement): https://www.rfc-editor.org/rfc/rfc7748
- RFC 5656 (SSH ECDH key exchange,
SSH_MSG_KEX_ECDH_INITmessage): https://www.rfc-editor.org/rfc/rfc5656
Exploitation-in-the-wild evidence: none known at the time of writing. CVE-2026-73430 is not listed in the CISA Known Exploited Vulnerabilities catalog, and there are no public reports of threat-actor campaigns abusing this flaw. EPSS (0.00332, 26.2nd percentile) indicates a low current likelihood of exploitation.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.