WiFi Reconnaissance

Reconnaissance
🌱 Beginner
T1040 T1592

Reconnaissance involves discovering available networks (ESSIDs), their security configurations, and connected clients.

What to Record During Recon

For each target AP note: BSSID, channel, encryption type (ENC), signal strength (PWR), and the number of associated clients. A strong signal (PWR > -60) + active clients = ideal handshake target. Save airodump output with -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.

01-airodump-scan.sh
bash
# 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 wlan0mon

Understanding Airodump Output

Column Meaning Attack Relevance
BSSIDAP MAC addressTarget identifier, vendor OUI lookup
PWRSignal strength (dBm)> -60 = strong, > -40 = very close
BeaconsBeacon frames receivedRapid increase = active AP near you
#DataData frames capturedHigh count = active clients (WEP/handshake targets)
CHChannelLock to this channel for targeted attacks
ENCEncryption (WPA2, WEP, OPN)Determines attack approach
CIPHERCCMP or TKIPTKIP = vulnerable to TKIP Michael attacks
AUTHPSK or MGTMGT = Enterprise (802.1X), PSK = Pre-shared key
ESSIDNetwork nameBlank or <length: N> = hidden SSID
MBMax speed (Mbps)802.11n/ac indicator, helps ID hardware gen

Hidden SSID Discovery

Hidden SSIDs Are Not Security

Hiding an SSID only removes the name from beacon frames — the network still broadcasts beacons and responds to directed probe requests. Any client that connects (or has the SSID saved) will reveal it in plaintext. This is security through obscurity with zero cryptographic value.

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.

02-hidden-passive.sh
bash
# 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 request

Method 2: Forced Deauthentication

If no clients are actively associating, force a disconnect. The reconnection handshake reveals the SSID.

03-hidden-deauth.sh
bash
# 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 wlan0mon

Method 3: Probe Request Sniffing with Wireshark

Capture all probe requests to see which SSIDs clients around you are searching for — including hidden ones.

04-hidden-probe-sniff.sh
bash
# 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.

05-hidden-bruteforce.sh
bash
# 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 -s

Kismet 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

06-kismet-install.sh
bash
# 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

kismet.conf
ini
# /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:FF

Querying the Kismet Database

Kismet stores results in a SQLite .kismet database. Query it for post-engagement analysis.

07-kismet-query.sh
bash
# 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.pcapng

Kismet vs. Airodump-ng

Use airodump-ng for quick tactical scans — it's faster to launch and simpler to read. Use Kismet for long-duration wardriving, multi-source recon, WIDS alerting, and when you need structured database output for reporting. The two complement each other.

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 – 141, 6, 1120 MHzMost APs on 1/6/11 — scan these first
1422 MHzJapan only (802.11b), rarely seen
1 – 131, 5, 9, 13 (EU)20 MHzEuropean 4-channel plan

5 GHz Band (802.11a/n/ac/ax)

Band Channels DFS Required Notes
UNII-136, 40, 44, 48NoMost common — scan first
UNII-252, 56, 60, 64YesShared with radar — APs may vacate
UNII-2 Ext100–144YesOften empty — targets here are less monitored
UNII-3149, 153, 157, 161, 165NoCommon in US, less in EU

DFS Channels & Radar Detection

DFS (Dynamic Frequency Selection) channels require APs to vacate if radar is detected. During pentesting, you can abuse this: spoofing radar pulses with an SDR forces all APs on DFS channels offline. This is federally illegal in most countries (it disrupts aviation/weather radar). Only test on isolated lab networks.

Efficient Scanning Strategy

08-channel-strategy.sh
bash
# 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 wlan0mon

Passive 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.

09-passive-fingerprint.sh
bash
# 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.mfpr

Client 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.

10-client-probes.sh
bash
# 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 -u

MAC Randomization

Modern iOS and Android devices randomize their MAC address during probe requests. The real MAC is only revealed after the device associates to an AP. Look for locally-administered MACs (second hex digit is 2, 6, A, or E) — these are randomized and won't match the real device MAC.

Output Formats & Post-Processing

11-output-formats.sh
bash
# 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.

🏠
WiFi Hacking 101 TryHackMe easy
airodump-ngBSSID/ESSID enumerationclient discovery
Open Lab
🔧
Wireless Recon Lab Custom Lab easy
kismet scanninghidden SSID revealpassive monitoring