Skip to content
HackIndex logo

HackIndex

MQTT Plaintext Transport Detection

3 min read Mar 16, 2026

MQTT on port 1883 transmits all data in plaintext including the CONNECT packet, which carries the username and password in the clear. Any passive observer on the network path between client and broker — including a compromised switch, a rogue access point, or an attacker on the same segment — can capture credentials and all message payloads. This is a distinct finding from missing authentication: even a broker that requires credentials is vulnerable if those credentials cross the wire unencrypted.

Confirm Port 1883 Accepts Connections

A response on port 1883 is sufficient to confirm plaintext transport is available:

┌──(kali㉿kali)-[~]
└─$ mosquitto_sub -h $TARGET_IP -p 1883 -t '#' --retained-only -C 1 -v 2>&1 | head -3

A CONNACK response on port 1883 — regardless of the return code — confirms the service is accepting connections without TLS. The protocol is running in plaintext.

Check whether TLS is available as an alternative on 8883:

┌──(kali㉿kali)-[~]
└─$ mosquitto_sub -h $TARGET_IP -p 8883 --insecure -t '#' --retained-only -C 1 -v 2>&1 | head -3

If 1883 is open and 8883 either refuses connections or is not open at all, clients have no encrypted path available.

Capture Credentials with tcpdump

On a network segment where you can observe traffic, capture the MQTT CONNECT packet to demonstrate credential exposure:

┌──(kali㉿kali)-[~]
└─$ sudo tcpdump -i any -w /tmp/mqtt-capture.pcap tcp port 1883 &

Trigger a client connection (or wait for an existing client to reconnect), then stop the capture:

┌──(kali㉿kali)-[~]
└─$ kill %1

Inspect the capture for MQTT CONNECT packets:

┌──(kali㉿kali)-[~]
└─$ tcpdump -r /tmp/mqtt-capture.pcap -A 2>/dev/null | grep -A 5 "MQTT"

The CONNECT packet payload contains the username and password as length-prefixed strings in plaintext. They appear directly readable in the packet bytes.

Decode a CONNECT Packet Manually

An MQTT CONNECT packet on the wire has a recognisable structure. The first two bytes after the fixed header are 00 04 followed by 4d515454 (ASCII "MQTT"), protocol level, connect flags, keepalive, and then the payload containing ClientID, username, and password.

In Wireshark, filter with mqtt and expand the CONNECT packet — username and password fields are decoded and displayed in plaintext.

Check Whether Clients Are Using 1883

If you have a shell on the target or observe internal traffic, check whether live clients are connecting over 1883:

┌──(kali㉿kali)-[~]
└─$ ss -tnp | grep 1883
┌──(kali㉿kali)-[~]
└─$ netstat -tnp | grep 1883

Active connections on 1883 confirm production clients are using the unencrypted port.

Document the Finding

Record:

  • Port 1883 accepts connections (plaintext confirmed)

  • Whether TLS is available at all on 8883

  • Whether authentication is in use — plaintext auth is worse than plaintext anonymous

  • Whether the broker is internet-facing or internal only (affects severity)

Plaintext transport combined with credential-based authentication means every authentication event leaks the password to any network observer.

References