hacktricks/src/network-services-pentesting/1883-pentesting-mqtt-mosquitto.md

114 lines
5.8 KiB
Markdown

# 1883 - Pentesting MQTT (Mosquitto)
{{#include ../banners/hacktricks-training.md}}
## Podstawowe informacje
**MQ Telemetry Transport (MQTT)** jest znany jako **protokół komunikacyjny typu publish/subscribe**, który wyróżnia się swoją ekstremalną prostotą i lekkością. Protokół ten jest specjalnie dostosowany do środowisk, w których urządzenia mają ograniczone możliwości i działają w sieciach charakteryzujących się niską przepustowością, dużą latencją lub niestabilnymi połączeniami. Główne cele MQTT obejmują minimalizację wykorzystania przepustowości sieci oraz redukcję zapotrzebowania na zasoby urządzeń. Dodatkowo, ma na celu utrzymanie niezawodnej komunikacji i zapewnienie pewnego poziomu gwarancji dostarczenia. Cele te sprawiają, że MQTT jest wyjątkowo odpowiedni dla rozwijającej się dziedziny **komunikacji maszyna-do-maszyny (M2M)** oraz **Internetu Rzeczy (IoT)**, gdzie kluczowe jest efektywne łączenie wielu urządzeń. Ponadto, MQTT jest bardzo korzystny dla aplikacji mobilnych, gdzie oszczędzanie przepustowości i żywotności baterii jest kluczowe.
**Domyślny port:** 1883
```
PORT STATE SERVICE REASON
1883/tcp open mosquitto version 1.4.8 syn-ack
```
## Inspecting the traffic
Gdy brokerzy MQTT otrzymują pakiet **CONNECT**, wysyłany jest pakiet **CONNACK**. Pakiet ten zawiera kod zwrotny, który jest kluczowy dla zrozumienia statusu połączenia. Kod zwrotny **0x00** oznacza, że dane uwierzytelniające zostały zaakceptowane, co oznacza udane połączenie. Z drugiej strony, kod zwrotny **0x05** sygnalizuje, że dane uwierzytelniające są nieprawidłowe, co uniemożliwia połączenie.
Na przykład, jeśli broker odrzuci połączenie z powodu nieprawidłowych danych uwierzytelniających, scenariusz wyglądałby mniej więcej tak:
```
{
"returnCode": "0x05",
"description": "Connection Refused, not authorized"
}
```
![](<../images/image (976).png>)
### [**Brute-Force MQTT**](../generic-hacking/brute-force.md#mqtt)
## Pentesting MQTT
**Uwierzytelnienie jest całkowicie opcjonalne** i nawet jeśli uwierzytelnienie jest wykonywane, **szyfrowanie nie jest domyślnie używane** (dane uwierzytelniające są wysyłane w postaci niezaszyfrowanej). Ataki MITM mogą nadal być przeprowadzane w celu kradzieży haseł.
Aby połączyć się z usługą MQTT, możesz użyć: [https://github.com/bapowell/python-mqtt-client-shell](https://github.com/bapowell/python-mqtt-client-shell) i subskrybować się do wszystkich tematów, 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**](https://github.com/akamai-threat-research/mqtt-pwn)
Możesz także użyć:
```bash
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.
```
Lub możesz **uruchomić ten kod, aby spróbować połączyć się z usługą MQTT bez uwierzytelnienia, subskrybować każdy temat i ich słuchać**:
```python
#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 Publikacji/Subskrypcji <a href="#b667" id="b667"></a>
Model publikacji/subskrypcji składa się z:
- **Publisher**: publikuje wiadomość do jednego (lub wielu) tematów w brokerze.
- **Subscriber**: subskrybuje jeden (lub wiele) tematów w brokerze i otrzymuje wszystkie wiadomości wysyłane przez publishera.
- **Broker**: kieruje wszystkimi wiadomościami od publisherów do subskrybentów.
- **Topic**: składa się z jednego lub więcej poziomów oddzielonych ukośnikiem (np. /smartshouse/livingroom/temperature).
### Format Pakietu <a href="#f15a" id="f15a"></a>
Każdy pakiet MQTT zawiera stały nagłówek (Rysunek 02). Rysunek 02: Stały Nagłówek
![https://miro.medium.com/max/838/1*k6RkAHEk0576geQGUcKSTA.png](https://miro.medium.com/max/838/1*k6RkAHEk0576geQGUcKSTA.png)
### Typy Pakietów
- CONNECT (1): Inicjowany przez klienta w celu zażądania połączenia z serwerem.
- CONNACK (2): Potwierdzenie serwera o udanym połączeniu.
- PUBLISH (3): Używany do wysyłania wiadomości z klienta do serwera lub odwrotnie.
- PUBACK (4): Potwierdzenie pakietu PUBLISH.
- PUBREC (5): Część protokołu dostarczania wiadomości zapewniająca, że wiadomość została odebrana.
- PUBREL (6): Dalsze zapewnienie w dostarczaniu wiadomości, wskazujące na zwolnienie wiadomości.
- PUBCOMP (7): Ostatnia część protokołu dostarczania wiadomości, wskazująca na zakończenie.
- SUBSCRIBE (8): Żądanie klienta do nasłuchiwania wiadomości z tematu.
- SUBACK (9): Potwierdzenie serwera o żądaniu SUBSCRIBE.
- UNSUBSCRIBE (10): Żądanie klienta o zaprzestanie otrzymywania wiadomości z tematu.
- UNSUBACK (11): Odpowiedź serwera na żądanie UNSUBSCRIBE.
- PINGREQ (12): Wiadomość sygnalizacyjna wysyłana przez klienta.
- PINGRESP (13): Odpowiedź serwera na wiadomość sygnalizacyjną.
- DISCONNECT (14): Inicjowany przez klienta w celu zakończenia połączenia.
- Dwie wartości, 0 i 15, są oznaczone jako zarezerwowane, a ich użycie jest zabronione.
## Shodan
- `port:1883 MQTT`
{{#include ../banners/hacktricks-training.md}}