patar56/mqtt-fuzzer

GitHub: patar56/mqtt-fuzzer

Stars: 0 | Forks: 0

# MQTT Security Agent **UCLA ECE 202C — IoT Security Final Project** An AI-powered MQTT broker security assessment tool built on top of **Claude Code** (Anthropic's CLI). The agent autonomously designs fuzzing campaigns, constructs raw MQTT packets, executes stateful multi-client attacks against live Docker-hosted brokers, and produces structured vulnerability reports — all driven by natural-language prompts in the Claude Code terminal. ## How It Works This project uses a **custom Claude Code subagent** (`mqtt-protocol-fuzzer`) defined in `.claude/agents/mqtt-protocol-fuzzer.md`. Rather than running a traditional Python CLI, you interact with the agent directly through the Claude Code terminal using `@agent-mqtt-protocol-fuzzer` prompts. The agent reasons about the MQTT protocol, writes and executes fuzzing scripts, spins up Docker containers, and produces reports — autonomously, in a single conversation turn. You (Claude Code terminal) │ └─ @agent-mqtt-protocol-fuzzer │ ├─ Reasons about MQTT protocol state machines ├─ Writes fuzzing scripts (raw TCP, no paho dependency) ├─ Spins up / verifies Docker broker containers ├─ Executes multi-client coordinated attack scenarios ├─ Analyzes broker responses and classifies vulnerabilities └─ Writes campaign reports to reports/ ## Research Basis This project synthesizes findings and techniques from five papers: | Paper | Contribution | |---|---| | [Burglars' IoT Paradise](https://ieeexplore.ieee.org/document/9152645) (IEEE S&P 2020) | MQTT vulnerability taxonomy (V1–V6) | | [MQTTactic](https://www.usenix.org/conference/usenixsecurity22/presentation/chen-bin-mqtt) (USENIX Sec 2022) | Authorization logic flaw categories | | [FUME](https://dl.acm.org/doi/10.1145/3548606.3560570) (CCS 2022) | Stateful fuzzing engine with response feedback | | [MGPTFuzz / LLM Protocol Fuzzing](https://www.ndss-symposium.org/ndss-paper/large-language-model-guided-protocol-fuzzing/) (NDSS 2024) | LLM-guided protocol spec parsing → FSM extraction | | FirmAgent (2026) | Hybrid fuzzing + LLM agent reasoning loop | ## Repository Structure mqtt-security-agent/ ├── .claude/ │ └── agents/ │ └── mqtt-protocol-fuzzer.md # Subagent definition (tools, system prompt) ├── agent/ │ ├── spec/mqtt_spec.py # Protocol FSM, vulnerability taxonomy │ ├── fuzzing/engine.py # Campaign 1 fuzzing engine │ ├── vulnerabilities/attacks.py # 7 targeted attack classes (V1–V7) │ └── broker/ │ ├── connector.py # Raw TCP MQTT packet builder │ └── docker_mgr.py # Docker broker lifecycle management ├── campaign2_fuzzer.py # Campaign 2 fuzzing engine ├── campaign3_fuzzer.py # Campaign 3 multi-broker fuzzer ├── campaign_final_fuzzer.py # Final campaign: multi-client differential fuzzer ├── config/ │ ├── mosquitto_hardened_final.conf # Hardened Mosquitto configuration │ ├── acl_hardened_final.conf # Hardened ACL file │ ├── emqx_hardened_final.conf # Hardened EMQX configuration (HOCON) │ ├── nanomq_hardened_final.conf # Hardened NanoMQ configuration │ └── hivemq_hardening_notes.md # HiveMQ hardening guidance (XML-based) ├── scripts/ │ ├── verify_mitigations.py # Campaign 3 PASS/FAIL verifier │ └── verify_mitigations_final.py # Final campaign verifier (28 checks, 4 brokers) ├── reports/ # All campaign outputs (see below) ├── docker/ │ ├── docker-compose.yml │ └── mosquitto/mosquitto.conf # Intentionally permissive config for research └── tests/ └── test_packet_builder.py # 37 unit tests (protocol encoding) ## Prerequisites - [Claude Code CLI](https://claude.ai/code) installed and authenticated - Docker Desktop running - Python 3.10+ (for fuzzing scripts executed by the agent) - Python packages: `paho-mqtt` (Campaign 1 analysis only — later campaigns use raw sockets) git clone https://github.com/patar56/mqtt-security-agent.git cd mqtt-security-agent pip install -r requirements.txt ## Usage All interaction happens through the **Claude Code terminal**. Open Claude Code in this project directory and use `@agent-mqtt-protocol-fuzzer` to invoke the fuzzing agent. ### Start a fuzzing campaign @agent-mqtt-protocol-fuzzer Spin up a Docker container with an MQTT broker and launch a fuzzing campaign to find vulnerabilities. The agent will: 1. Pull and start `eclipse-mosquitto:2.0.18` in Docker with a permissive config 2. Run generation-based and mutation-based fuzzing 3. Execute targeted vulnerability attacks from the academic literature 4. Write results to `reports/` ### Target a specific broker or vulnerability class @agent-mqtt-protocol-fuzzer Run the session hijacking attack (V3) against the broker on localhost:1884. ### Multi-broker campaign @agent-mqtt-protocol-fuzzer Run a fuzzing campaign against Mosquitto, EMQX, HiveMQ CE, and NanoMQ. Produce a cross-broker comparison matrix. ### Request mitigations @agent-mqtt-protocol-fuzzer Produce hardened configs and a mitigation guide for all confirmed vulnerabilities. ### Continue a prior campaign ## Campaign History & Results Four campaigns were run over the course of this project, each building on the prior methodology. ### Campaign 1 — Mosquitto 2.0.18 (285 test cases) Grammar-based generation fuzzing + mutation fuzzing + academic vulnerability reproduction. | Vuln | Name | CVSS | Result | |------|------|------|--------| | V1 | Unauthorized Will Message Exploitation | 7.5 | CONFIRMED | | V2 | Retained Message Poisoning | 6.5 | CONFIRMED | | V3 | ClientID Session Hijacking | 8.1 | CONFIRMED | | V4 | Wildcard Subscription Eavesdrop (`#`) | 7.2 | CONFIRMED | | V5 | QoS 2 Duplicate Message Injection | 5.3 | NOT CONFIRMED (spec-compliant) | | V6 | $SYS Topic Information Disclosure | 4.3 | CONFIRMED | | V7 | Zero-Length ClientID Spec Violation | 6.0 | NOT CONFIRMED (spec-compliant) | **Anomaly rate:** 41.4% (118/285) | **Broker crashes:** 0 ### Campaign 2 — Mosquitto 2.0.18 (84 test cases) Expanded attack surface: credential fields, shared subscriptions, QoS state machine, connection flooding, fingerprinting. | Vuln | Name | CVSS | Result | |------|------|------|--------| | V8 | Unauthenticated Credential Acceptance | 6.5 | CONFIRMED | | V9 | Shared Subscription Namespace Abuse | 5.4 | CONFIRMED | | V10 | QoS State Machine Leniency (PID=0) | 4.3 | CONFIRMED | | V11 | Session Persistence Resource Accumulation | 5.3 | CONFIRMED | | V17 | Broker Configuration Fingerprinting | 3.7 | CONFIRMED | **Cumulative confirmed vulnerabilities: 10** ### Campaign 3 — 4 Brokers, 978 test cases Multi-broker testing: Mosquitto, NanoMQ, HiveMQ CE 2024.3, EMQX 5.0.0. Plus 10 new vulnerability classes and concrete mitigations for all prior findings. | Vuln | Name | CVSS | |------|------|------| | V18 | Oversized CONNECT silent drop | 6.5 | | V19 | 500 subscriptions per packet granted | 5.3 | | V20 | 104,931 PUBLISH/sec — no rate limiting | 7.5 | | V21 | PINGREQ keepalive abuse | 5.3 | | V22 | QoS 2 silently downgraded to QoS 0 | 5.4 | | V24 | 1 PUBLISH → 263 copies (overlapping subs) | 7.5 | | V26 | Null bytes / invalid UTF-8 in topic names | 6.5 | | V27 | keepalive timeout enforcement gap | 5.3 | | V28 | Will self-delivery cross-client injection | 6.8 | | V31 | QoS 2 in-flight session hijacking | 8.1 | **Cumulative confirmed vulnerabilities: 20** **Cross-broker highlights:** - V1, V3, V8, V11 confirmed on **all four brokers** — MQTT protocol design defaults, not implementation bugs - EMQX 5.0.0: worst §2.3.1 offender (accepts PID=0 in PUBACK/PUBREC/PUBREL/PUBCOMP) - HiveMQ CE: only broker that correctly rejects PID=0 - EMQX: correctly blocks `#` wildcard subscriptions (V4 not confirmed) ### Final Campaign — All 4 Brokers, Differential Fuzzing (100 broker-runs) Fundamentally redesigned fuzzer (`campaign_final_fuzzer.py`, 1,849 lines, raw sockets, no paho dependency). Key improvements over prior campaigns: **New final campaign findings:** | Finding | Detail | Broker(s) | |---------|--------|-----------| | R1 | NanoMQ delivers 2 copies of QoS 2 PUBLISH when DUP races PUBREL | NanoMQ | | C2 | Message amplification: EMQX 3×, NanoMQ 4× with 4 overlapping filters | EMQX, NanoMQ | | V51 | Unbounded `SessionExpiry` accepted (MQTT v5) | EMQX | | V52 | `UserProperty` flood accepted without limit | EMQX, HiveMQ | | V53 | Divergent reason codes for Topic Alias out-of-bounds | EMQX vs HiveMQ | | V54 | v5 CONNECT fields accepted silently on v3.1.1 brokers | Mosquitto, NanoMQ | **Divergence rate:** 64% (16/25 differential tests showed broker disagreement) **Final broker risk ranking:** HiveMQ CE 2024.3 (lowest) < EMQX 5.0.0 < Mosquitto 2.0.18 ≈ NanoMQ ## Project Totals | Metric | Value | |--------|-------| | Campaigns | 4 | | Total test cases | 1,447 | | MQTT brokers tested | 4 (Mosquitto, NanoMQ, HiveMQ CE, EMQX) | | Confirmed vulnerabilities | 20+ | | Broker crashes | 0 | | Hardened configs produced | 4 (one per broker) | ## Reports & Outputs All reports are in `reports/`. Raw JSON results are included for reproducibility. | File | Description | |------|-------------| | `fuzzing_campaign_report.md` | Campaign 1 narrative | | `vulnerability_report.md` | Campaign 1 vulnerability deep-dives | | `fuzzing_campaign2_report.md` | Campaign 2 narrative | | `vulnerability_report_campaign2.md` | V8–V17 deep-dives | | `fuzzing_campaign3_report.md` | Campaign 3 narrative | | `vulnerability_report_campaign3.md` | V18–V31 deep-dives | | `mitigations_campaign3.md` | Mitigation guide for V1–V17 | | `multi_broker_report_campaign3.md` | Cross-broker comparison matrix (C3) | | `fuzzing_final_campaign_report.md` | **Master narrative — all 4 campaigns** | | `vulnerability_report_final.md` | **Definitive vulnerability catalog** | | `multi_broker_final_report.md` | **Final cross-broker analysis** | | `ai_conversation_log.md` | Full AI interaction log for submission | | `figures/*.png` | 6 visualizations (scorecard, timelines, matrices) | | `fuzzing_raw_results*.json` | Raw test data per campaign | ## Defense-in-Depth Model Mitigations are layered across 4 tiers, with hardened configs in `config/`: | Tier | Control | Implementation | |------|---------|----------------| | 1 — Authentication | Who can connect | `allow_anonymous false`, password file, TLS client certs | | 2 — Authorization | Who can publish/subscribe to what | ACL file, deny wildcards, deny `$SYS/#`, per-client namespaces | | 3 — Resource controls | DoS prevention | `max_connections`, `max_inflight_messages`, `message_size_limit`, `persistent_client_expiration` | | 4 — Network | Perimeter defense | mTLS required, broker on private network, firewall blocks port 1883 externally | Run the automated verifier to check mitigation status: python scripts/verify_mitigations_final.py # Runs 28 checks across all 4 brokers, outputs PASS/FAIL + JSON ## Running Unit Tests python -m pytest tests/ -v # 37 passed (protocol packet encoding)