是谁关了我家的灯-MQTT协议测绘分析与安全问题探究
2023-3-14 20:10:15 Author: 源影安全实验室(查看原文) 阅读量:10 收藏

一、MQTT概述  
MQTT是一种基于发布/订阅模式的轻量级消息传输协议,它归属于应用层,专门针对低带宽和不稳定网络环境的物联网应用而设计,可以用极少的代码为联网设备提供实时可靠的消息服务。MQTT协议广泛应用于物联网、移动互联网、智能硬件、车联网、智慧城市、远程医疗、电力、石油与能源等领域。官方定义如下:
MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks. The design principles are to minimise network bandwidth and device resource requirements whilst also attempting to ensure reliability and some degree of assurance of delivery. These principles also turn out to make the protocol ideal of the emerging “machine-to-machine” (M2M) or “Internet of Things” world of connected devices, and for mobile applications where bandwidth and battery power are at a premium.

1. 协议报文

  • 固定报头  

每个MQTT控制报文都包含一个固定报头。如下表,描述了固定报头的格式。
Bit
7
6
5
4
3
2
1
0
byte1
MQTT控制报文的类型
用于指定控制报文类型的标志位
byte2...
剩余长度
  • 控制报文的类型  

名字
报文流动方向
描述
Reserved
0
禁止
保留
CONNECT
1
客户端到服务端
客户端请求连接服务端
CONNACK
2
服务端到客户端
连接报文确认
PUBLISH
3
两个方向都允许
发布消息
PUBACK
4
两个方向都允许
QoS1 消息发布收到确认
PUBREC
5
两个方向都允许
发布收到(保证交付第一步)
PUBREL
6
两个方向都允许
发布释放(保证交付第二步)
PUBCOMP
7
两个方向都允许
QoS2 消息发布完成
(保证交互第三步)
SUBSCRIBE
8
客户端到服务端
客户端订阅请求
SUBACK
9
服务端到客户端
订阅请求报文确认
UNSUBSCRIBE
10
客户端到服务端
客户端取消订阅请求
UNSUBACK
11
服务端到客户端
取消订阅报文确认
PINGREQ
12
客户端到服务端
心跳请求
PINGRESP
13
服务端到客户端
心跳响应
DISCONNECT
14
客户端到服务端
客户端断开连接
Reserved
15
禁止
保留
  • 标志位 Flag Bits  

控制报文
固定报头标志
Bit 3
Bit 2
Bit 1
Bit 0
CONNECT
Reserved
0
0
0
0
CONNACK
Reserved
0
0
0
0
PUBLISH
Used in MQTT 3.1.1
DUP1
QoS2
QoS2
RETAIN3
PUBACK
Reserved
0
0
0
0
PUBREC
Reserved
0
0
0
0
PUBREL
Reserved
0
0
1
0
PUBCOMP
Reserved
0
0
0
0
SUBSCRIBE
Reserved
0
0
1
0
SUBACK
Reserved
0
0
0
0
UNSUBSCRIBE
Reserved
0
0
1
0
UNSUBACK
Reserved
0
0
0
0
PINGREQ
Reserved
0
0
0
0
PINGRESP
Reserved
0
0
0
0
DISCONNECT
Reserved
0
0
0
0
注:
  • DUP1 代表控制报文的重复分发标志。
  • QoS2 代表 PUBLISH报文的服务质量等级。
  • RETAIN3 代表 PUBLIS
    H报文
    match
    的保留
    标志。
2. MQTT的通信过程
    • 客户端连接到MQTT代理;
    • 客户端订阅一个或多个主题;
    • 发布者发布一个特定主题的消息;
    • MQTT代理将该消息传递给所有已订阅该主题的客户端;
    • 客户端收到消息并执行必要的操作。
3. MQTT vs HTTP   
  • MQTT 的最小报文仅为 2 个字节,比 HTTP 占用更少的网络开销。
  • MQTT 与 HTTP 都能使用 TCP 连接,并实现稳定、可靠的网络连接。
  • MQTT 基于发布订阅模型,HTTP 基于请求响应,因此 MQTT 支持双工通信。
  • MQTT 可实时推送消息,但 HTTP 需要通过轮询获取数据更新。
  • MQTT 是有状态的,但是 HTTP 是无状态的。
  • MQTT 可从连接异常断开中恢复,HTTP 无法实现此目标。

