IoT Security Training Kit (ESP32)
⚠️ All vulnerabilities are intentionally implemented and intended exclusively for lab scenarios. Not for use in production.
Summary / Value Proposition
- Hands-on instead of slides: 10 real IoT attack surfaces (HTTP, MQTT, OTA, UART, BLE, Storage, RNG, Logging) on real hardware.
- Before/after visibility: Switchable build mode (Vulnerable vs. Fixed) with clear measurement criteria and PoV tests.
- Practical setup: Docker services (MQTT, OTA/Web, Scoring), PoV scripts, and CI checks – ready to use immediately.
- Scalable: Team CTF with flag submission, trainer guides, extensible with custom scenarios (e.g., signed OTA pipelines, SBOM).
Highlights
- 10 Challenges with clear learning objectives (see below)
- Build switch: BUILD_FIXED=1 activates hardening (immediately shows the effect)
- Clean separation: Exploit-free PoV scripts demonstrate risks without "weaponization"
- Trainer material: Syllabus, solution guides, facilitation roadmap, scoring server
- CI-ready: Example workflow (Static Analysis/Tree), easily extensible (SAST/Secrets scan)
Deliverables
- Firmware (ESP-IDF v5.x) with 10 modules (HTTP server, MQTT client, BLE GATT, UART CLI, OTA handler, KV store, etc.)
- Docker Compose: Mosquitto (MQTT), lightweight OTA/Web server, optional scoring server
- PoV tools (Python) + requirements, example commands
- Documentation: Setup, syllabus, challenges (description → PoV → fix → success criteria), facilitation guide
- CI workflow (.github/workflows) as a starting point for your pipeline
Learning Objectives & Curriculum
- systematically identify and prioritize IoT attack surfaces,
- demonstrably identify insecure defaults, weak tokens/PRNG, and unencrypted communication,
- securely design the OTA path (download → verification → commit) (TLS, signature, anti-rollback, verify-before-commit),
- specifically find and fix memory/protocol errors (overflow, format string, missing bounds checks),
- properly apply BLE permissions (pairing/encryption, attribute permissions),
- configure log/KV storage so that secrets do not "leak."
The 10 Challenges at a Glance
- Default Credentials (HTTP Basic) PoV: Login with default credentials. Fix: Disable Basic auth, short-lived tokens + TLS, never hardcode secrets.
- Insecure MQTT (without TLS/Auth) PoV: Publish/Subscribe without auth; command abuse. Fix: TLS, username/password, topic isolation, authorization, QoS/retain rules.
- Weak Token (PRNG) PoV: Predictable session tokens (rand() with fixed seed). Fix: TRNG/DRBG (esp_random), nonces, rate limits.
- Command Injection (simulated) & Logging PoV: Unvalidated cmd parameter → log format/buffer issues. Fix: Whitelist, safe formatting, bounds checks.
- UART Overflow PoV: Unchecked copy → out-of-bounds write. Fix: Length validation, strlcpy/memcpy_s, fuzzing on UART paths.
- Unsigned/Plain OTA PoV: OTA from http:// without signature verification. Fix: HTTPS, signature before commit, anti-rollback, hash verification after writing.
- BLE Insecure Permissions PoV: Read/write without pairing/encryption. Fix: Tighten GATT permissions, bonding, secure connections.
- Plaintext Provisioning & Secret Logging PoV: KV store/logs contain passwords. Fix: Redaction, NVS encryption, never log secrets.
- Sensitive Data in NVS PoV: Unencrypted NVS dump. Fix: Enable NVS encryption, key management.
- Insecure Update Channel (TOCTOU) PoV: Time window between check and application. Fix: Atomic "verify-before-commit" strategy, post-write hash, A/B rollback.
Architecture (Lab)
[Participants] ──(HTTP/MQTT/BLE/UART)──> [ESP32 DevKit]
│ │
├───────────────(MQTT)──────────────┤
│ ▼
[Docker: Mosquitto] [Docker: OTA/Web]
│ │
└──────────────(HTTP/REST)──────────┘
│
[Scoring Server]
Build Modes:
- Vulnerable (Default): Vulnerabilities active, PoVs work.
- Fixed: Hardening active → PoVs fail; logs/checks show "clean" behavior.
Technical Specifications
- Target: ESP32 DevKit (ESP32-WROOM32/equivalent)
- ESP-IDF: v5.x (HTTP Server, MQTT Client, BLE GATT, NVS, OTA)
- Partitioning: A/B-capable (factory, ota_0, ota_1); rollback support activatable
- Docker: Mosquitto (MQTT, 1883), OTA/Web (Flask, 8000), optional Scoring (5050)
- PoV Tools: Python 3.10+ (requests, paho-mqtt)
- CI Skeleton: Cppcheck + structure, easily extensible (SAST, secret scan, lint)
Example Schedule (2-Day Workshop)
- Setup & Recon (nmap, MQTT sub, BLE scan)
- HTTP/MQTT Challenges (#1, #2, #3)
- UART Overflow (#5) incl. logic analyzer insight
Integration & Extensions
- Signed OTA Pipeline (ESP32/STM32): seamless integration of an Ed25519-based update chain (manifest, verify-before-commit, anti-rollback).
- SBOM & Supply Chain: CycloneDX in CI, release signatures (cosign), reproducible builds.
- Device-specific Scenarios: CAN gateway, industrial protocols, sensors with Wheatstone bridge examples.
Security & Ethics
- The kit is operated exclusively in isolated lab environments (dedicated SSID/VLAN).
- PoV scripts target only the provided hardware/containers.
- No publication of production-grade exploits or 0-days.
Variants & Services
Frequently Asked Questions (FAQ)
Example Commands
Bash
# Firmware (Vulnerable)
idf.py -C firmware/esp32 set-target esp32
idf.py -C firmware/esp32 build && idf.py -C firmware/esp32 flash monitor
# Firmware (Fixed)
idf.py -C firmware/esp32 build -D BUILD_FIXED=1
# Docker Services
docker compose -f docker/docker-compose.yml up -d
# PoV: Default Credentials
python tools/pov_default_creds.py http://<ESP32-IP>/login
# PoV: Insecure MQTT
python tools/pov_insecure_mqtt.py
Contact & Demo
SEO / Metadata (optional)
Html
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Course",
"name": "IoT Security Training Kit (ESP32)",
"description": "CTF-style hands-on training for secure embedded development on ESP32.",
"provider": {
"@type": "Organization",
"name": "Büngener Software",
"url": "https://buengener-software.de"
},
"hasCourseInstance": {
"@type": "CourseInstance",
"courseMode": "OnSite/OnLine",
"startDate": "2025-10-01",
"endDate": "2025-12-31",
"location": {
"@type": "Place",
"name": "In-house / Remote"
}
}
}
</script>
Versioning
- v1.0 – Initial release of the Training Kit (10 challenges, Docker lab, PoV, CI skeleton)