1883 - Pentesting MQTT (Mosquitto)

Support HackTricks

基本情報

MQ Telemetry Transport (MQTT) は、極めてシンプルで軽量なパブリッシュ/サブスクライブメッセージングプロトコルとして知られています。このプロトコルは、デバイスの能力が限られている環境や、低帯域幅、高遅延、または信頼性の低い接続が特徴のネットワークで動作するように特別に設計されています。MQTTの主な目的は、ネットワーク帯域幅の使用を最小限に抑え、デバイスリソースへの要求を減らすことです。さらに、信頼性のある通信を維持し、一定の配信保証を提供することを目指しています。これらの目標により、MQTTは急成長している**機械間通信 (M2M)およびモノのインターネット (IoT)**の分野に非常に適しています。ここでは、多数のデバイスを効率的に接続することが不可欠です。さらに、MQTTはモバイルアプリケーションにも非常に有益であり、帯域幅とバッテリー寿命を節約することが重要です。

デフォルトポート: 1883

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

トラフィックの検査

MQTTブローカーがCONNECTパケットを受信すると、CONNACKパケットが返送されます。このパケットには接続状況を理解するために重要なリターンコードが含まれています。リターンコードが0x00の場合、認証情報が受け入れられたことを意味し、接続が成功したことを示します。一方、リターンコードが0x05の場合、認証情報が無効であることを示し、接続を防ぎます。

例えば、ブローカーが無効な認証情報のために接続を拒否した場合、シナリオは次のようになります:

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

MQTTのペンテスト

認証は完全にオプションです そして、認証が行われている場合でも、デフォルトでは暗号化は使用されません(資格情報は平文で送信されます)。MITM攻撃は依然として実行可能で、パスワードを盗むことができます。

MQTTサービスに接続するには、次のものを使用できます: https://github.com/bapowell/python-mqtt-client-shell そして、次のようにしてすべてのトピックに自分を購読します:

> 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/#"

あなたはまた、https://github.com/akamai-threat-research/mqtt-pwnを使用することができます。

あなたはまた、使用することができます:

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.

または、このコードを実行して、認証なしでMQTTサービスに接続し、すべてのトピックにサブスクライブしてそれらをリッスンすることができます:

#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/#')

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()

More information

from here: https://morphuslabs.com/hacking-the-iot-with-mqtt-8edaf0d07b9b

The Publish/Subscribe Pattern

パブリッシュ/サブスクライブモデルは以下で構成されています:

  • Publisher: ブローカー内の1つ(または複数)のトピックにメッセージを公開します。

  • Subscriber: ブローカー内の1つ(または複数)のトピックにサブスクライブし、パブリッシャーから送信されたすべてのメッセージを受信します。

  • Broker: パブリッシャーからサブスクライバーへのすべてのメッセージをルーティングします。

  • Topic: スラッシュ(/)で区切られた1つ以上のレベルで構成されています(例:/smartshouse/livingroom/temperature)。

Packet Format

すべてのMQTTパケットは固定ヘッダーを含みます(図02)。図02: 固定ヘッダー

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

Packet Types

  • CONNECT (1): クライアントがサーバーへの接続を要求するために開始します。

  • CONNACK (2): サーバーの成功した接続の確認。

  • PUBLISH (3): クライアントからサーバー、またはその逆にメッセージを送信するために使用されます。

  • PUBACK (4): PUBLISHパケットの確認。

  • PUBREC (5): メッセージが受信されたことを保証するメッセージ配信プロトコルの一部。

  • PUBREL (6): メッセージ配信のさらなる保証、メッセージのリリースを示します。

  • PUBCOMP (7): メッセージ配信プロトコルの最終部分、完了を示します。

  • SUBSCRIBE (8): クライアントがトピックからメッセージを受信するためのリクエスト。

  • SUBACK (9): サーバーのSUBSCRIBEリクエストの確認。

  • UNSUBSCRIBE (10): クライアントがトピックからのメッセージ受信を停止するためのリクエスト。

  • UNSUBACK (11): サーバーのUNSUBSCRIBEリクエストへの応答。

  • PINGREQ (12): クライアントによって送信されるハートビートメッセージ。

  • PINGRESP (13): ハートビートメッセージに対するサーバーの応答。

  • DISCONNECT (14): クライアントによって接続を終了するために開始されます。

  • 0と15の2つの値は予約されており、その使用は禁じられています。

Shodan

  • port:1883 MQTT

Support HackTricks

Last updated