4. 测绘情况

目前,全网共计有 102 万主机开放了 MQTT 服务,主要集中在亚洲地区。

韩国地区位居榜首,这表示韩国地区拥有大量的 IoT 设备,其原因有以下三点:
1、韩国拥有发达的技术基础设施,并一直在大力投资信息技术和通信 (ICT) 基础设施,这可能是该国物联网设备普及的一个促成因素。
2、韩国政府一直在积极推动物联网技术的实施,并为物联网相关研发提供支持。2014年,韩国政府推出 “Creative Economy” 政策,旨在通过支持物联网等新兴技术促进创新创业。政府还设立了研究中心,并一直为物联网相关的研究和开发提供资金。
3、韩国是几家大型科技公司的所在地,例如三星和 LG,它们一直在开发物联网产品和技术。

5. 相关概念  

  • Topic 

MQTT基于发布订阅模式进行消息通信,客户端可以作为发布者发布消息或或者作为订阅者订阅主题,当消息发布时,服务端负责接收消息并将其转发给订阅了相关主题的客户端。MQTT 主题 (Topic) 类似 URL 路径,例如:
chat/room/1sensor/10/temperaturesensor/+/temperature$SYS/broker/metrics/packets/received$SYS/broker/metrics/#
主题 (Topic) 通过'/'分割层级,支持'+', '#'通配符:
'+': 表示通配一个层级,例如 a/+,匹配 a/x, a/y'#': 表示通配多个层级,例如 a/#,匹配 a/x, a/b/c/d
  • 系统Topic 

系统Topic是指周期性发布自身运行状态、消息统计、客户端上下线事件到以 $SYS/ 开头的主题。
注意:一般务端默认只允许本机的 MQTT 客户端订阅 $SYS 主题。
  • 保留消息  

     MQTT 客户端向服务器发布 (PUBLISH) 消息时,可以设置保留消息 (Retained Messages) 标志在当前主题设置一条持久消息,消息将被保存在服务器上,新的订阅者订阅主题时将接收到该消息。每个主题下只能存在一份保留消息,因此如果已经存在相同主题的保留消息,则该保留消息被替换。
  • 遗嘱消息  

MQTT 遗嘱消息可以在客户端意外断线时将“遗嘱”优雅地发送给第三方订阅者,以实现离线通知、设备状态更新等业务。其中意外断线指客户端断开前未向服务器发送 DISCONNECT 消息,比如:
      • 因网络故障或网络波动,设备在保持连接周期内未能通讯,连接被服务端关闭
      • 设备意外掉电
      • 设备尝试进行不被允许的操作而被服务端关闭连接,例如订阅自身权限以外的主题等。
  • QoS  

MQTT 协议中规定了消息服务质量(Quality of Service),它保证了在不同的网络环境下消息传递的可靠性,QoS 的设计是 MQTT 协议里的重点。
QoS
含义
QoS 0
“至多一次”,消息发布完全依赖底层 TCP/IP 网络,会发生消息丢失或重复,这一级别可用于对采集数据要求不严格的情况。
QoS 1
“至少一次”,确保消息到达,但消息可能会重复发生。
QoS 2
“只有一次”,确保消息只到达一次,这一级别可用于要求严格的情况,消息重复或丢失都是不允许的。

1. 服务端  

这里选取 EMQX 作为服务端,仅需三步即可完成服务端的搭建。

1、配置 EMQX Apt 源(Ubuntu)
curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash
2、安装 EMQX
sudo apt-get install emqx
3、启动 EMQX
sudo systemctl start emqx
更多安装方式参考:https://www.emqx.io/zh/downloads

2. 客户端 

   这里选取MQTTX作为MQTT客户端工具,值得注意的是此工具仅支持MQTT 5.0协议,除此之外的协议不支持。下载链接:https://mqttx.app/

3. 使用方式  

a)创建连接

点击 “New connection”,填写Name和Host字段即可,Name可以随意填写。
         
b)订阅主题

点击“NewSubscription”,填写想要订阅的主题即可。       

c)发布消息
在底部文本框输入消息内容,点击发送按钮即可完成消息发布。        

1. 安全隐患 

