Catch the rogue transmitter hiding in your air-gapped plant — passive RF monitoring that flags every unauthorised emitter on the spectrum.
An isolated control network is supposed to be an island. But a single hidden device with a radio — a cellular modem taped inside a panel, a rogue Wi-Fi access point, a Bluetooth bridge — quietly builds a runway off that island. Aether reads a spectrum sweep, finds every transmitter in the air, checks each against your approved-radio baseline, and raises the ones that should not be there.
It only ever listens. No transmitting, no probing, no jamming — just a receiver and an analysis of what is already on the air. Point it at a recorded sweep from a cheap SDR and read the waterfall.
Wireless is the blind spot of OT security. Teams lock down switches and firewalls, then a contractor leaves a 4G dongle in a cabinet and the air gap is gone. The hardware to find these — an RTL-SDR — costs about the price of lunch; the missing piece is software that turns a sweep into "here is what is transmitting, and here is what shouldn't be." That is Aether.
pip install -r requirements.txt
# scan the bundled demo sweep against its baseline
python run.py scan samples/demo_sweep.npz --baseline samples/baseline.json
# open the live waterfall + findings
python run.py dashboard --results aether_results.json
# -> http://localhost:3002No SDR yet? The bundled samples/demo_sweep.npz is a synthetic capture of an
isolated control room: two approved Wi-Fi APs and a LoRa sensor that belong there,
and three things that don't — a bursty cellular modem, a rogue Wi-Fi AP, and an
intermittent Bluetooth/Zigbee bridge.
Aether detects every emitter rising above the noise floor, identifies the band it sits in, and gives each a verdict against your baseline:
| Verdict | Meaning |
|---|---|
| ✓ sanctioned | matches an approved radio in your baseline |
| ✖ rogue | a transmitter that should not be present here |
| ? unknown | unexpected, but ambiguous — worth a look |
Bands it knows: cellular (LTE/GSM 700–2600 MHz uplink/downlink), Wi-Fi / Bluetooth / Zigbee (2.4 GHz ISM), LoRa and ISM (433 / 868 / 915 MHz), DECT, and the UHF ranges in between. Within 2.4 GHz it separates Wi-Fi from narrowband devices by bandwidth.
Findings are tuned for an isolated site, where the air should be quiet apart from a known, short list of radios:
- Cellular transmitter inside an isolated zone — critical, always. A modem on a control segment is a ready-made exfiltration path, whether it transmits constantly or in short bursts.
- Unauthorised Wi-Fi / Bluetooth / Zigbee — a rogue access point or bridge that could span the isolated network to the outside.
- Persistent unidentified carrier — a steady signal with no known service and no baseline match.
- Unknown ISM / LoRa emitter — surfaced so you can confirm it belongs to a sanctioned sensor.
Each finding carries the frequency, band, peak power, and how persistent the signal was across the sweep.
spectrum sweep (.npz: time x frequency power)
│
▼
noise floor (spectrum-wide) ─▶ detect signals above the floor
│
├─▶ cluster contiguous bins into emitters, measure persistence
├─▶ identify band -> category (cellular / wifi / lora / ...)
├─▶ compare to approved-radio baseline -> sanctioned vs unknown
└─▶ findings: rogue cellular / wireless / persistent carriers
│
▼
JSON results ──▶ live waterfall dashboard
The dashboard is a single self-contained page — a scrolling time × frequency waterfall with rogue carriers marked in red, plus the findings list. It ships no external dependencies, so it runs on an air-gapped analyst laptop.
Aether analyses sweeps; it does not drive the radio for you (yet). Capture one with
any SDR and a sweep tool, then save it as a .npz with freqs_mhz, times, and a
power (time × frequency, dBm) array:
- An RTL-SDR with
rtl_power/soapy_power, or a HackRF withhackrf_sweep. - Walk the receiver through the facility to catch low-power local emitters that a fixed antenna would miss.
The bundled scripts/make_demo_sweep.py shows the exact array format.
Aether is receive-only — it never transmits. Monitor only the spectrum at sites you own or are authorised to assess, and be aware that intercepting some transmissions is regulated in many jurisdictions. Use it to find rogue radios on your own network, nothing else.
- Live SDR capture (RTL-SDR / HackRF) for a standing monitor on a mirror antenna
- Bluetooth / Wi-Fi demodulation to pull device identifiers, not just spectrum
- Direction-finding hints from multi-point captures to help locate an emitter
- Baseline learning mode: build the approved list from a known-clean sweep
- Alerting hooks (syslog / webhook) on a new rogue between sweeps
MIT — see LICENSE.

