esptools
ESP32 hardware security assessment toolkit — device management, blue-team monitors, red-team audits, forensics, reporting
v2.0.2Authorized engagements only. Every red command refuses to start without
--engagement <NAME> AND the operator typing the literal string
AUTHORIZED at the warning banner. The auth confirmation is logged to
<evidence>/auth-log.jsonl with operator, hostname, and UTC timestamp.
Use only within a written, signed engagement authorization from the asset owner.
Quick Start
Install via jcli (recommended)
jcli install esptools
If you don't have jcli yet, install it first with
curl -fsSL https://cli.johlem.net/tools/jcli/install.sh | bash.
Or install directly
curl -fsSL https://cli.johlem.net/tools/esptools/install.sh | bash
Detect connected ESP32 boards
esptools device detect # scan /dev/ttyUSB* and /dev/ttyACM*
esptools --port /dev/ttyACM0 device info
esptools --port /dev/ttyACM0 device identify
Prepare a board for new firmware
esptools --port /dev/ttyACM0 device prepare # reset into bootloader, re-detect
esptools --port /dev/ttyACM0 device prepare --erase # + full-flash erase (MAC-typed gate)
esptools --port /dev/ttyACM0 device flash --firmware blue/sentinel
Forensics — CVE check + flash dump
esptools --port /dev/ttyACM0 forensics cveccheck # CVE-2025-27840 etc.
esptools --port /dev/ttyACM0 forensics efusedump # Secure Boot / Flash Encryption / JTAG status
esptools --port /dev/ttyACM0 --engagement Client-IR forensics flashdump --verify # full flash + SHA-256
esptools forensics fwanalyze --firmware ./dump.bin --find-keys --find-urls --entropy
Blue-team monitor + report
esptools --mode blue --port /dev/ttyACM0 --engagement Client-Audit \
blue sentinel --duration 600 --signal-webhook https://signal.example/webhook
esptools --engagement Client-Audit report \
--evidence ./esptools-evidence/20260606-143200-Client-Audit \
--client "Client" --operator "johlem"
Red-team audit (typed AUTHORIZED required)
esptools --mode red --engagement RT-2026-04 --port /dev/ttyACM0 \
red probeharvest --duration 300
# Banner displays → operator types: AUTHORIZED
# Auth row written to <evidence>/auth-log.jsonl with operator + hostname + UTC.
What it does
esptools is a single CLI binary that consolidates the workflow an operator runs against an ESP32 board during an authorized engagement. Five concerns under one binary:
- Device management. Detect / identify / flash via
esptool.pysubprocess wrappers; RTS/DTR reset via theserialportcrate; magic-header read at flash offset0xF000to surface the currently-installed esptools firmware name + version. - Blue-team monitors. Wired host-side via a shared serial-JSON event consumer — sentinel (WiFi), blewatch (BLE), canary (network honeypot), physmon (PIR/reed/vibration), netmap (ARP + TCP scan), arpwatch, clockwatch (NTP), beaconwatch, selftest.
- Red-team audits. probeharvest, evilapcheck, hidinject, badusb, mitm, blemitm, wpsaudit, blespooftest — every one behind the mandatory typed-AUTHORIZED gate + mandatory engagement scope.
- Forensics. flashdump (full flash + SHA-256 + zstd), flashread (partition-aware), efusedump (Secure Boot / Flash Encryption / JTAG posture), fwanalyze (pure-Rust static analysis: 11 regex categories + sliding-window Shannon entropy), cveccheck (embedded CVE database).
- Reporting. Markdown engagement report with DORA / NIS2 cross-reference for every tool used.
CVE-2025-27840 — ESP32 undocumented HCI commands
At RootedCON 2025, Tarlogic disclosed 29 undocumented Bluetooth HCI commands present in
every shipping ESP32 chip family (ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6, ESP32-H2).
These commands enable raw RAM read/write, MAC spoofing, and packet injection without
authentication. esptools forensics cveccheck ships with this entry pre-loaded
+ flags every chip family as likely vulnerable per disclosure until vendor
mitigation lands. Treat all Espressif BLE/BT devices as potentially MAC-spoofable.
The embedded database also covers CVE-2019-15894 (BT heap overflow), CVE-2021-28139 (BLE OOB write), CVE-2022-29587 (OTA signature bypass).
Command tree
device
| Command | What it does |
|---|---|
device detect | Scan /dev/ttyUSB* + /dev/ttyACM*, run esptool chip_id per port, return chip + MAC + flash size + installed esptools firmware (from magic header at flash offset 0xF000). |
device info | Full diagnostic dump: chip, MAC, flash, PSRAM, Secure Boot, Flash Encryption, eFuse, crystal frequency. |
device identify | Read 48-byte JHLM header at flash offset 0xF000, parse mode + tool ID + version + build timestamp. |
device reset | Pure-Rust RTS/DTR pulse. --bootloader drops chip into ROM bootloader. |
device erase | Full flash erase. Refuses without the operator typing the exact device MAC. |
device prepare | Reset into bootloader mode + optional --erase + re-detect to confirm chip responds. The single command to run before device flash. |
device flash | esptool write_flash with chip-compat check + SHA-256 verification of the catalog binary. |
blue (monitors)
| Command | What it does |
|---|---|
blue sentinel | Passive WiFi monitor — rogue AP, deauth flood, probe storm, evil twin. |
blue blewatch | BLE advertisement scanner + baseline diff. |
blue canary | Network honeypot — log unsolicited TCP/ICMP from monitored VLAN. |
blue physmon | Physical-intrusion sensors (PIR / reed / vibration). |
blue netmap | Active ARP + TCP asset discovery for DORA ICT inventory. |
blue arpwatch | Passive ARP-table monitor (ARP poisoning / IP conflict). |
blue clockwatch | NTP integrity monitor. |
blue beaconwatch | 802.11 beacon anomaly detector. |
blue selftest | Hardware self-test before field engagements. |
red (audits — typed AUTHORIZED required)
| Command | What it does |
|---|---|
red probeharvest | 802.11 probe-request capture + device/SSID mapping with OUI resolution. |
red evilapcheck | Rogue AP + captive portal credential capture. Captures encrypted with AES-256-GCM via PBKDF2. |
red hidinject | USB HID keyboard payload injector. DuckyScript parser + multi-layout (us / uk / fr / de / lu). |
red badusb | Advanced USB device emulator (HID + MSC + CDC). |
red mitm | ARP-poisoning MITM with HTTP / DNS capture. Firmware sends corrective ARP at end-of-run. |
red blemitm | BLE GATT MITM proxy. |
red wpsaudit | WPS PIN / PBC vulnerability audit. |
red blespooftest | BLE advertisement cloning test. |
forensics
| Command | What it does |
|---|---|
forensics flashdump | Full-flash dump via esptool read_flash, SHA-256 sidecar, zstd compression, metadata JSON for evidence chain. |
forensics flashread | Partition-aware read (nvs / otadata / esptools / app0 / app1 / spiffs / all) in raw / hex / strings format. |
forensics efusedump | espefuse summary parser. Secure Boot, Flash Encryption, JTAG-disable, key block burn status, factory MAC. |
forensics memdump | RAM dump via JTAG / ESP-IDF coredump (v2.1 lands the wiring; v2 stub surfaces dependency list). |
forensics logextract | Partition string-extraction + WiFi credential heuristic recovery. Full NVS binary parser queued for v2.1. |
forensics fwanalyze | Pure-Rust static firmware analysis. 11 category regexes (URLs, IPv4, email, PEM, JWT, AWS / GitHub / Slack / Stripe / Google keys, base64 blobs, WiFi PSK hints) + sliding-window Shannon entropy (256-byte windows / 64-byte step; flags >7 bits/byte). |
forensics cveccheck | Embedded CVE database lookup (CVE-2025-27840 et al.) keyed by chip family. |
monitor + report
| Command | What it does |
|---|---|
monitor | Built-in serial terminal + JSON event viewer. --filter by event type, --raw passthrough, --log tee, --timestamp local-time prepend. Full crossterm TUI queued for v2.1. |
report | Walks evidence dir, aggregates per-tool summaries, emits Markdown report. --template {blue,red,forensics,full}. DORA / NIS2 cross-reference auto-mapped. |
Prerequisites
esptools checks every prerequisite on startup and exits cleanly (exit code 5) if a hard requirement is missing. Soft prerequisites trigger a yellow warning row.
- Hard:
esptool(Espressif v5+) oresptool.py(older),python3. - Soft:
espefuse(forensics efusedump),openocd(forensics memdump JTAG path, v2.1+),minicom(alternative serial monitor). - Linux serial group: operator must be in
dialout(Debian) oruucp(NixOS) to open/dev/ttyUSB*//dev/ttyACM*without sudo. Fix:sudo usermod -aG dialout $USERthen re-login.
pipx install esptool # OR
nix profile install nixpkgs#esptool # NixOS
sudo usermod -aG dialout $USER # serial-port access
ESP32 firmware
The host-side esptools binary is half the picture. The other half is the per-tool
ESP32 firmware that implements the actual WiFi / BLE / network detection logic. Each firmware
image embeds a 64-byte JHLM magic header at flash offset 0xF000 so
device identify can read it back without serial chatter with the running tool.
Firmware is built separately from the ESP-IDF / Arduino-ESP32 sources documented in
tools/esptools/rust/FIRMWARE.md. v2 ships the host binary + the protocol contract;
the firmware images are scheduled for v2.1. Drop your own builds into
~/.local/share/esptools/firmware/ or use the catalog fetch path
(esptools device flash --fetch <NAME>) once cli.johlem.net publishes the
catalog index.
Evidence layout
./esptools-evidence/
└── 20260606-143200-ClientX-2026/
├── session.json # invocation metadata
├── auth-log.jsonl # red-team AUTHORIZED confirmations + UTC + operator + hostname
├── blue/<tool>/...
├── red/<tool>/... # incl. evilapcheck-captures.jsonl.enc (AES-256-GCM)
└── forensics/
├── flashdump/
├── flashread/
├── efusedump/
├── memdump/
├── logextract/
├── fwanalyze/
└── cveccheck/
Authorization: esptools red commands interact with WiFi / BLE / USB on target hardware in ways that may violate Luxembourg Penal Code Art. 509-1 (computer fraud), EU NIS2 Directive Art. 32 (unauthorized access), and GDPR Art. 5 (unlawful data processing) if run outside a signed engagement. The mandatory typed-AUTHORIZED gate + auth-log audit trail document scope; running without is operator-only liability.
Review every script before piping into bash: install.sh · esptools/install.sh