a)未授权访问

目前大部分 MQTT 服务端都有相对完备的认证方式,如:密码认证、JWT认证等,但是由于默认情况下未开启认证功能,即允许所有客户端连接,这代表任何人都可以发布或订阅消息,如果存在敏感数据或指令,将导致信息泄露或者被恶意攻击者滥用指令。
此次探测使用了 paho-mqtt 库,paho-mqtt 可以说是 Python MQTT 开源客户端库中的佼佼者。它由 Eclipse 基金会主导开发,除了 Python 库以外,同样支持各大主流的编程语言,比如 C++、Java、JavaScript、Golang 等。目前 Python 版本已经实现了 3.1 和 3.1.1 MQTT 协议,在最新开发版中实现了 MQTT 5.0。Paho 的接口使用非常简单优雅,只需要少量的代码就能实现 MQTT 的订阅及消息发布。
使用以下代码,即可轻松地创建与 MQTT 服务端地连接,并获取连接结果。
client = mqtt.Client()client.connect(self.host, port=self.port, keepalive=1)rc = client.loop()
rc 代表连接结果,它可以指示当前的连接状态,具体含义如下表。
rc
含义
0
连接成功
1
连接被拒绝 – 协议版本不正确
2
连接被拒绝 – 客户端标识符不正确
3
连接被拒绝 – 服务器不可用
4
连接被拒绝 – 用户名或密码错误
5
连接被拒绝 – 未授权
6-255
当前未使用
从上表可以看出,仅当 rc 值为0时,代表连接成功。但在探测过程中,我们发现有的 MQTT 服务虽然可以连接成功,但会立刻断开,下图的日志显示了这一问题。       
这类主机我们应该归属于不存在未授权访问的一类,但如果使用上面的代码会得到连接成功的结果,这显然不是我们想要的结果。这里可以通过两次调用 loop 函数的方式,再次确认连接状态,以获取正确的结果,代码如下。
client = mqtt.Client()client.connect(self.host, port=self.port, keepalive=1)client.loop()rc = client.loop()
通过脚本对公网上开放的 MQTT 服务进行未授权访问扫描,我们共计发现了5.5 W+的主机具有未授权访问漏洞,其中1883端口包含5.2 W+,占据了绝大多数。除此之外,我们还发现开启 SSL 功能的服务器存在未授权访问的概率低于未开启 SSL 功能的服务器,这表明开启 SSL 的资产管理者有较高的安全意识。如果启用了 SSL,但 MQTT 服务端未正确配置为需要客户端身份验证,则仍可能允许未经授权的客户端连接并可能访问到敏感数据或控制连接的设备。正确配置MQTT 服务端非常重要,包括启用 SSL、实施适当的身份验证和授权措施,以防止未经授权的访问。
b)未采用加密传输  

若连接过程未采用加密传输,则可能被中间人攻击,可获取其验证的用户名和密码。

c)弱口令

MQTT 服务端密码认证使用了弱口令,黑客可能采用弱口令爆破的方式非法登录,窃取服务器数据或下达恶意指令。

c)漏洞

服务端软件自身存在缺陷可被利用,或者订阅端或服务端解析内容不当产生安全漏洞,这将导致整个系统不安全。

如CVE-2019-11779,在Eclipse Mosquitto 1.5.0 到1.6.5 中,如果恶意MQTT 客户端发送一个SUBSCRIBE 数据包,其中包含一个由大约65400 个或更多'/' 字符组成的主题,即主题层次分隔符,则会发生堆栈溢出。

2 安全影响

a)通过通配符订阅全部主题或系统主题

如果 MQTT 服务存在未授权访问或弱口令,登陆后,可以通过 # 订阅全部主题或 $SYS/# 订阅系统主题,获取敏感信息。
         
订阅全部主题

订阅系统主题

b)轨迹泄露

根据泄露信息来看,敏感泄露信息数据主要来自于 IoT 设备状态信息,包括On、Off、Online、Offline等状态。通过网络空间搜索引擎,发现有近2500+的 MQTT 服务暴露了设备的状态信息。
伴随这 IoT 设备的发展,设备间的联动也逐渐变多,IoT 设备会通过 MQTT 协议发布消息通知其他的设备,以实现设备间的联动。如下图所示,IoT 设备识别到了 Christopher McKay 到家了,将走廊的灯光自动开启,这为生活增加了便利,但由于暴露在互联网上,导致了个人生活轨迹的泄露。
         

