文 年华 | 图 lmn
随着物联网的快速发展,当前在物联网中的常见的五种协议分别是:HTTP、CoAP、XMPP、AMQP、MQTT。但在这么多协议中,毫无疑问MQTT最具代表性,因为它占用带宽小、轻量级、简单易用等优点最符合物联网的应用场景。可以毫不夸张的说:每个物联网开发人员都一定了解MQTT
今天我们将从三个方面来探讨一下MQTT的安全性,分别是登陆认证问题、权限控制问题以及Broker自身安全性的问题(不知道什么是Broker没关系,接着往下看就是了),如果师傅已经了解了MQTT的基础知识建议直接看第三小节
【本文所有截图均在模拟环境进行】
1 MQTT简介
术语
为了防止师傅们疑惑,本文使用术语定义如下:
客户端(Client):使用MQTT的程序或设备,一般分为发布者和订阅者
服务端(Server):发布者和订阅者之间的中介【Broker】
主题(Topic):附加在消息上的一个标签,Broker会将该消息发送给所有订阅该主题的订阅者
主题过滤器(Topic Filter):订阅者订阅时可使用通配符同时订阅一个或多个主题
基本介绍
MQTT的主要工作原理如下图所示,发布者和订阅者就像常见系统中的客户端一样,中心服务器在MQTT中被称为Broker[1]
△ 图片来源:mqtt.org
那MQTT的设计优点有哪些呢?郭朝斌老师将其归纳为五个方面[2]
1. 契合物联网大部分应用场景的发布-订阅模式
2. 能够满足物联网中资源受限设备需要的轻量级特性
3. 时刻关注物联网设备低功耗需求的优化设计
4. 针对物联网中多变的网络环境提供的多种服务质量等级
5. 支持在物联网应用中越来越被重视的数据安全
接下来我们分别讲解一下这五个特性
发布-订阅模式
△ 图片来源:emqx.io
通过上图可以看到有两个MQTT客户端同时订阅了同一个主题Temperature,当温度传感器作为发布者发布其检测到的温度时,订阅者手机、电脑和后端服务器都会收到同样的消息
发布-订阅模式的优点在于发布者与订阅者的解耦,这种解耦表现在以下两个方面[3]:
1. 空间解耦,订阅者与发布者不需要建立直接连接,新的订阅者想要加入网络时不需要修改发布者的行为
2. 时间解耦,订阅者和发布者不需要同时在线,即便不存在订阅者也不影响发布者发布消息
因为发布-订阅模型的应用,使得MQTT允许一个传感器发布的数据触发多个订阅者的一系列动作
轻量级模型
MQTT的轻量体现在两个方面:
一是MQTT消息采用二进制的编码格式,充分利用字节位,协议头紧凑,减少了通过网络传输的数据量。下图展示了MQTT的固定头格式:
△ 图片来源:docs.oasis-open.org
二是MQTT消息交互流程非常简单,MQTT 3.1.1一共定义了14种数据包类型,感兴趣的朋友可以查阅MQTT的官方手册,这里不再赘述
代码语言:javascript复制https://mcxiaoke.gitbooks.io
低功耗优化
MQTT协议十分注重低功耗的优化设计,主要体现在Keepalive机制
这个机制工作的原理是:Client 和 Broker 都基于 Keepalive 确定时间长度,来判断一段时间内是否有消息在双方之间传输。这个时间长度是Client建立连接时设置的,如果超出这个时间长度,双方没有收到新的数据包,那么就判定连接断开。 虽然 Keepalive 要求一段时间内必须有数据包传输,但实际情况是,Client 和 Broker 不可能时刻都在传输主题消息。因此MQTT定义了 PINGREQ 和 PINGRESP 这两种消息类型。它们都没有可变头部和消息体,也就只有 2 个字节大小。Client 和 Broker 通过分别发送 PINGREQ 和 PINGRESP 消息,就能够满足 Keepalive 机制的要求。
此外,MQTT 5.0 还引入了重复主题特性,即Client在重复发送某个Topic的消息时,可以从第二次开始将Topic长度设置为0
多种QoS
在物联网环境中网络质量不稳定、网络带宽低等因素均会影响到发布者、订阅与Broker之间的通信。为了解决这个问题,MQTT协议设计了三种不同的QoS如下:
1. QoS 0,表示消息至多收到一次,即消息可能丢失,但不会重复投递
2. QoS 1,表示消息至少收到一次,即消息保证送达,但可能重复投递
3. QoS 2,表示消息有且只有收到一次
安全传输
提到安全传输,首先我们要验证客户端是否有权限接入MQTT Broker
MQTT支持两种层次的认证:
1.传输层认证,传输层使用TLS认证设备,并且加密了通讯。
2.应用层认证,支持client id / username / password 等方式认证设备,但是只在应用层验证设备,不加密通讯
在本文中我们主要分析在应用层认证的MQTT,因为在传输层直接使用TLS加密之后我们就没有办法嗅探或者做其他操作了。但也这不是意味着支持TLS就能解决所有问题,因为MCU/RTOS根本玩不了TLS,怎么办?还能怎么办,继续不加密呗
接下来我们再来看看MQTT的认证过程:
客户端将用户名密码使用CONNECT消息发送到Broker,Broker根据认证信息判断是否准入,使用CONNACK消息返回结果,其中认证返回值的具体含义如下:
通过这个表格,其实我们可以判断,如果连接某个Broker,返回值为0就代表我们已经成功连接,如果返回值为4说明我们的账号密码错误,如果返回值为5说明该Broker不支持用户密码方式登陆【需要记住】
最后我们还需要注意Broker支持认证链,它会按照默认先后顺序进行链式认证:
△ 图片来源:docs.emqx.cn
主题
MQTT协议基于主题(Topic)进行消息路由,主题(Topic)类似URL路径,例如:
代码语言:javascript复制chat/room/1
sensor/10/temperature
sensor/ /temperature
$SYS/broker/metrics/packets/received
$SYS/broker/metrics/#
主题(Topic)通过'/'分割层级,支持' ', '#'通配符:
代码语言:javascript复制' ': 表示通配一个层级,例如a/ ,匹配a/x, a/y
'#': 表示通配多个层级,例如a/#,匹配a/x, a/b/c/d
订阅者可以订阅含通配符主题,但发布者不允许向含通配符主题发布消息[4]
2 MQTT体验
既然要搞MQTT,怎么可以连工具都没有呢?这里我们直接使用hbmqtt这个库来模拟MQTT client,安装方式很简单,直接pip
代码语言:javascript复制pip3 install hbmqtt
这里我们使用eclipse提供的免费broker进行测试,地址如下:
代码语言:javascript复制mqtt.eclipseprojects.io
△ 图片来源:mqtt.eclipseprojects.io
它提供了四种mqtt连接方式,今天我们主要来看看不加密的TCP连接方式,即常见的1883端口
我们打开一个终端,订阅/nianhua/iotsecurity这个主题消息:
代码语言:javascript复制hbmqtt_sub --url mqtt://mqtt.eclipseprojects.io:1883 -t /nianhua/iotsecurity
打开另一个终端,通过hbmqtt_pub发布一个/nianhua/iotsecurity主题的消息
代码语言:javascript复制hbmqtt_pub --url mqtt://mqtt.eclipseprojects.io:1883 -t /nianhua/iotsecurity -m Hello,World!
如果想了解命令的执行细节,可以在上面的命令中加上"-d"参数
再次查看打开的第一个命令行,我们可以发现我们发送的Hello,World!已经接收到了。至此,我们已经完成了一次MQTT通信
另外如果你不喜欢命令行,这里推荐一个超级好用的MQTT客户端:MQTTX 下载地址:https://mqttx.app/cn/
△ 图片来源:mqttx
Emmmmm,如果你连软件都不想下,那这里推荐给你一个在线的MQTT客户端:
代码语言:javascript复制tools.exqx.io
△ 图片来源:tools.exqx.io
3 MQTT攻击面
在这一小节我们主要介绍MQTT面临的安全风险以及如何去攻击
我们可以使用关键字"port=1883 && banner=MQTT"在fofa中搜索使用了默认端口的Broker,搜索结果如下图(January 5, 2021)所示,共发现了约26万可用Broker
△ 图片来源:fofa
接下来我们就从登陆认证问题、权限控制问题以及Broker自身安全性的问题来分析MQTT的安全性
登陆认证问题
1.匿名登陆
通过使用shodan检索MQTT协议,我们可以发现很多MQTT Connect code为0,这意味着连接到该MQTT Broker无需进行身份验证【详见1-MQTT简介/安全传输】
△ 图片来源:shadon
经笔者粗略统计大概有67.9%的可用MQTT Broker设置了匿名登陆:
2.用户名密码暴力破解
说是暴力破解,其实主要还是看字典【主要是MQTT中常见的弱口令】,因为MQTT只是单纯验证用户名和密码,没有其他校验机制,所以我们可以使用暴力破解来尝试获取用户名和密码
借着暴力破解这一小节,我们介绍一个新工具:MQTT-PWN,上图就是我们用MQTT-PWN破解某个MQTT Broker的成功截图,爆破得到了账号密码,就可以直接接入Broker
该项目的Github地址如下:
代码语言:javascript复制https://github.com/akamai-threat-research/mqtt-pwn
最好使用Docker的安装方式,pyenv有点问题,暴力破解的命令:
代码语言:javascript复制bruteforce --host host --port port -uf USERNAMES_FILE -pf PASSWORDS_FILE
默认用户和密码字典在mqtt-pwn的resources/wordlists文件夹中
MQTT-PWN还支持更多功能,如Owntracks (GPS Tracker)、Sonoff Exploiter等[5]
感兴趣的大家自己看下文档去进行测试
3. 嗅探账号密码
因为MQTT是基于TCP协议实现的,在流量传输的过程中并未考虑加密(这里是指的除去MQTTS之外,即不包含使用TLS的MQTTS),其实这样做也有利于降低客户端设备的成本,毕竟本来单片机算力就不高
假设我们现在和客户端设备位于同一个网络中,我们可以通过嗅探局域网流量(MIMT中间人攻击)来抓取账号密码
△ 图片来源:MQTT安全案例分享[6]
抓取到设备的账号密码后,我们就可以通过MQTT工具或者是MQTT-PWN连接到Broker进行下一步攻击
4. 从Web应用中获取账号密码
很多厂商为了展示自己的物联网设备,往往会开发一个展示屏幕,如这种:
△ 图片来源:some where
而这些展示的信息来源有部分可能是通过浏览器直接连接到MQTT Broker,订阅部分要展示的信息
通过查看请求信息或者是从F12中的network查看该页面是否有mqtt的连接操作等等,如果有就可以继续在js文件中搜索是否存在mqtt的地址、账号密码等信息
5. 硬件层面-固件提取
对于无法通过一般途径获取账号密码的客户端,我们可以通过提取设备的固件,对其逆向分析,然后把文件系统中的证书或是账号密码提取出来
然后我们就可以仿冒该设备连接到Broker,订阅/#【主题通配符】。或者是Broker中的ACL配置有问题,尝试是否可以控制其他设备等等
6. 中间人篡改消息
这个中间人和刚刚的账号密码嗅探虽然用的是同一种技术,但是这种方法是直接在流量中修改发送者发出消息
现在攻击者和客户端(发布者/订阅者)在同一个网络中,攻击者作为中间人代理客户端和Broker的通信[4]
假设攻击者想篡改将发布的主题名从"outTpoic"修改为"outTpuc",攻击者需要从流量中筛选出符合条件的报文进行修改,我们可以使用Etterfilter配合脚本来完成:
代码语言:javascript复制#owned.filter
if (ip.proto == TCP && tcp.dst == 1883 && ip.dst == 'IP Broker' &&search(DATA.data, "outTopic")) {
replace("outTopic", "outTopuc");
msg("payload replacedn");
}
权限控制问题
1. 登陆至订阅者
当我们通过上述方法登陆至Broker之后,我们可以订阅该broker的所有主题消息(使用/#,#是MQTT消息主题通配符),如下图所示
此外我们还编写了一个脚本用来提取所有发布者发送的消息,我们可以看到提取出来的信息包括姓名、电话、经纬度、昵称以及其他敏感信息等等【实验数据!!!】
2. 登陆至发布者
我们还可以对该系统中的主题进行分析,这里我们以路灯举例,路灯作为订阅者接收来自合法发布者的控制。如下图所示,如果我们冒充合法发布者对路灯进行恶意控制
此外,我们还可以冒充发布者发布更新固件指令,blah ... 下面我们来看个案例[6]
智慧大厦场景中存在和停车、安防、灯光、广播、会议、环境监测等相关的各类传感器,这些传感器将受控于网关,并利用网关将数据传输到云端呈现。在本案例中,MQTT的通信安全问题出现在智慧大厦的网关盒子中。 拓扑逻辑如下:
在MQTT的通信场景中,研究员在网关前端抓取TCP数据包,并通过盒子的平台控制盒子的Wi-Fi射频打开与关闭,发现其通信方式使用的是MQTT通信,其认证方式只用了用户名和密码。 基于之前的分析,发现只需要一条shell命令即可控制这个通信过程。事实证明,盒子的Wi-Fi指示灯成功被我们熄灭和点亮。 由于存在厂商相关的敏感信息,本章不再展示实图,有兴趣的朋友欢迎随时沟通交流。
Broker自身安全性问题
1. 默认账户口令
现在有很多开源的Broker实现,在国内较为出名的是EMQ X,它不仅提供高并发能力的集群特性还支持扩展插件机制。该项目还提供给用户一个可直观查看的web仪表盘,通过web界面可以管理设备与监控设备等等。
但该项目为了方便使用者,直接为web管理台设置了默认账号密码,很多厂商部署了EMQ X之后并不会修改默认账号密码,如下图:
通过shadon我们检索出18083端口且title中包含Dashboard的站点,可以使用默认口令尝试登陆【我没试!!!!!!求生欲强烈!!!】
2. XSS漏洞
现在很多Broker都支持WEB端管理,管理员可以直接通过浏览器查看client以及topic等信息。如果我们使用mqtt直接发送包含有xss的信息到Broker就可以直接绕过web端的防御
这里我们使用CVE-2020-13821做实验,首先本地搭建一个hivemq 4.3.2:
代码语言:javascript复制docker run -p 8080:8080 -p 1883:1883 hivemq/hivemq4:4.3.2
该Broker的用户名和密码为admin和hivemq,如下图所示:
我们使用hbmqq来发布一个消息,其中消息的内容随便输入,指定client-id为xss payload:
代码语言:javascript复制hbmqtt_pub --url mqtt://ip:port -t / -m 1 -i "<img src=x onerror=prompt(2);>"
再回到HiveMQ中的Clients功能页,点击Refresh Snapshot刷新所有MQTT会话:
Bingo,这里只是弹窗演示一下,实际攻击环境中可以更换为XSS平台的payload
3. 其他漏洞
现在MQTT Broker供应商越来越多,但是经过这几天的检索,发现漏洞其实并没有想象的那么多。但是很多攻击面是可以预见的,像是发布者发送消息到订阅者,Broker有可能将其存入数据库,如果没有做好转义,是否能够产生注入等等
这里也仅仅是提供一下思路,希望能够达到抛砖引玉的效果,如果师傅们发现什么好玩的漏洞,欢迎来《物联网IoT安全》公众号投稿
4 其他
MQTT在僵尸网络中的应用
MQTT在僵尸网络中应用这一思路最早是由Lucas和Neal在DEFCON24上提出[7],如下图所示
被控IoT设备即是发布者也是订阅者,僵尸设备发布关于设备自身运行状态到bot/status主题,同时订阅用于执行命令的bot/command主题
而C&C攻击者可以通过bot/command主题向设备发送指令,通过订阅bot/status主题获取每个设备的运行状态
5 防范措施
1. 使用MQTTS防止中间人攻击
2. 在MQTT Broker上启用Topic ACL
3. 尽量使用客户端证书作为设备身份凭证,以验证设备合法性
总之,MQTT协议在安全上做出了很多努力,但是使用者并不在意这些安全特性,可能是受限于硬件资源或是对于安全的不重视
如果想要了解更多MQTT的安全防范机制,可以访问
代码语言:javascript复制https://www.hivemq.com/mqtt-security-fundamentals/
以获得帮助
6 TODO
最近一直在使用MQTT-PWN,但感觉不是特别好用。希望有时间LMN师傅可以开发一个MQTT的漏洞利用套件【MQTT-SUIT】
7 参考引用
代码语言:javascript复制[1] MQTT: The Standard for IoT Messaging. Retrieved January 7, 2021, from https://mqtt.org/
[2] 郭朝斌.(2020, November 25). 物联网开发实战. 极客时间. Available January 7, 2021, from https://time.geekbang.org/column/article/312691
[3] MQTT 发布订阅模式介绍. Retrieved January 7, 2021, from https://www.emqx.io/cn/blog/mqtt-5-introduction-to-publish-subscribe-model
[4] MQTT Topic-based Message Routing. Retrieved January 7, 2021, from https://docs.emqx.io/en/enterprise/v3.0/mqtt.html
[5] Tiger-Team.(2020, July 31).物联网安全之MQTT协议安全. 安全课. Retrieved January 7, 2021, from https://www.anquanke.com/post/id/212335
[6] https://github.com/akamai-threat-research/mqtt-pwn
[7] L, Lundgren.(2016). Light Weight Protocol Serious Equipment Critical Implications. Defcon 24. Retrieved January 7, 2021, from https://www.defcon.org/html/defcon-24/dc-24-speakers.html
[8] S. Andy, B. Rahardjo and B. Hanindhito, "Attack scenarios and security analysis of MQTT communication protocol in IoT system," 2017 4th International Conference on Electrical Engineering, Computer Science and Informatics (EECSI), Yogyakarta, 2017, pp. 1-6, doi: 10.1109/EECSI.2017.8239179.
[9] D. Evans, “ The Internet of things: how the next evolution of the Internet is changing everything,” Cisco Internet Business Solution Group White Paper, April 2011.