Blog Details

Introduction to MQTT and Setting Up a Lab for MQTT Pentesting on MacOS

Introduction to MQTT and Setting Up a Lab for MQTT Pentesting on MacOS

What is MQTT

MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol designed for communication between applications and devices, especially in IoT (Internet of Things) systems. It supports a wide range of platforms, including web applications, desktop apps, mobile apps (Android and iOS), cloud services, and embedded systems.It operates on a publish/subscribe model, enabling devices to send and receive messages through a central server known as a broker. This means that with the protocol, you can exchange messages between devices to trigger actions and facilitate communication.

Let’s take an example

Suppose there is a robot and an application. With the help of the app, the robot can perform actions like move, stop, and more. The app sends commands like “move” or “stop” to the robot using MQTT. When the robot receives the message through the MQTT protocol, it executes the corresponding action.This is how MQTT is used for communication between IoT devices and applications, enabling devices to perform actions based on messages received.

MQTT Components Explained (With Robot Example)

  • Broker: Acts as the middleman that routes messages — for example, taking commands from the app and passing them to the robot.
  • Publisher: The sender of messages — for example, a mobile app publishing or sending command“move forward” to the robot.
  • Subscriber: The receiver of messages — the robot subscribes to a topic like robot/1/move to receive commands and that’s why when app sends command to move forward, robot receive this command and robot takes corresponding action.
  • Client: Any device that uses MQTT — both the app and the robot are clients; one publishes, the other subscribes.
  • Topic: It’s like the address where messages are sent or received. For example, if there are 3 robots, each robot listens (subscribes) to its own topic. When a message send/publish to their topic, they know,which robot to perform their specific action.
  • Message: The data payload being transmitted — such as { "command": "move_forward" }.
  • Session: Represents the connection state — starts when the robot connects and ends when it disconnects.
  • QoS (Quality of Service): QoS defines how reliably the message should be delivered between the publisher, broker, and subscriber. MQTT offers three levels of QoS: —
  • QoS 0 — Sends the message once with no guarantee; fastest but least reliable.
  • QoS 1 — Ensures the message arrives at least once; may be delivered more than once.
  • QoS 2 — Guarantees the message is delivered only once; most reliable but slowest.
  • Retained Message: The last message stored by the broker on a topic — useful so that if the robot connects later, it still receives the latest command.

MQTT vs HTTP: A Quick Comparison

  • MQTT (Lightweight) vs HTTP (Heavier)
  • Protocol Type: MQTT uses a Publish/Subscribe model, while HTTP uses a Request/Response model.
  • Connection Model: MQTT maintains a persistent (long-lived) connection, whereas HTTP is stateless, opening a new connection per request.
  • Message Size: MQTT messages are small and binary, while HTTP messages are larger and text-based (headers, body, etc.).
  • Bandwidth Usage: MQTT consumes very low bandwidth; HTTP uses more bandwidth.
  • Overhead: MQTT has minimal overhead; HTTP has high overhead due to headers and TCP handshakes.
  • Communication Direction: MQTT supports bi-directional communication; HTTP is typically unidirectional (client to server).
  • Power Consumption: MQTT is low-power, ideal for battery-based devices; HTTP has higher power usage due to frequent connections.
  • Speed / Latency: MQTT offers fast, low-latency messaging; HTTP is slower due to repeated connection setup/teardown.
  • Designed For: MQTT is ideal for IoT, mobile, and embedded devices; HTTP is suited for web apps, browsers, and APIs.
  • Offline Support: MQTT supports offline capabilities like retained messages and Last Will & Testament (LWT); HTTP does not.
  • Security: MQTT supports TLS, username/password, and certificates; HTTP relies on TLS/SSL (HTTPS).
  • Examples: MQTT is used in smart home devices, robots, telemetry systems; HTTP powers web browsers, REST APIs, and file transfers.

How to Set Up a Lab for MQTT Pentesting: Step-by-Step Guide

MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe messaging protocol widely used in IoT ecosystems — from smart home devices to industrial automation. This guide will walk you through setting up a lab environment for MQTT pentesting, including broker/client setup, traffic analysis, and solving Docker connectivity issues.

Lab Components

To perform MQTT pentesting, you’ll need the following:

  1. MQTT Broker — The server that routes messages (we’ll use Eclipse Mosquitto).
  2. MQTT Clients — To subscribe and publish messages (we’ll use mosquitto_pub and mosquitto_sub).

Step 1: Set Up the MQTT Broker

We’ll run the broker inside a Docker container using the official Eclipse Mosquitto image.

docker pull eclipse-mosquitto

Press enter or click to view image in full size

docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto

Press enter or click to view image in full size

Step 2: Install MQTT Clients

Install Mosquitto clients on your host machine (MacOS):

brew install mosquitto

Press enter or click to view image in full size

Step 3: Subscribe & Publish to a Topic

Subscribe to a Topic (Terminal 1)

mosquitto_sub -h localhost -t robot/1/move

This command will stay in a waiting state until it receives a message from a publisher.

Press enter or click to view image in full size

Publish a Topic (Terminal 2)

