IoT Pentesting 101: How to Hack MQTT – The Standard for IoT Messaging

As almost every industry uses at least one of those tiny embedded devices called Smart Things, I think that it might be the right time to start a series of IoT Pentesting and Hacking. As every IoT device has to be connected to the Internet, I want to briefly introduce you to the MQTT Protocol or the Standard for IoT Messaging.

How Does It Work?

MQTT (Message Queuing Telemetry Transport) is a lightweight machine-to-machine (M2M) protocol that uses publish/subscribe messaging model.

In MQTT a publisher publishes messages on a topic and a subscriber must subscribe to that topic to view the message. Messages are published to a broker on a topic. The job of an MQTT broker is to filter messages based on topic, and then distribute them to subscribers.

Source: https://mqtt.org/

Create a Test Environment That Mimics a Real IoT Environment

If you already have an environment set up, you can skip this and go straight to the Common MQTT Attacks section.

It is a fact that most of the IoT devices are not as affordable as we would want to, but don’t be scared. The MQTT Protocol can be used without the need for an actual device, but by using an open-source server (broker) called Mosquitto. With Mosquitto, you can deploy brokers and mimic the publisher’s and the subscriber’s actions as if there is a real IoT infrastructure involved. With all of that being said, let’s find out how to deploy such an IoT infrastructure.

Deploy the Mosquitto broker (server)

The easiest method to deploy the Mosquitto broker is to use its Docker image. Before creating the actual container, we have to make some adjustments first. You have to create the following three directories, log, data, and config. Once you’ve done that, download the mosquitto.conf file and place it under the config directory:

wget https://raw.githubusercontent.com/eclipse/mosquitto/master/mosquitto.conf

Open the config file with your preferred editor and add the following lines at the end of it.

persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

By default, the mosquitto server accepts connections only from the local machine. To be able to subscribe or publish from remote devices, and also allow unauthenticated access, we have to uncomment the following lines:

# listener 1883 0.0.0.0
# allow_anonymous true

If you were able to follow the above steps, you are ready to deploy the image by using the following command:

docker run -it -p 1883:1883 -p 9001:9001 -v /home/st3v3nss/Data/mosquitto/:/mosquitto/ eclipse-mosquitto

Test The Environment

Once the Mosquitto server is up and running, you have to spawn two other shells, one for the subscriber and one for the publisher. The subscriber listens for any topic updates, and the publisher sends update messages to a specific topic.

#subscribe to every topic
mosquitto_sub -v -t '#' -h 127.0.0.1

#send message to specific topic
mosquitto_pub -t '/home/room1/light-sensor' -m "Light on" -h 127.0.0.1 

The entire flow can be seen in the following screenshot:

Before starting with the actual MQTT vulnerabilities and exploits, let’s first create some traffic that would aid us in the further steps. We can send retained messages by appending the -r flag to the mosquitto_pub command as shown below:

mosquitto_pub -t 'updates' -h 127.0.0.1 -m "{\"d\": \"$(date)\"}" -r

The following bash script can be used to send unlimited updates to the broker server.

#!/bin/bash

while :
do
    mosquitto_pub -t 'updates' -h 127.0.0.1 -m "{\"d\": \"$(date)\"}" -r
    sleep 5
    mosquitto_pub -t 'updates' -h 127.0.0.1 -m "{\"d\": \"$(date)\"}" -r
    sleep 5
    mosquitto_pub -t "updates" -h 127.0.0.1 -m "{\"d\": \"^FLAG{Th1s_1s_n0t_0K}$\"}"
    sleep 3
done

Common MQTT Attacks

Broker Reconnaissance and Fingerprinting

As every IoT pentest starts with the reconnaissance step, we will begin by scanning the in-scope asset.

nmap -sV -sC -p- -v 127.0.0.1

Having the discovered broker’s port, 1883, the software used, mosquitto, and its version 2.0.11, we can advance with our reconnaissance phase. From the nmap output, we can observe the topics used by this broker such as test and updates. Our aim is to find as much information as possible, so we can try to subscribe to those topics and listen for updates, as there is no authentication mechanism in place (we were able to obtain the retained messages).

mosquitto_sub -t '#' -h 127.0.0.1 -v

The above screenshot shows that anyone, including unauthorized threat actors, can subscribe to vulnerable MQTT topics and listen for sensitive data.

Dictionary Attacks and Brute-Force

When the mosquitto server is configured to accept only authenticated users, thus enhancing the security of the broker server, attackers can still perform brute-force attacks and obtain valid credentials that would allow them to successfully authenticate on the vulnerable server.

Modifying the Environment

