1. MQTT 未授权访问检测与利用

MQTT 未授权访问检测与利用 学习卡片

实验环境与目标

本例在一台隔离的 Linux 主机上搭建 Mosquitto 代理,故意开启匿名访问,然后从另一台主机(或同一主机的不同终端)用 mosquitto_sub 与 mosquitto_pub 验证:未携带任何用户名/口令的客户端能否成功订阅与发布。最后通过抓包分析 CONNECT 与 SUBSCRIBE 报文中认证字段的缺失情况。

实验拓扑与关键端口如下:

攻击者主机 mosquitto_sub / pub 无用户名 / 无口令 tcpdump 抓包 Mosquitto 代理 监听 1883/tcp allow_anonymous true 无 password_file 无 ACL 限制 broker: 192.168.56.10 合法 IoT 设备 发布传感器数据 主题: sensors/temp QoS 0 CONNECT SUBSCRIBE PUBLISH CONNECT 报文认证字段缺失分析 CONNECT 可变报头 + 载荷 Protocol Name: MQTT Connect Flags: 0x02 (Clean Session) Username Flag=0, Password Flag=0 SUBSCRIBE 报文 Packet ID: 1 Topic Filter: # (通配符) 无认证信息,直接订阅成功

搭建 Mosquitto 并开启匿名访问

在代理主机上安装 Mosquitto 后,编辑配置文件 /etc/mosquitto/mosquitto.conf,关键配置如下:

# /etc/mosquitto/mosquitto.conf
listener 1883 0.0.0.0
allow_anonymous true
# 不配置 password_file,不配置 acl_file

重启服务并确认监听状态:

sudo systemctl restart mosquitto
sudo ss -tlnp | grep 1883
# 预期输出:LISTEN 0 100 0.0.0.0:1883 0.0.0.0:* users:(("mosquitto",pid=...))
该配置仅用于隔离实验环境。生产环境中 allow_anonymous true 且无 ACL 会导致任意客户端读写全部主题。

未授权订阅验证

在攻击者主机上执行订阅命令,不提供任何认证参数:

mosquitto_sub -h 192.168.56.10 -p 1883 -t '#' -v

参数说明:-h 指定代理地址,-p 指定端口,-t '#' 订阅所有主题,-v 显示主题名。若连接成功且无报错,终端会保持等待状态,说明未授权订阅已生效。

未授权发布验证

在另一个终端(或合法设备模拟端)执行发布:

mosquitto_pub -h 192.168.56.10 -p 1883 -t 'sensors/temp' -m '{"device":"sensor-01","temp":36.5}'

此时订阅终端应立即输出:

sensors/temp {"device":"sensor-01","temp":36.5}

这证明攻击者无需任何凭据即可向任意主题发布消息,订阅者会正常收到。若将主题改为 cmd/device-01 并发布控制指令,同样会被下游设备接收,形成指令注入风险。

抓包分析认证缺失点

在攻击者主机上对 1883 端口抓包:

sudo tcpdump -i any -w mqtt_anon.pcap port 1883

复现一次订阅与发布后停止抓包,用 Wireshark 打开并过滤 mqtt。重点观察两个报文:

  • CONNECT 报文:Connect Flags 字节中 Username Flag 与 Password Flag 均为 0,载荷中只有 Client ID,没有 User Name 和 Password 字段。代理端因 allow_anonymous true 直接返回 CONNACK 并置 Return Code 为 0(连接已接受)。
  • SUBSCRIBE 报文:报文本身不携带任何认证字段,认证完全依赖 CONNECT 阶段。由于 CONNECT 阶段未认证,SUBSCRIBE 的 Topic Filter 为 # 时代理不做 ACL 校验,直接返回 SUBACK 授予 QoS 0。

由此可归纳出认证缺失点:MQTT 3.1.1 的认证只发生在 CONNECT 阶段,SUBSCRIBE/PUBLISH 不重复认证;当代理配置为匿名允许且无 ACL 时,任何网络可达的客户端都能完成全主题读写。

检测与加固要点

检测项命令/方法未授权特征
匿名连接mosquitto_sub -t '#' -v 无 -u/-P成功收到消息
匿名发布mosquitto_pub -t test -m x 无 -u/-P订阅端收到 test
CONNECT 标志Wireshark 查看 Connect FlagsUsername/Password Flag=0
SUBACK 返回Wireshark 查看 SUBACK对 # 返回 QoS 0 授予

加固方向:设置 allow_anonymous false,配置 password_file 启用用户名口令认证,并通过 acl_file 限制每个客户端可订阅/发布的主题范围。完成加固后重复上述命令,未携带凭据的连接应被拒绝,CONNACK 返回码非 0。