c)内外探测

IoT设备会通过 MQTT 协议发布自己的配置信息,以供其他设备获取,其中包含了IP、设备名称等信息,通过这些信息可以达到内网探测的目的。暴露内部网络 IP 地址可能会带来严重的安全风险。如果攻击者获得了对内部网络中设备 IP 地址的访问权限,他们可能会发起范围广泛的攻击,例如访问机密信息、窃取数据、安装恶意软件,甚至获得网络控制权。通过网络空间搜索引擎,我们发现了近 4000+ 的 MQTT 服务器向外暴露了配置信息,其中包括PC、TV、路由器等设备的配置信息。     

d)身份信息泄露

除此之外,我们还发现物联网设备通过 MQTT 协议进行身份认证,但在通信过程中使用了明文,暴露了用户邮箱地址、名字、密码等身份信息。如下图的设备,在通信过程中,向外发布了用户邮箱、姓名、性别和密码信息,暴露了个人身份信息。

根据我们的测绘数据,通过订阅 # 和 $SYS/# 主题的方式,对含有未授权访问的主机进行了时长为 3 秒的记录,共有 3000+ 的主机进行了响应,地区分布如下图所示。
从上图中,我们可以看出MQTT 使用率较高的同时也存在开发者安全意识缺乏的问题,需要加强有关保护 MQTT 服务的培训;而具有最多 MQTT 服务的韩国,排名第四,韩国排名较低可能表其采取了更主动的安全措施或 MQTT 使用率可能较低。
我们对响应的主题和内容也进行了分析,主题分布和内容关键词分布如下图所示。
通过上图,我们可以发现系统主题 SYS 是占据了最多的数量,这表明了绝大多数的主机没有设置合理的 ACL 规则,导致可以远程订阅系统主题并访问敏感信息,包括系统配置、身份验证凭据或设备数据,为系统带来了潜在的安全风险。
主题gateway排名第二,这表明 MQTT 服务被大量用作网关。网关可以将来自 MQTT 服务端的消息转换为 HTTP 或 CoAP 格式,以便与 Web 服务器或其他不直接支持 MQTT 的设备进行通信。它允许不同的系统通过 MQTT 无缝地相互通信。如果 MQTT 网关允许未经授权的访问,攻击者可能会获取设备和服务器之间传输的敏感数据。
主题machine_status_change、status、config的数量也不少,这表明这些主题的消息会泄露设备的物理状态及配置信息,攻击者可能会使用泄露的信息来操纵设备,导致它们发生故障或执行意外操作。如内容关键词分布图所示,我们可以发现大量的内容包含pseudoRanges、carrierSignal和rinexCode这些关键词,其中的pseudoRanges是伪距,代表地面接收机到卫星之间的大概距离;arrierSignal是指GPS信号的载波频率,由导航数据调制,提供准确的授时信息;rinexCode 是指用于调制 GPS 信号以用于导航目的的代码。这些消息极有可能包含来自 GPS 接收器的数据的消息,企业和组织经常将 GPS 数据用于关键流程,该数据的泄漏可能会破坏这些流程并导致财务损失或其他负面影响。
1设置合理的 ACL 规则,如只允许本机的 MQTT 客户端订阅 $SYS 和 # 主题。
2、服务端开启访问控制功能,设置密码认证,不允许未授权的用户登录。
3、传输数据采用密文的方式,避免数据泄露。
  • MQTT协议:  https://mcxiaoke.gitbook.io/mqtt/

  • EMQX:  https://www.emqx.io/

  • Mosquitto Security:  https://mosquitto.org/security/

  • 物联网安全之MQTT协议安全:  https://bacde.me/post/mqtt-security-part-

    one/

文章来源: http://mp.weixin.qq.com/s?__biz=MzkwNjM5NTkwOA==&mid=2247483809&idx=1&sn=229c9cc9d21a7d6abde00dfe7bab563e&chksm=c0e869caf79fe0dc783fc36b2473965920c8841063f93b889860456838f7255034cd0b715f35#rd
如有侵权请联系:admin#unsafe.sh