To able to reproduce this vulnerability, we have to modify our mosquitto.conf file so that it requires authentication in order to subscribe or publish to topics.

First, set the allow_anonymous to false, then locate the password_file line and replace it with the following password_file /mosquitto/config/password_file.txt. Next, use the mosquitto_passwd password_file.txt username to add new users. After all of that, the password_file.txt would look like this:

admin:$7$101$wrIksuXk2pWsb8Mk$xxo7hz+V8ZNq0kfy/FKJ2+O7zMvl4eaxzCooYOrTfXb4ndbQ8a97h83njQsLhXzts33eBp0XcLEv7rOZAGtnXw==
user:$7$101$Rb4YYrkQyULF2F8M$QhiZ1PFMlzflNQDYnKDEDCkTf32yJ7X5PMYe6rfcX+MKXpoFPGDjiFM5mOW3G+zN5H27+4Q2Gzq2zHnq4RpMhw==
root:$7$101$ClDqbY9E5weFf+qx$POzDaO1HuPixGzu/9XEhg57TOdNT0CgscKLeSooOEPkRBbvnHvz3rYvancKlKTG6n8bHrzcAb6rqHJriqqDs9w==
test:$7$101$lSbyxGqYLs+aE+u8$amt1xM63puWfKQ5DbydhMkrbJdRsK0vi5sL4yfUBSOVhSeoiWMSQ+mEaDLT1JF+Rh/I3uM6j5PvhLYBGRg9upw==

Dictionary Attack Using Metasploit

In IoT Pentesting, as in every pentest, Brute-Force and Dictionary attacks occurs due to missing rate-limiting mechanism and poorly configured authentication. Breaking a simple authentication mechanism, such as using a username and a weak password for connecting to the mosquitto server, might allow attackers to obtain access to hidden functionalities or perform account takeovers. We can exploit that by using Metasploit’s module called auxiliary/scanner/mqtt/connect. For this, I created simple wordlists containing some users and passwords used for authentication.

msf6 > use auxiliary/scanner/mqtt/connect
msf6 auxiliary(scanner/mqtt/connect) > set PASS_FILE /tmp/passwords.txt
msf6 auxiliary(scanner/mqtt/connect) > set USER_FILE /tmp/users.txt

Once we have all set, we can run the exploit and discover weak valid credentials used for MQTT authentication.

Metasploit module show options
Running the exploit

To test the credentials, we can subscribe to any topic and intercept sensitive data that might be sent. Furthermore, we can also send malicious data that might trigger alerts and errors to IoT subscribers.

DoS Attacks Using Known CVE

In almost every pentest assessment, conducting Denial of Service attacks is strictly forbidden as it crashes the software and denies access to it. While pentesting IoT devices, you will often come across outdated and vulnerable software with publicly known vulnerabilities. In such cases, you’ll only need proof of the software’s version to indicate that it might be vulnerable. If the Company is willing to take the risk of such an attack, you can use any of the two known CVEs for the Mosquitto server.

CVE-2017-7651

The Mosquitto version 1.4.14 is prone to Denial of Service Attacks simply by filling the RAM memory with a lot of connections with a large payload. This can be done without authentications if occur in the connection phase of the MQTT protocol.

If the user starts the connection and sends 80% of a big payload and then keeps a low transfer rate for the connection not to be closed, with repeated actions the server’s RAM memory ends and the O.S. kills the process for Out of Memory (OOM).

You can find the source code of the exploit written by Felipe Balabanian on my GitHub, alongside the compiled binary.

The mosquitto version can be downloaded from https://mosquitto.org/files/source/mosquitto-1.4.14.tar.gz and compiled using the make command. Once we set up the vulnerable server and launched the exploit, the server will crash after a couple of minutes.

CVE-2018-12543

Mosquitto versions 1.5 to 1.5.2 are prone to Denial of Service by publishing to a topic that starts with $ but that is not $SYS, e.g. $TEST.

The mosquitto version can be downloaded from https://mosquitto.org/files/source/mosquitto-1.5.1.tar.gz and compiled using the make command. Once the server is up and running, use the below command to crash the mosquitto server.

mosquitto_pub -h 127.0.0.1 -t '$TEST' -m "message"

Summary

This was a brief introduction to the IoT Pentesting that presented the very basic information about the MQTT Protocol, the top-most used networking protocol by the IoT devices due to its simplicity. The covered area included the deployment of dummy environments and common attacks such as Dictionary attacks and publicly known CVEs. There are many more issues to be explained in future articles, so stay put and wait for IoT Pentesting 101: Deploying And Exploiting Dummy ICS Environments using Node-RED.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s