Skip to content

UncleJ4ck/Specter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Specter

Specter is a passive WiFi monitor and lightweight wireless IDS written in Python on top of Scapy. It hops channels, fingerprints every nearby access point, and flags rogue and evil-twin APs in real time. It is meant for network administrators and security people watching the integrity of their own wireless.

The detection logic lives in a pure DetectionEngine that consumes plain Observation records, so every detector is unit-tested without a radio (see tests/).

What it detects

Detector Signal
EVIL_TWIN A known SSID advertised by a BSSID that is not in your allowlist
SECURITY_DOWNGRADE A listed AP suddenly advertising Open or WEP where it should be WPA2/WPA3
PMF_DOWNGRADE A listed AP recorded as PMF-required seen without PMF (spoof / deauth-DoS exposure)
SSID_CONFLICT The same SSID offered both secured and open by different BSSIDs
VENDOR_MISMATCH A listed BSSID whose OUI vendor no longer matches
MULTICHANNEL_BSSID One BSSID claiming two channels (impossible for a real AP)
KARMA An AP that probe-answers many distinct SSIDs (KARMA / MANA responder)
CSA_SPOOF A Channel Switch Announcement from a foreign BSSID for a known SSID (client eviction)
CSA_OBSERVED A Channel Switch Announcement from any other AP (informational, LOW)
SIGNAL_ANOMALY An AP whose signal deviates from its own baseline (robust MAD z-score)
TSF_ANOMALY A beacon timestamp running backwards (AP reset or freshly spun clone)
PMKID_EXPOSED An EAPOL M1 carrying an RSN PMKID (clientless-crackable handshake)
DEAUTH_FLOOD A burst of deauth / disassoc frames (evil-twin precursor)
BEACON_FLOOD A burst of new BSSIDs (mdk3-style beacon flood)
AUTH_FLOOD A burst of 802.11 authentication frames at one AP (auth DoS)
ASSOC_FLOOD A burst of association requests at one AP (association DoS)
WPS_BRUTEFORCE Excessive EAP frames from one station to one AP (Reaver-style WPS brute)
WEP_REPLAY A flood of replayed WEP data frames (aireplay-style ARP replay / IV harvesting)

Channel from a frame is trusted when it comes from the DS Parameter Set (2.4 GHz), the HT Operation element (5 GHz), or the HE Operation element (6 GHz), so the channel hopper never makes a single AP look multi-channel. Evil twins of cloaked (hidden) SSIDs are caught once the attacker probe-responds with the real name, and the alert is tagged [cloaked].

Other features

  • Real-time scanning across 2.4, 5, and 6 GHz with adaptive channel hopping.
  • MAC randomization of the monitoring interface (disable with --no-mac-spoof).
  • Async vendor (OUI) lookup off the capture path, with an on-disk cache, so a slow or rate-limited API never drops frames.
  • Dual-interface failover.
  • Alerts logged to specter_alerts.log; rogue APs saved to rogue_aps.json on exit, with cipher, AKM, PMF, and WPS recorded per AP.
  • Webhook and command alerting for HIGH/CRITICAL events (--webhook, --alert-cmd).
  • Tunable detection thresholds via a JSON config (--config).
  • Optional active modules (off by default): KARMA bait probing and deauth-based defense.

Installation

git clone https://github.com/UncleJ4ck/specter.git
cd specter
pip3 install -r requirements.txt

Project layout

specter.py            # thin launcher (sudo python3 specter.py ...)
specter/              # package
  _radio.py           # single guarded scapy import boundary
  models.py           # Observation, Alert, constants, ranking helpers (pure)
  engine.py           # DetectionEngine, all detectors (pure)
  parsing.py          # 802.11 frame -> Observation
  vendor.py           # async OUI lookup
  interfaces.py       # monitor mode, MAC spoof, channel hopping
  active.py           # KARMA bait, deauth defense (gated)
  notify.py           # webhook + command alerting
  render.py           # terminal UI
  capture.py          # packet handler, logging, persistence
  cli.py              # argparse + capture loop
tests/test_specter.py # hard-assertion detector tests (no radio)

The engine and models have no scapy or I/O dependency, which is what makes the detectors testable on any machine.

Usage

sudo python3 specter.py <interface> [known_networks.json] [secondary_interface] [options]
# or, equivalently:
sudo python3 -m specter <interface> [known_networks.json] [secondary_interface] [options]
  • <interface>: primary wireless interface (required).
  • [known_networks.json]: allowlist of your legitimate APs (optional). Without it, Specter still does evil-twin, conflict, karma, flood, and anomaly detection; with it, it also does allowlist, downgrade, and vendor checks.
  • [secondary_interface]: failover interface (optional).

Options:

