Skip to content
Selected work
003/Case study

NMS

A command server and a fleet of ESP32 probes watching a lab's wireless environment for intrusions.

PL.003 · 2026
Shipped2026
Year
2026
Status
Shipped
Interface
English
Stack
Python · Flask · MQTT · ESP32 / C++ · SQLite

The constraint

Catching wireless attacks — deauthentication floods, rogue access points, evil twins — means watching from several physical vantage points at once, so the sensor has to be a fleet of hardware probes reporting to one server. But a system that only runs when the boards are powered on the bench is one you can neither develop against day to day nor demonstrate without the rig.

The hard part

The wire protocol is pinned as JSON Schema with a golden-fixture corpus, so the Python virtual probe and the C++ ESP32 firmware are two implementations of one contract that a conformance suite holds to the byte — which is what lets the whole system run and demo with no hardware attached. The firmware also carries a real 802.11 deauthentication capability, and gating it honestly is part of the engineering: detection stays passive and always-on, the attack only fires when the server dispatches a job carrying an explicit confirm flag, and a NOTICE records which techniques were adopted and which were left out on purpose.

The RF survey: three access points grouped by BSSID, each with a signal-strength bar per probe that saw it, and below them the sub-GHz carriers a separate radio sweeps — the same networks measured from several vantage points at once.
The RF survey: three access points grouped by BSSID, each with a signal-strength bar per probe that saw it, and below them the sub-GHz carriers a separate radio sweeps — the same networks measured from several vantage points at once.
The job queue: recon and control commands dispatched to each node with chunk and gap counts and a delivery state — and the runs that arrived a chunk short marked incomplete, the gap recorded rather than rounded up to done.
The job queue: recon and control commands dispatched to each node with chunk and gap counts and a delivery state — and the runs that arrived a chunk short marked incomplete, the gap recorded rather than rounded up to done.
The wireless intrusion timeline: rogue access points, an evil twin spoofing a known SSID on an unexpected BSSID, and a deauthentication flood clocked at 240 frames a second — each alert tagged by type and attributed to the probe that caught it.
The wireless intrusion timeline: rogue access points, an evil twin spoofing a known SSID on an unexpected BSSID, and a deauthentication flood clocked at 240 frames a second — each alert tagged by type and attributed to the probe that caught it.