WiFi Reconnaissance
Reconnaissance involves discovering available networks (ESSIDs), their security configurations, and connected clients.
📑 Table of Contents
What to Record During Recon
-w so you can re-analyse offline.
Airodump-ng Scanning
Airodump-ng is the primary wireless recon tool. It channel-hops across all bands and displays discovered APs and associated clients in real time.
# Full scan — all channels, all bands
sudo airodump-ng wlan0mon
# Target a specific channel and BSSID (stops channel hopping)
sudo airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:FF -w capture wlan0mon
# 5 GHz only scan (channels 36-165)
sudo airodump-ng --band a wlan0mon
# Dual-band scan (2.4 + 5 GHz simultaneously)
sudo airodump-ng --band abg wlan0mon# Full scan — all channels, all bands
sudo airodump-ng wlan0mon
# Target a specific channel and BSSID (stops channel hopping)
sudo airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:FF -w capture wlan0mon
# 5 GHz only scan (channels 36-165)
sudo airodump-ng --band a wlan0mon
# Dual-band scan (2.4 + 5 GHz simultaneously)
sudo airodump-ng --band abg wlan0monUnderstanding Airodump Output
| Column | Meaning | Attack Relevance |
|---|---|---|
| BSSID | AP MAC address | Target identifier, vendor OUI lookup |
| PWR | Signal strength (dBm) | > -60 = strong, > -40 = very close |
| Beacons | Beacon frames received | Rapid increase = active AP near you |
| #Data | Data frames captured | High count = active clients (WEP/handshake targets) |
| CH | Channel | Lock to this channel for targeted attacks |
| ENC | Encryption (WPA2, WEP, OPN) | Determines attack approach |
| CIPHER | CCMP or TKIP | TKIP = vulnerable to TKIP Michael attacks |
| AUTH | PSK or MGT | MGT = Enterprise (802.1X), PSK = Pre-shared key |
| ESSID | Network name | Blank or <length: N> = hidden SSID |
| MB | Max speed (Mbps) | 802.11n/ac indicator, helps ID hardware gen |
Hidden SSID Discovery
Hidden SSIDs Are Not Security
Hidden networks appear in airodump-ng as <length: N> where N is the SSID length.
There are four reliable methods to reveal the actual SSID:
Method 1: Passive Wait
Lock airodump to the hidden AP's channel and wait. When any client connects or sends a directed probe request, the ESSID will appear automatically.
# Lock to hidden AP's channel and wait for client probe
sudo airodump-ng -c 11 --bssid AA:BB:CC:DD:EE:FF wlan0mon
# ESSID will populate when a client sends a probe request# Lock to hidden AP's channel and wait for client probe
sudo airodump-ng -c 11 --bssid AA:BB:CC:DD:EE:FF wlan0mon
# ESSID will populate when a client sends a probe requestMethod 2: Forced Deauthentication
If no clients are actively associating, force a disconnect. The reconnection handshake reveals the SSID.
# Deauth a connected client — they'll re-probe with the SSID
sudo aireplay-ng -0 5 -a AA:BB:CC:DD:EE:FF -c CC:DD:EE:FF:00:11 wlan0mon
# Watch airodump — ESSID appears on reassociation
sudo airodump-ng -c 11 --bssid AA:BB:CC:DD:EE:FF wlan0mon# Deauth a connected client — they'll re-probe with the SSID
sudo aireplay-ng -0 5 -a AA:BB:CC:DD:EE:FF -c CC:DD:EE:FF:00:11 wlan0mon
# Watch airodump — ESSID appears on reassociation
sudo airodump-ng -c 11 --bssid AA:BB:CC:DD:EE:FF wlan0monMethod 3: Probe Request Sniffing with Wireshark
Capture all probe requests to see which SSIDs clients around you are searching for — including hidden ones.
# Capture and filter for probe requests containing the target BSSID
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x04" \
-T fields -e wlan.ssid -e wlan.sa | sort -u
# Wireshark display filter for probe requests
wlan.fc.type_subtype == 0x04 && wlan.ssid != ""# Capture and filter for probe requests containing the target BSSID
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x04" \
-T fields -e wlan.ssid -e wlan.sa | sort -u
# Wireshark display filter for probe requests
wlan.fc.type_subtype == 0x04 && wlan.ssid != ""Method 4: MDK4 SSID Brute Force
If the SSID length is known (from the <length: N> value), brute-force or dictionary attack the name.
This works because APs respond to correct probe requests even when hidden.
# Brute force hidden SSID using MDK4 probe mode
sudo mdk4 wlan0mon p -t AA:BB:CC:DD:EE:FF -f /usr/share/wordlists/ssid-list.txt
# Generate SSID wordlist from common patterns
crunch 8 8 abcdefghijklmnopqrstuvwxyz0123456789 | \
sudo mdk4 wlan0mon p -t AA:BB:CC:DD:EE:FF -s# Brute force hidden SSID using MDK4 probe mode
sudo mdk4 wlan0mon p -t AA:BB:CC:DD:EE:FF -f /usr/share/wordlists/ssid-list.txt
# Generate SSID wordlist from common patterns
crunch 8 8 abcdefghijklmnopqrstuvwxyz0123456789 | \
sudo mdk4 wlan0mon p -t AA:BB:CC:DD:EE:FF -sKismet Deep Dive
Kismet is a passive wireless network detector, sniffer, wardriving tool, and WIDS framework. Unlike airodump-ng, Kismet runs a persistent web UI, supports multiple data sources simultaneously, logs to a SQLite database for post-analysis, and detects non-802.11 protocols (Bluetooth, Zigbee, BTLE).
Installation & Configuration
# Install Kismet (Kali/Debian)
sudo apt install kismet
# Add your user to the kismet group (avoids running as root)
sudo usermod -aG kismet $USER
# Start Kismet with a Wi-Fi source
kismet -c wlan0mon
# Start with multiple sources (dual-band + Bluetooth)
kismet -c wlan0mon:name=WiFi_2G -c wlan1mon:name=WiFi_5G -c hci0:name=BTLE# Install Kismet (Kali/Debian)
sudo apt install kismet
# Add your user to the kismet group (avoids running as root)
sudo usermod -aG kismet $USER
# Start Kismet with a Wi-Fi source
kismet -c wlan0mon
# Start with multiple sources (dual-band + Bluetooth)
kismet -c wlan0mon:name=WiFi_2G -c wlan1mon:name=WiFi_5G -c hci0:name=BTLE
Access the Kismet web UI at http://localhost:2501. The dashboard shows live AP discovery,
client associations, alerts, and GPS mapping (if a GPS receiver is attached).
Kismet Configuration Tuning
# /etc/kismet/kismet.conf — key settings
# Override default source (or add via CLI)
source=wlan0mon:name=MainWiFi,hop=true,hop_rate=5/sec
# Channel lock for targeted recon
source=wlan0mon:name=TargetCH,channel=6
# Enable PCAP logging for offline analysis
log_types=kismet,pcapng
# Wardriving — enable GPS
gps=gpsd:host=localhost,port=2947
# Alert on rogue APs — compare against known BSSID list
# (edit /etc/kismet/kismet_alerts.conf)
apspoof=CorpWiFi:ssidregex="CorpWiFi",validmacs=AA:BB:CC:DD:EE:FF# /etc/kismet/kismet.conf — key settings
# Override default source (or add via CLI)
source=wlan0mon:name=MainWiFi,hop=true,hop_rate=5/sec
# Channel lock for targeted recon
source=wlan0mon:name=TargetCH,channel=6
# Enable PCAP logging for offline analysis
log_types=kismet,pcapng
# Wardriving — enable GPS
gps=gpsd:host=localhost,port=2947
# Alert on rogue APs — compare against known BSSID list
# (edit /etc/kismet/kismet_alerts.conf)
apspoof=CorpWiFi:ssidregex="CorpWiFi",validmacs=AA:BB:CC:DD:EE:FFQuerying the Kismet Database
Kismet stores results in a SQLite .kismet database. Query it for post-engagement analysis.
# List all discovered SSIDs with encryption types
sqlite3 Kismet-*.kismet "SELECT devmac, type, CAST(device AS TEXT) FROM devices WHERE type='Wi-Fi AP';" | head -20
# REST API — query device list (while Kismet is running)
curl -s http://localhost:2501/devices/summary/devices.json \
-H 'KISMET: admin:changeme' | python3 -m json.tool | head -30
# Export to Wigle CSV for wardriving upload
kismetdb_to_wiglecsv --in Kismet-*.kismet --out wardriving-results.csv
# Convert to pcapng for Wireshark analysis
kismetdb_to_pcap --in Kismet-*.kismet --out capture.pcapng# List all discovered SSIDs with encryption types
sqlite3 Kismet-*.kismet "SELECT devmac, type, CAST(device AS TEXT) FROM devices WHERE type='Wi-Fi AP';" | head -20
# REST API — query device list (while Kismet is running)
curl -s http://localhost:2501/devices/summary/devices.json \
-H 'KISMET: admin:changeme' | python3 -m json.tool | head -30
# Export to Wigle CSV for wardriving upload
kismetdb_to_wiglecsv --in Kismet-*.kismet --out wardriving-results.csv
# Convert to pcapng for Wireshark analysis
kismetdb_to_pcap --in Kismet-*.kismet --out capture.pcapngKismet vs. Airodump-ng
Channel Strategy & Band Planning
Understanding channel allocation is critical for efficient scanning and avoiding interference during attacks. Locking to the wrong channel wastes time and misses handshakes.
2.4 GHz Band (802.11b/g/n)
| Channels | Non-Overlapping | Width | Notes |
|---|---|---|---|
| 1 – 14 | 1, 6, 11 | 20 MHz | Most APs on 1/6/11 — scan these first |
| 14 | — | 22 MHz | Japan only (802.11b), rarely seen |
| 1 – 13 | 1, 5, 9, 13 (EU) | 20 MHz | European 4-channel plan |
5 GHz Band (802.11a/n/ac/ax)
| Band | Channels | DFS Required | Notes |
|---|---|---|---|
| UNII-1 | 36, 40, 44, 48 | No | Most common — scan first |
| UNII-2 | 52, 56, 60, 64 | Yes | Shared with radar — APs may vacate |
| UNII-2 Ext | 100–144 | Yes | Often empty — targets here are less monitored |
| UNII-3 | 149, 153, 157, 161, 165 | No | Common in US, less in EU |
DFS Channels & Radar Detection
Efficient Scanning Strategy
# Step 1: Quick 2.4 GHz sweep — channels 1, 6, 11 only (covers ~90% of APs)
sudo airodump-ng --channel 1,6,11 wlan0mon -w quick-scan --output-format csv
# Step 2: Full 5 GHz sweep (if adapter supports it)
sudo airodump-ng --band a wlan0mon -w 5ghz-scan --output-format csv
# Step 3: Lock to target channel for handshake capture
sudo airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:FF -w target wlan0mon
# Tip: Use '--channel-hop-dwell-time' flag to control hop speed
# Shorter dwell = wider scan, fewer packets per channel
# Longer dwell = narrower scan, more packets, better for remote APs
sudo airodump-ng --channel-hop-dwell-time 500ms wlan0mon# Step 1: Quick 2.4 GHz sweep — channels 1, 6, 11 only (covers ~90% of APs)
sudo airodump-ng --channel 1,6,11 wlan0mon -w quick-scan --output-format csv
# Step 2: Full 5 GHz sweep (if adapter supports it)
sudo airodump-ng --band a wlan0mon -w 5ghz-scan --output-format csv
# Step 3: Lock to target channel for handshake capture
sudo airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:FF -w target wlan0mon
# Tip: Use '--channel-hop-dwell-time' flag to control hop speed
# Shorter dwell = wider scan, fewer packets per channel
# Longer dwell = narrower scan, more packets, better for remote APs
sudo airodump-ng --channel-hop-dwell-time 500ms wlan0monPassive Fingerprinting
Beyond basic SSID/BSSID enumeration, you can extract detailed information about AP hardware, firmware, and security capabilities from passive observation alone — no active probing required.
# OUI vendor lookup from BSSID (first 3 octets)
# AA:BB:CC:DD:EE:FF → look up AA:BB:CC at https://maclookup.app
# This reveals the AP manufacturer (Ubiquiti, Cisco, TP-Link, etc.)
# Extract supported rates and capabilities from beacons
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x08" \
-T fields -e wlan.bssid -e wlan.ssid -e wlan.fixed.capabilities \
-e wlan_radio.channel -e wlan.rsn.pcs.type | sort -u
# Identify WPS-enabled APs (Wash)
sudo wash -i wlan0mon -C
# Look for "Lck" column = WPS lock status
# Version 1.0 = vulnerable to Pixie Dust and brute force
# Probe for 802.11w (MFP) support
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x08 && wlan.rsn.capabilities.mfpc == 1" \
-T fields -e wlan.bssid -e wlan.ssid -e wlan.rsn.capabilities.mfpr# OUI vendor lookup from BSSID (first 3 octets)
# AA:BB:CC:DD:EE:FF → look up AA:BB:CC at https://maclookup.app
# This reveals the AP manufacturer (Ubiquiti, Cisco, TP-Link, etc.)
# Extract supported rates and capabilities from beacons
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x08" \
-T fields -e wlan.bssid -e wlan.ssid -e wlan.fixed.capabilities \
-e wlan_radio.channel -e wlan.rsn.pcs.type | sort -u
# Identify WPS-enabled APs (Wash)
sudo wash -i wlan0mon -C
# Look for "Lck" column = WPS lock status
# Version 1.0 = vulnerable to Pixie Dust and brute force
# Probe for 802.11w (MFP) support
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x08 && wlan.rsn.capabilities.mfpc == 1" \
-T fields -e wlan.bssid -e wlan.ssid -e wlan.rsn.capabilities.mfprClient Enumeration & Probe Analysis
Client devices leak valuable intelligence through probe requests — they broadcast the names of every network they've previously connected to. This enables targeted evil twin attacks.
# List all client probes visible in the area
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x04" \
-T fields -e wlan.sa -e wlan.ssid 2>/dev/null | sort | uniq -c | sort -rn
# Example output:
# 47 CC:DD:EE:FF:00:11 CorpWiFi ← employee phone, searching for work SSID
# 23 CC:DD:EE:FF:00:11 Hilton_WiFi ← recently stayed at Hilton
# 12 AA:BB:CC:DD:EE:22 ATT-WIFI-1234 ← home network name
# 8 AA:BB:CC:DD:EE:33 <Broadcast> ← modern device, doesn't leak SSIDs
# Correlate clients to APs (airodump lower pane)
# The "Probes" column shows SSIDs each client has searched for
# The "BSSID" column shows which AP they're currently associated to
# Filter for clients NOT associated to any AP (searching/roaming)
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x04 && wlan.da == ff:ff:ff:ff:ff:ff" \
-T fields -e wlan.sa -e wlan.ssid | sort -u# List all client probes visible in the area
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x04" \
-T fields -e wlan.sa -e wlan.ssid 2>/dev/null | sort | uniq -c | sort -rn
# Example output:
# 47 CC:DD:EE:FF:00:11 CorpWiFi ← employee phone, searching for work SSID
# 23 CC:DD:EE:FF:00:11 Hilton_WiFi ← recently stayed at Hilton
# 12 AA:BB:CC:DD:EE:22 ATT-WIFI-1234 ← home network name
# 8 AA:BB:CC:DD:EE:33 <Broadcast> ← modern device, doesn't leak SSIDs
# Correlate clients to APs (airodump lower pane)
# The "Probes" column shows SSIDs each client has searched for
# The "BSSID" column shows which AP they're currently associated to
# Filter for clients NOT associated to any AP (searching/roaming)
tshark -i wlan0mon -Y "wlan.fc.type_subtype == 0x04 && wlan.da == ff:ff:ff:ff:ff:ff" \
-T fields -e wlan.sa -e wlan.ssid | sort -uMAC Randomization
Output Formats & Post-Processing
# Save in all useful formats simultaneously
sudo airodump-ng -w recon --output-format pcap,csv,kismet,netxml wlan0mon
# Output files created:
# recon-01.cap — full packet capture (Wireshark, hashcat, hcxpcapngtool)
# recon-01.csv — parseable spreadsheet (Excel, grep, awk)
# recon-01.kismet.csv — Kismet-compatible CSV
# recon-01.kismet.netxml — XML format for scripting
# Quick CSV analysis — top APs by client count
awk -F',' 'NR>2 && $1!="" {print $14, $1}' recon-01.csv | sort | uniq -c | sort -rn | head -20
# Parse with Python for reporting
python3 -c "
import csv
with open('recon-01.csv') as f:
reader = csv.reader(f)
for row in reader:
if len(row) > 13 and row[5].strip():
print(f'{row[0].strip():20s} CH:{row[3].strip():3s} ENC:{row[5].strip():6s} {row[13].strip()}')" # Save in all useful formats simultaneously
sudo airodump-ng -w recon --output-format pcap,csv,kismet,netxml wlan0mon
# Output files created:
# recon-01.cap — full packet capture (Wireshark, hashcat, hcxpcapngtool)
# recon-01.csv — parseable spreadsheet (Excel, grep, awk)
# recon-01.kismet.csv — Kismet-compatible CSV
# recon-01.kismet.netxml — XML format for scripting
# Quick CSV analysis — top APs by client count
awk -F',' 'NR>2 && $1!="" {print $14, $1}' recon-01.csv | sort | uniq -c | sort -rn | head -20
# Parse with Python for reporting
python3 -c "
import csv
with open('recon-01.csv') as f:
reader = csv.reader(f)
for row in reader:
if len(row) > 13 and row[5].strip():
print(f'{row[0].strip():20s} CH:{row[3].strip():3s} ENC:{row[5].strip():6s} {row[13].strip()}')" Practice Labs
Practice wireless recon techniques in isolated environments.