Skip to content

MQTT Service Detection and Version Identification

3 min read Created Mar 16, 2026 Last updated Mar 16, 2026

MQTT brokers listen on TCP 1883 for plaintext and TCP 8883 for TLS. Neither port is universally standard: embedded devices and IoT deployments frequently use non-standard ports or run brokers on localhost only. The first step is confirming the service is present, that it speaks MQTT, and what implementation is running.

Nmap Service Detection

┌──(kali㉿kali)-[~]
└─$ nmap -sV -p 1883,8883 $TARGET_IP
PORT     STATE SERVICE  VERSION
1883/tcp open  mqtt     Mosquitto mqttd 1.6.9
8883/tcp open  ssl/mqtt Mosquitto mqttd 1.6.9

Nmap's service detection recognises MQTT by the CONNECT/CONNACK handshake. A version string in the output identifies the broker software. Common implementations you will encounter:

  • Mosquitto: most common on Linux targets
  • HiveMQ: enterprise Java broker, community and commercial editions
  • EMQX: Erlang-based, common in large-scale IoT deployments
  • VerneMQ: Erlang-based, clustered deployments
  • RabbitMQ with MQTT plugin: general-purpose message broker with MQTT support

Scan common alternative ports:

┌──(kali㉿kali)-[~]
└─$ nmap -sV -p 1883,8883,1884,8884,11883 $TARGET_IP

Confirm with Mosquitto Client

The mosquitto_sub client attempts a CONNECT and reports the broker's CONNACK response code, which tells you immediately whether anonymous access is permitted:

┌──(kali㉿kali)-[~]
└─$ mosquitto_sub -h $TARGET_IP -p 1883 -t '#' --retained-only -C 1 -v 2>&1 | head -5
Client mosqsub|12345-kali sending CONNECT
Client mosqsub|12345-kali received CONNACK (0)

CONNACK return code 0 means connection accepted. Any non-zero code means the connection was refused: the reason tells you more:

Code

Meaning

0

Accepted

1

Unacceptable protocol version

2

Identifier rejected

3

Server unavailable

4

Bad username or password

5

Not authorised

Code 4 or 5 confirms authentication is required. Code 0 without supplying credentials confirms anonymous access: a vulnerability finding covered in MQTT Unauthenticated Access.

Confirm TLS on 8883

Check whether 8883 enforces TLS and note the certificate details:

┌──(kali㉿kali)-[~]
└─$ openssl s_client -connect $TARGET_IP:8883 -quiet 2>/dev/null | head -10
depth=0 CN=mosquitto
verify error:num=18:self-signed certificate
Certificate chain...

A self-signed certificate is common on embedded deployments. Note the CN and expiry: they sometimes reveal hostnames or internal domain names.

Connect over TLS without verifying the certificate:

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

--insecure skips certificate validation, which is required for self-signed certs.

Identify Protocol Version

MQTT has versions 3.1, 3.1.1, and 5.0. The version affects available features and how the broker handles malformed packets. Force a specific version to test support:

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

If version 5 is rejected (CONNACK code 1) but 3.1.1 is accepted, note this: version 5 has better authentication controls and its absence is relevant for the security posture.

References