Network Security

Comprehensive network security toolkit with deauth attack detection and device monitoring

  • Version: 2.1.0 (per the project’s CHANGELOG, 2025-12-22)
  • Language: Python 3.7+
  • License: Apache 2.0

📦 View on GitHub · 📖 Read Blog Post

A dark three-column dashboard render: a WiFi Monitor panel showing RSSI -42 dBm with signal bars and layered waveforms, a network topology map of AP and client nodes carrying four red deauthentication-attack callouts above Traffic Volume and Attack Attempts charts, and a Threat Level column with a red DEAUTH ATTACK DETECTED banner over a long table of device MAC addresses — a concept render, not a screenshot of the tool

Overview

WiFi Security Monitor is an open-source Python toolkit designed to protect wireless networks from attacks and unauthorized access. It combines two powerful monitoring systems into one comprehensive security solution that works with any WiFi adapter supporting monitor mode.

The rest of this page is a setup walkthrough rather than a feature list: what the two programs need before they will start, which configuration keys you have to fill in, the commands that run them, and how to read the numbers they print.

Every threshold quoted below comes from a named line of the shipped source or a named section of the project README. Where those two disagree — and on the threat-level table they do — this page follows the code, because the code is what prints the label on your screen.

🛡️ Deauth Attack Detection

Real-time detection of WiFi deauthentication attacks using advanced behavioral analysis

  • Dual-band monitoring (2.4GHz & 5GHz)
  • MAC spoofing detection
  • Threat scoring (0-100 scale)
  • Forensic logging for evidence

📡 Network Device Monitor

Track all devices on your network with intelligent detection and alerting

  • Real-time device tracking
  • IoT device identification
  • Suspicious device alerts
  • Connection statistics & history

🧠 Behavioral Analysis

Advanced fingerprinting techniques that don’t rely on hardware MAC addresses

  • Timing pattern analysis
  • RSSI tracking & anomaly detection
  • Sequence number verification
  • Multi-factor legitimacy scoring

🌐 Universal Compatibility

Works with any monitor mode capable WiFi adapter on Linux systems

  • Tested on Raspberry Pi & Ubuntu
  • Supports Atheros, Ralink, Realtek chipsets
  • Run both tools simultaneously
  • No specialized hardware required

🎯 Use Cases

  • Home network security
  • Security research & testing
  • IoT device management
  • Network troubleshooting
  • Penetration testing (authorized)

How It Works

Instead of relying on hardware MAC addresses (which most adapters don’t expose), WiFi Security Monitor uses sophisticated behavioral fingerprinting:

  • ⏱️ Timing Analysis — Legitimate routers have consistent timing patterns, while attack tools show irregular behavior
  • 📶 RSSI Tracking — Sudden signal strength changes indicate device switching or location spoofing
  • 🔢 Sequence Numbers — Duplicate or anomalous sequence numbers reveal packet injection attacks
  • 📊 Rate Analysis — Attack tools often use unusual transmission rates that differ from legitimate traffic
  • ✅ Legitimacy Scoring — Multi-factor assessment combines all metrics to determine if a device is genuine

What raises the threat score

calculate_threat_level() in deauth_detector.py builds the score additively from the frame it just saw plus the history it holds for that transmitter. The weights, by source line:

  • +35 — the deauth is addressed to one of the MACs you listed in local_device_macs (:434-435). An attack on your own gear outranks every other signal.
  • +20 — the packet source is impersonating one of your own devices (:437-438).
  • +40 / +25 / +10 — attack rate, in three descending bands: above 10, above 5, above 2 (:440-445).
  • +20 — the frame is a broadcast deauth addressed to ff:ff:ff:ff:ff:ff, i.e. an attempt to knock everyone off at once (:449-450).
  • +25 — the hardware transmitter address and the packet source MAC disagree: MAC spoofing (:453-454).
  • +15 / +10 / +5 — this attacker has been active for over an hour, over ten minutes, or over a minute (:462-467).
  • +20 / +10 — timing analysis rates the sender highly automated, or somewhat automated (:472-475).
  • +15 / +10 — burst counts above five, and above two (:478-481).
  • +15 — sequence-number anomalies: duplicates, an oversized gap, or a suspiciously perfect run, all found by detect_sequence_anomalies() (:485-486).
  • +20 — the last four RSSI samples span more than 20 dBm, which a stationary transmitter does not do (:489-493).
  • +10 — the source MAC has the locally administered bit set, the usual sign of a software-assigned address (:496-499).

The total is clamped by min(score, 100) at :500, which is why the scale is exactly the 101 integers from 0 to 100.

What lowers it

There is one subtraction, and it is why a busy home network does not alarm all evening.

When a frame claims to come from a router, the adapter has not exposed a hardware MAC, and the behavioral legitimacy score is at least 70, the detector reduces the threat by int(legitimacy / 100 * threat_reduction_percentage) (:656-660).

With the shipped threat_reduction_percentage of 80, a source scoring 90% legitimate loses 72 points — the code’s own comment on that line states exactly that. So a printed 62 is not a confidence level. It is the sum of the flags above, minus that discount where it applies.

What You Need

💻 Hardware

  • A WiFi adapter that supports monitor mode — this is the one part you cannot substitute
  • Chipsets the README’s Requirements section names as tested: Atheros (ath9k), Ralink/MediaTek (RT2800, MT7612U), Realtek (RTL8812AU)
  • A second adapter if you want the deauth detector and the device monitor running at the same time

🐧 Software

  • Linux — the README reports testing on Raspberry Pi and Ubuntu
  • Python 3.7 or higher
  • Root/sudo access, required for monitor mode
  • One dependency: requirements.txt pins scapy>=2.5.0 and lists nothing else, so pip3 install -r requirements.txt pulls Scapy and its own dependencies and no more

✅ Confirmed Working Adapters

These four are listed under Confirmed Working in the README’s Supported Adapters section. They are the author’s tested set, not ours:

  • Alfa AWUS036NHA (Atheros AR9271)
  • Alfa AWUS036ACH (Realtek RTL8812AU)
  • TP-Link TL-WN722N v1 (Atheros AR9271)
  • Panda PAU09 (Ralink RT5372)

⚠️ Known Limitations

Straight from the README’s Known Limitations list, plus two the source makes plain:

  • Most adapters don’t expose hardware MAC addresses. That is not a footnote, it is the reason the behavioral analysis exists at all. When the driver withholds it the detector prints Hardware MAC: Not exposed by MT7612U driver (deauth_detector.py:690) and falls back to legitimacy scoring for that transmitter.
  • 5GHz monitoring requires a 5GHz-capable adapter. A 2.4GHz-only card in the list above will never see a 5GHz deauth no matter what you put in channels.
  • Built-in laptop WiFi typically doesn’t support monitor mode. Budget for a USB adapter.
  • A monitor-mode radio hears one channel at a time. channel_hopper() sets a channel with iw dev <iface> set channel <n>, sleeps for the dwell time, then moves on (:334-347). With the shipped example — five channels at 1.5 seconds — a full cycle is 7.5 seconds and the radio is on any given channel 20% of the time. A short burst on a channel it is not currently tuned to is simply not captured.
  • The shipped example config never visits 5GHz. config.example.json lists "channels": [1,2,3,4,5], and the detector’s own band test is channel <= 14 means 2.4GHz (:907-908). Out of the box, this is a 2.4GHz-only setup until you edit that list.

Configuration

Neither program takes command-line flags. Both read a JSON file from the working directory and refuse to start without it: deauth_detector.py:18-22 checks for config.json, prints ❌ Error: config.json not found!, and calls sys.exit(1).

network_monitor.py:22-25 does the same for monitor_config.json. So configuration is not optional setup you can skip on a first run — it is the first run.

The detector: config.json

Copy the shipped example and edit it:

cp config.example.json config.json
nano config.json

The keys, with the values the example actually ships:

  • network.interface — "wlan1". The monitor-mode interface, not your normal one. Use the interface name airmon-ng printed back at you in Install and enable monitor mode above — on a one-adapter machine that is usually neither wlan0 nor the example’s wlan1.
  • network.channels — [1,2,3,4,5]. Replace these with your router’s channel and at least one more; see the warning below.
  • network.channel_dwell_time — 1.5. Seconds spent on each channel before hopping.
  • network.whitelist_macs — empty in the example. Your router’s MACs go here; the example’s own comment says leaving it empty is fine and that filling it reduces false positives.
  • network.local_device_macs — empty in the example. Devices listed here get the ⚠️ ATTACKING YOUR NETWORK! banner and the +35 threat boost.
  • detection.rssi_jump_threshold — 20, low_rate_threshold — 6.0, timing_cv_threshold — 0.3, sequence_gap_threshold — 100, burst_threshold_ms — 100.
  • detection.legitimacy_threshold — 70, and detection.threat_reduction_percentage — 80. These two are the discount described above.
  • output.log_file — "data/attacker_evidence.log", plus alerts_enabled and verbose booleans.
  • wifi.tx_power_dbm — 17 and wifi.path_loss_exponent — 3.5, which feed the rough distance estimate printed with each alert.

Every one of those is read by direct key lookup at deauth_detector.py:32-50. Delete a key from your copy and you get a KeyError on startup, not a sensible default — so edit values, never remove lines.

Give it at least two channels. The example config’s comment offers to “leave empty to scan all channels”, but the code does not support that: current_channel = CHANNELS[0] runs at :56, and the startup banner reads both CHANNELS[0] and CHANNELS[1] at :907-908 to label the two bands it prints.

An empty list fails at import, and a single-entry list fails at the banner, both before any packet is captured. Two entries is the practical floor — for example your 2.4GHz channel and one 5GHz channel.

The monitor: monitor_config.json

The device monitor has its own file with a different shape, which is easy to miss:

cp monitor_config.example.json monitor_config.json
nano monitor_config.json
  • network.interface — "wlan1", the monitor-mode adapter.
  • network.hostname_interface — "eth0". A second, ordinary interface used to capture hostnames; the comment suggests eth0 or wlan0.
  • network.channels — [11] and channel_dwell_time — 2.0. A single channel is fine here: this program only ever reads CHANNELS[0] (network_monitor.py:50).
  • network.known_devices — empty. Add your own MACs to cut down alert noise.
  • alerts.alert_on_new_device and alerts.alert_on_iot_device — both true.
  • output.log_file — "data/network_devices.log".

Device history is kept separately in data/device_database.json (network_monitor.py:56), which survives restarts and accumulates first-seen time, connection count, total packets and total connection time per MAC. The example config notes that you add a nickname field directly in that database file to give a device a human name.

Finding the MAC addresses

The README’s Configuration section gives the two lookups you need. Your router’s MAC is on the router’s label, or run iwconfig while connected to it. Your own device’s MAC comes from ip link show or ifconfig.

Running It

Install and enable monitor mode

# Clone the repository
git clone https://github.com/nnxazolazuranikola/wifi-security-monitor.git
cd wifi-security-monitor

# Install dependencies
pip3 install -r requirements.txt

Then put the adapter into monitor mode. Do these three in order — the third one is the step that tells you what to write in your config file:

  1. Clear the processes holding the adapter first.

    sudo airmon-ng check kill

    sudo airmon-ng check kill stops the network-management processes that hold the adapter — NetworkManager and wpa_supplicant keep the interface associated to an ordinary network, and that alone is enough to make the switch fail or to let monitor mode flap back.

    Running it up front avoids the failure listed under When it won’t start below, where the same command appears as a cure rather than a precaution.

  2. Switch the adapter over, then read what the command prints.

    # Enable monitor mode (replace wlan0 with your interface)
    sudo airmon-ng start wlan0

    sudo airmon-ng start usually renames the interface when it enables monitor mode, and the interface name it prints back is the name that goes in network.interface — not wlan0, and not the wlan1 that ships in the example config.

    Copy it from that output rather than guessing; the naming scheme differs between airmon-ng versions, so there is no single correct answer to hard-code here.

  3. Confirm it before you edit anything.

    iwconfig          # or: iw dev

    Find the interface name from step 2 in that listing and check it reports Mode:Monitor. If it is still showing managed mode, or the name is absent, monitor mode did not take and the detector will exit with No such device the moment you start it.

A note on why the example file disagrees with your machine: config.example.json carries "wlan1" because the project’s README describes running the two programs on two separate adapters — the detector on one, the network monitor on the other (see Run both at once).

With a single adapter you will normally end up with a different name, and that name, not wlan1, is the one to use.

Start the deauth detector

cp config.example.json config.json
nano config.json           # set interface, channels, optional MACs

sudo python3 deauth_detector.py
tail -f attacker_evidence.log

The banner it prints on startup is worth reading rather than scrolling past: it echoes the interface, the log path, the channel-hop pair and dwell time, whether any whitelist is in force, and the four threat levels it will use.

If the interface or channels in that banner are not what you expected, stop and fix the config before you trust anything that follows.

Start the network device monitor

cp monitor_config.example.json monitor_config.json
nano monitor_config.json   # set interface

sudo python3 network_monitor.py
tail -f network_devices.log
cat device_database.json   # device history

It classifies devices by MAC OUI and flags IoT gear by keyword — the shipped list at network_monitor.py:177-178 matches ESP, Camera, Hue, Ring, Nest, Echo, Alexa, Sonos, Xiaomi IoT, SmartCam, Foscam, Hikvision, Dahua and Wyze.

Run both at once

This needs two WiFi adapters, one per program, because each one owns its interface and hops it independently. The README’s own recipe is two terminals:

# Terminal 1: deauth detector on wlan1
sudo python3 deauth_detector.py

# Terminal 2: network monitor on wlan2
sudo python3 network_monitor.py

When it won’t start

The README’s Troubleshooting section covers the three failures you are most likely to hit first:

  • “No such device” — the interface name is wrong or monitor mode is not enabled. Check with iwconfig, then sudo airmon-ng start wlan0.
  • “Operation not permitted” — you are not root. Both programs need sudo.
  • No detections at all — verify the channels match your router’s frequency, confirm the interface really is in monitor mode with iwconfig wlan1, and kill anything else holding the adapter with sudo airmon-ng check kill.

Understanding the Output

Threat levels

These are the four bands get_threat_label() branches on, and the same four the startup banner prints. Note that the README’s summary table is out of date and lists only three; trust these.

  • 🟢 LOW (0-29) — Likely legitimate activity - normal router behavior with no red flags
  • 🟡 MEDIUM (30-49) — Suspicious activity detected - monitor closely and investigate source
  • 🟠 HIGH (50-69) — Persistent or broadcast attacks
  • 🔴 CRITICAL (70-100) — Active attack detected - immediate action required to protect network

Legitimacy score

Separate from the threat score, and shown only when a frame claims to be your router. It is a percentage, printed by deauth_detector.py:700-705 on the same three boundaries the README documents:

  • 🟢 80-100% — genuine router behavior
  • 🟡 50-79% — uncertain, verify manually
  • 🔴 0-49% — likely spoofed or malicious

A high legitimacy score is what triggers the threat discount described earlier, so the two numbers move against each other on purpose.

An alert, line by line

The README’s Example Output shows the shape of a single detection:

🚨 ATTACK #5 DETECTED - 2025-12-21 22:15:30 ⚠️ ATTACKING YOUR NETWORK!
   THREAT LEVEL: 🔴 CRITICAL (85/100)

⚠️  ATTACKER IDENTIFICATION:
    Packet Source:     aa:bb:cc:dd:ee:ff (UnknownVendor)
    🔴 LEGITIMACY:     15% - LIKELY SPOOFED!

📡 SIGNAL ANALYSIS:
    Signal Strength:   -65 dBm
    Est. Distance:     ~12m

Reading it in order: the attack counter and timestamp, then the ⚠️ ATTACKING YOUR NETWORK! suffix which appears only when the target MAC is one you listed in local_device_macs. The threat level carries both label and raw score.

The identification block names the packet source and its vendor from the OUI, and prints the hardware MAC beside it when the driver exposes one — with a 🎭 MAC SPOOFING: YES line when the two disagree.

The distance is an estimate derived from RSSI using the tx_power_dbm and path_loss_exponent values from your config, so treat it as an order of magnitude and nothing finer: it assumes a path-loss model, not a measurement.

Where the evidence lands

The detector appends to the path in output.log_file, data/attacker_evidence.log by default, writing a session header at startup and a full record per attack, and it prints Evidence saved to: with that path on exit (:1014).

The device monitor writes data/network_devices.log alongside its persistent data/device_database.json. Those files are the forensic output; the terminal is just the live view.

This tool is for authorized security testing only. Only use it on networks you own or have explicit permission to test. Monitor mode may violate local regulations in some jurisdictions. Unauthorized network monitoring may be illegal in your country. The author assumes no liability for misuse.

Get Started

WiFi Security Monitor is open source and actively maintained. Check out the repository for complete documentation, examples, and community support.

🔮 Future Plans

  • Web dashboard interface
  • Email/SMS notifications
  • Machine learning detection
  • Additional attack types
  • Mobile app support

📦 GitHub Repository · 📚 Documentation · 📝 Release Blog Post

PythonNetwork SecurityCybersecurityOpen Source

← Back to Projects

Back to the top