Flag Effect
--band {2.4,5,6,all} Band(s) to hop. Default 2.4. Use all for dual/tri-band cards.
--config FILE JSON file overriding detection thresholds (see below).
--webhook URL POST each HIGH/CRITICAL alert as JSON to a URL.
--alert-cmd CMD Run a command on each HIGH/CRITICAL alert. Fields are exported as SPECTER_* env vars.
--no-mac-spoof Keep the real MAC on the monitor interface.
--active-karma Inject bait probe requests for a random SSID to flush KARMA/MANA APs.
--active-defense Transmit deauth frames at confirmed rogue APs. Asks for confirmation.

Example:

sudo python3 specter.py wlan0 config.json wlan1 --band all \
  --webhook https://hooks.example.com/specter

Notifications

HIGH and CRITICAL alerts are written to specter_alerts.log and, if configured, sent out of band:

  • --webhook URL POSTs a JSON body {severity, type, bssid, ssid, detail, count}.
  • --alert-cmd CMD runs CMD with the same fields as SPECTER_SEVERITY, SPECTER_TYPE, SPECTER_BSSID, SPECTER_SSID, SPECTER_DETAIL, SPECTER_COUNT. For email, point it at your MTA, e.g. --alert-cmd 'sh -c "printf \"%s\" \"$SPECTER_DETAIL\" | mail -s \"$SPECTER_TYPE\" you@example.com"'.

Both run on a background thread, so a slow endpoint never drops frames.

Threshold config

--config thresholds.json overrides any of the detection thresholds. Unspecified keys keep their defaults.

{ "deauth_flood": 15, "beacon_flood": 25, "signal_swing": 20, "karma_ssids": 4 }

Keys: power_history, signal_min_samples, signal_swing, tsf_regress, karma_ssids, flood_window, deauth_flood, beacon_flood, auth_flood, assoc_flood, wps_window, wps_eap.

Known-networks file

A JSON list of your legitimate APs. Multiple BSSIDs per SSID are fine (mesh, band steering). encryption and pmf are optional baselines that enable downgrade detection.

[
  { "ssid": "YourNetwork", "bssid": "e4:9e:12:00:00:01", "vendor": "Freebox SAS", "encryption": "wpa2", "pmf": "required" },
  { "ssid": "YourNetwork", "bssid": "e4:9e:12:00:00:02", "vendor": "Freebox SAS", "encryption": "wpa2" }
]

encryption accepts a family: open, wep, wpa, wpa2, wpa3-transition, wpa3. pmf set to required raises PMF_DOWNGRADE if that AP is later seen without protected management frames.

Active defense, legal note

--active-defense sends 802.11 deauthentication frames at APs Specter has confirmed as rogue. Transmitting deauth can be illegal in many jurisdictions (the FCC has issued large fines for it) and can knock legitimate nearby clients offline. Only enable it on wireless you own or are explicitly authorized to defend. It is off by default and prompts for a typed confirmation.

Testing

Two suites, both run without a wireless card:

python3 tests/test_specter.py       # detector logic, hard assertions + negative controls
python3 tests/test_integration.py   # real scapy frames through the capture and notify paths

The unit suite covers every detector with a positive case and a negative control. The integration suite dissects genuine 802.11 frames (beacon, RSN, EAPOL with a PMKID KDE, CSA) through parse_packet and make_handler, and drives the webhook and --alert-cmd notifier against a real loopback HTTP server and a real subprocess. What remains hardware-only: monitor-mode setup, iw channel hopping, and over-the-air transmission (sendp).

On-air demo

Creating an experimental evil twin with airgeddon

Creating an experimental evil twin with airgeddon

Specter detecting the evil twin

Specter detecting the evil twin

Tested on:

  • Ubuntu 22.04
  • PopOS
  • Raspberry Pi 3 Model B+

TODO

  • Switching between two interfaces
  • Multithreading
  • MAC spoofing
  • KARMA / MANA detection (passive distinct-SSID count + active bait)
  • Logging
  • Evil twin for unlisted SSIDs (conflict, downgrade, CSA)
  • Deauth and beacon flood detection
  • Auth flood, assoc flood, and WPS/EAP brute-force detection
  • PMKID exposure alerting (EAPOL M1 RSN PMKID KDE)
  • PMF downgrade detection (PMF-required baseline)
  • Webhook and command alerting (email via --alert-cmd + MTA)
  • Tunable thresholds via --config
  • 5 GHz channel via HT Operation, 6 GHz via HE Operation
  • Per-AP signal classifier (robust MAD modified z-score)
  • WEP ARP-replay detection (scoped to WEP data frames, not broadcast-MAC heuristics)
  • Hidden-SSID (cloaked) evil-twin correlation via probe responses
  • Deauthentication as a defensive mechanism (gated)
  • On-air verification of monitor mode, channel hop, and deauth transmit (needs a card)

About

Used to detect rogueAP and evil twin attacks and all those nastly evil wireless attacks

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages