|WHAT?在很多IOT设备中默认存在MQTT服务,这是一个值得关注的攻击面。下面对MQTT协议及其挖掘思路进行分析。
MQTT是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的发布、订阅信息传输协议。可在不可靠的网络环境中进行扩展,适用于设备硬件存储空间或网络带宽有限的场景。使用MQTT协议,消息发送者与接收者不受时间和空间的限制。物联网平台支持设备使用MQTT协议接入。
实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。
MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:
(1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);
(2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容。
|开源实现项目 Mosquitto大部分设备中的MQTT协议实现是基于Mosquitto 改的,如果开源项目本身存在漏洞的话,将影响大部分设备的MQTT组件。下面简单分析下Mosquitto的实现和我们能够接触到的攻击面
基本启动方式流程模块:websocket.c -> read_handle.c
在switch case LWS_CALLBACK_RECEIVE:
在handle_connect和authentic相关的时候,会执行mosquitto_security_auth_start,通过返回值rc确定数据流
其中mosquitto_security_auth_start 调用auth_start_v4相关
由此可知这个方法恒定返回MOSQ_ERR_SUCCESS,之后会调用到connect__on_authorised,里面的connection_check_acl再调用mosquitto_acl_check函数对权限进行检测
之后的mosquitto_acl_check函数会去配置信息,再根据策略去执行相关的认证函数。
网络net处理数据包net__socket_accept()函数
mux_epoll__handle()函数
最终来自main函数调用的mosquitto_main_loop
回到生成sock本身,最后调用的是epoll_ctrl(epoll库)来生成
在callback_mqtt() 中:case LWS_CALLBACK_RECEIVE
case LWS_CALLBACK_RECEIVE:数据赋值的地方
可惜定死了mosq->in_packet.to_process
比较明显的攻击面就是Mosquitto本身和自定义的topic。未授权的情况下,组件本身的漏洞产生的点可能来自于数据流的处理,认证相关,如果存在弱密码或者配置文件认证信息写死的情况下,还可以关注topic的攻击面。
MQTT主要有两大版本:v3 和 v5,
MQTT v3 不支持 auth,所以遇到这种版本的相当于可以直接看topic的攻击面
Mosquitto本身下面介绍一些Mosquitto的历史漏洞
(1)CVE-2021-34434NULL point漏洞,该漏洞是授权后的一个数据请求导致的。Client在连接之后可以在数据包中指定context->in_packet.command,handle__packet函数会根据命令执行相应的函数,如果是CMD_CONNACK命令,将会步入handle__connack函数中。下图是patch后的代码,可以看出添加了对NULL的检查,如果没有检查的情况下,之后调用context->bridge->name会异常崩溃。
漏洞函数是acl__check_single,由mosquitto_acl_check函数引用,前面提到,mosquitto_acl_check是认证权限相关的函数。当username 带有+#,可以绕过认证check。下图是patch后的代码,添加了对+#的检查
Broker 创建alc 文件可以指定权限配置
user admin漏洞产生的原因和这个样式有关。
(3)CVE-2017-7651mosquitto__calloc()这类型的的函数是自定义的内存分配函数,patch的地方就是限制了size,如果在没有限制size的情况,通过大量发包,可能导致资源占用过大dos
这个内存分配函数在前期接收数据包并生成mosquitto context的时候会调用,所以这是一个未授权就可以触发的漏洞。下图是patch后的代码,可以看到添加了大小限制。
把mqtt问题转变成http问题:
Topic = url为了更好的理解sub和pub的关系及其topic的攻击面,可以阅读下面的例子。
在发布者像broker发布(pub)消息的时候,订阅者会接收(sub)到消息并执行回调(callback)函数。所以攻击者就相当于发布者的身份,被攻击的目标就是订阅者的身份,所以自定义topic的攻击面就是订阅者的回调函数。通过到了相应的路由,那么漏洞类型和http相关的类型差不多,可能涉及到逻辑漏洞、命令注入、溢出等。
Python实现的小例子本文介绍了MQTT协议和MQTT协议的开源实现Mosquitto,很多设备的mqtt组件都是基于Mosquitto改的,当然还有些是自定义实现的。不管是哪种,我们去挖掘其攻击面无非还是挖掘组件本身和路由(topic),挖掘的过程可以借鉴Mosquitto的代码和它的框架类型,快速地找到相应的逻辑代码。在实际挖掘过程中发现有些设备的mqtt组件存在协议版本过久和一些配置文件写死的情况,在这种情况下topic的攻击面将大大增加。
代码审计万变不离其宗:字符串大法好!映射函数有可能在so中,也可能在别的service bin中(根据改写的方式而定),所以如果在单个bin中找不到相应的逻辑,需要在大目录下搜索相关字符串,找到映射路由topic/function ,就可以对应审计了。
比如:
思路相通,和http fuzz差不多,还是需要通过逆向找到相应的topic,然后和http fuzz一样怼着topic去发送变异数据包。
欢迎光临 谷动谷力 (http://bbs.sunsili.com/) | Powered by Discuz! X3.2 |