长亭百川云 - 文章详情

MQTT安全初探

物联网IoT安全

57

2024-07-13

文 年华 | 图 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的官方手册,这里不再赘述

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路径,例如:

chat/room/1

主题(Topic)通过'/'分割层级,支持'+', '#'通配符:

'+': 表示通配一个层级,例如a/+,匹配a/x, a/y   

订阅者可以订阅含通配符主题,但发布者不允许向含通配符主题发布消息[4]

2 MQTT体验

既然要搞MQTT,怎么可以连工具都没有呢?这里我们直接使用hbmqtt这个库来模拟MQTT client,安装方式很简单,直接pip

pip3 install hbmqtt

这里我们使用eclipse提供的免费broker进行测试,地址如下:

mqtt.eclipseprojects.io

△  图片来源:mqtt.eclipseprojects.io

它提供了四种mqtt连接方式,今天我们主要来看看不加密的TCP连接方式,即常见的1883端口

我们打开一个终端,订阅/nianhua/iotsecurity这个主题消息:

hbmqtt_sub --url mqtt://mqtt.eclipseprojects.io:1883 -t /nianhua/iotsecurity

打开另一个终端,通过hbmqtt_pub发布一个/nianhua/iotsecurity主题的消息

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客户端

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地址如下:

https://github.com/akamai-threat-research/mqtt-pwn

最好使用Docker的安装方式,pyenv有点问题,暴力破解的命令:

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配合脚本来完成:

#owned.filter

权限控制问题

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:

docker run -p 8080:8080 -p 1883:1883 hivemq/hivemq4:4.3.2

该Broker的用户名和密码为admin和hivemq,如下图所示:

我们使用hbmqq来发布一个消息,其中消息的内容随便输入,指定client-id为xss payload:

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的安全防范机制,可以访问

https://www.hivemq.com/mqtt-security-fundamentals/

以获得帮助

6 TODO

最近一直在使用MQTT-PWN,但感觉不是特别好用。希望有时间LMN师傅可以开发一个MQTT的漏洞利用套件**【MQTT-SUIT】**

7 参考引用

[1] MQTT: The Standard for IoT Messaging. Retrieved January 7, 2021, from https://mqtt.org/

手把手带你搭建钓鱼Wi-Fi热点[1]

利用区块链技术保障IoT安全

智能汽车安全入门|世界智能驾驶挑战赛总结

初识物联网安全

骚姿势获取无线路由器后台权限

[

Cobalt Strike|DNS Beacon

](http://mp.weixin.qq.com/s?__biz=MzUzMjcxMzg5Mg==&mid=2247485700&idx=1&sn=87ee6bd6b36dd7583b8b9f7ffa54054a&chksm=faae51cfcdd9d8d9aae235e3928e0ce4e669da3e188a2cd69e75b238b2f5abfd67f8f7a05c2c&scene=21#wechat_redirect)

广告时间

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2