mosquitto_pub -h localhost -t robot/1/move -m “move_forward”

Press enter or click to view image in full size

If everything is working correctly, Terminal 1 should display:

Press enter or click to view image in full size

Issue Faced: No Message Received?

If you’re running Mosquitto inside Docker on macOS, you might notice that messages don’t appear in the subscriber terminal. Why?

Root Cause:

By default, Docker isolates the container’s network. So your host’s MQTT client (running on localhost) cannot directly communicate with the broker inside Docker.

Press enter or click to view image in full size

Monitoring MQTT Broker Logs (Troubleshooting with Docker)

During pentesting or lab setup, it’s common to run into issues where the MQTT clients fail to connect to the broker or messages aren’t delivered. To debug these issues effectively, you’ll want to inspect the Mosquitto broker logs.


Since our broker is running inside a Docker container, we can use Docker’s built-in logging commands to view real-time output.

Step 1: View Container Logs

Docker assigns a random name to containers if you don’t specify one. For example, your container might be named agitated_fermi.

To view all log output from that container:

docker logs agitated_fermi

Press enter or click to view image in full size

Step 2: Solution: Allow External Connections in mosquitto.conf

We need to provide a custom configuration file that:

  1. Explicitly sets a listener on port 1883
  2. Allows anonymous clients (for lab testing)

Step 3:Run the Broker with Custom Config

Now run the container with this config mounted inside:

docker run -it \
— name mqtt-broker \
-p 1883:1883 \
-v /Users/vaishali/mosquitto.conf:/mosquitto/config/mosquitto.conf \
eclipse-mosquitto

Press enter or click to view image in full size

Now if you publish a message it will work properly and displayed on sibscriber terminal.

Step 3:: Capture MQTT Traffic with Wireshark

Problem:

Wireshark on macOS cannot directly capture Docker container traffic using its default interfaces.

Solution: Capture Traffic Inside the Container

We’ll use tcpdump inside the Docker network and then import the capture into Wireshark.

Step-by-step:

  1. Run a sniffer container on the same network as the broker:

docker run -it — net container:mqtt-broker — name mqtt-sniffer ubuntu bash

Press enter or click to view image in full size

2. Install tcpdump in the container:

apt update && apt install tcpdump -y

Press enter or click to view image in full size

3. Capture MQTT traffic:

tcpdump -i any port 1883 -w /tmp/mqtt_traffic.pcap

Press enter or click to view image in full size

4. In a new terminal, copy the capture file to your host:

docker cp mqtt-sniffer:/tmp/mqtt_traffic.pcap ./mqtt_traffic.pcap

Press enter or click to view image in full size

5. Open it in Wireshark on your host:

Press enter or click to view image in full size

Apply a filter to display only MQTT traffic in the capture.

Press enter or click to view image in full size

Real-World vs Lab: Capturing MQTT Traffic

In our lab environment, we’re using Docker to run the MQTT broker — which creates a bit of complexity when it comes to capturing network traffic. Since Docker on macOS uses a virtualized network interface, we can’t directly capture MQTT packets with Wireshark from the host system.

To work around this, we capture the traffic inside the Docker network using tcpdump, then export the capture file (.pcap) and analyze it with Wireshark.

However, in a real-world scenario, you typically don’t need this workaround.

In Real Attacks (or Live Environments)

If the MQTT broker is running on a physical device or VM connected to the same network (e.g., an IoT gateway, server, or router), then:

  • You can capture traffic directly on the network interface (like Wi-Fi or Ethernet) using Wireshark.
  • No need to export or copy files from containers — just listen on the correct interface and apply a filter like: tcp.port == 1883 , mqtt

If the MQTT broker is hosted on a physical device or VM connected to a different network — such as when you’re controlling a smart device located in another city using a mobile app — the traffic typically won’t appear in Wireshark, since it doesn’t pass through your local network interface. However, if you’re using a browser or app based MQTT client and have configured Burp Suite as your proxy, you can still inspect the MQTT communication in Burp’s WebSocket tab, as it captures traffic directly from their.

This makes things faster and closer to how an attacker or pentester would operate in the field — monitoring live MQTT traffic as it flows between devices and the broker.

Conclusion

In this blog, we focused on setting up a practical MQTT pentesting lab using Docker, configuring the Mosquitto broker, and capturing MQTT traffic effectively — even dealing with challenges like Docker’s networking on macOS.

We demonstrated how to:

  • Run the MQTT broker with a custom config to allow anonymous connections
  • Subscribe and publish messages with MQTT clients
  • Capture MQTT traffic using tcpdump inside Docker and analyze it in Wireshark
  • Understand real-world traffic capture limitations and scenarios

What’s Next?

In the next blog, we’ll dive deeper into common MQTT attacks and vulnerabilities, exploring:

  • How to identify and exploit insecure MQTT configurations
  • Attacks like topic hijacking, message spoofing, and authentication bypass
  • Enhancing our lab environment to simulate and defend against these attacks

Stay tuned to learn how to turn your MQTT lab into a powerful pentesting playground and sharpen your IoT security skills!