attack: add WPA3-SAE Transition Mode PMKID discovery via directed probe#70
Open
lasersharkkiller wants to merge 1 commit into
Open
Conversation
## Problem
AngryOxide's M1-retrieval (PMKID) attack only fires when an AP has a
confirmed PSK AKM in its RSN IE. Some WPA3-SAE Transition Mode APs
advertise only SAE in their beacon RSN IE while still including PSK in
their probe response RSN IE — a valid 802.11 configuration. These APs
were invisible to PMKID collection because the PSK flag was never set
from the beacon alone.
## What this PR adds
### 1. `APFlags::is_sae_transition_mode()` (src/devices.rs)
Helper that returns `true` when an AP advertises both SAE and PSK AKMs
in its RSN IE — the canonical definition of WPA3-SAE Transition Mode.
Used by attack code to distinguish transition mode from plain WPA2.
### 2. `build_probe_request_ap_ssid()` (src/tx.rs)
New frame builder that sends a unicast probe request directly to a
specific AP MAC address, carrying the AP's SSID. Unlike the existing
`build_probe_request_directed` (broadcast + SSID) and
`build_probe_request_target` (unicast + no SSID), this variant is
addressed to the AP so only that AP responds, and carries the SSID so
the AP replies with its full probe-response RSN IE.
### 3. `transition_probe_attack()` (src/attack.rs)
New attack function that runs in the beacon processing loop. When an
AP is seen advertising SAE but PSK support has not yet been confirmed
(rsn_akm_psk != Some(true)) and no probe response has been received
yet (pr_station.is_none()), a unicast probe request is sent to the AP
every 32 beacons (~3 s at typical beacon rates) until a response
arrives.
Gate conditions (all must be true to fire):
- disable_pmkid is false
- notx is false
- AP is a target and not whitelisted
- No complete handshake already collected
- rsn_akm_sae == Some(true)
- rsn_akm_psk != Some(true) (PSK not yet confirmed)
- pr_station.is_none() (no probe response received yet)
- Has an SSID
- beacon_count % 32 == 0 (rate limit)
### 4. m1_retrieval_attack / m1_retrieval_attack_phase_2 (src/attack.rs)
Both functions now detect transition mode (is_sae_transition_mode())
and emit distinct status log messages:
- Phase 1: "M1 Retrieval (SAE Transition) - Sent Authentication Req"
- Phase 2: "M1 Retrieval (SAE Transition PSK Downgrade) - Sent Association Req"
The association request continues to advertise only PSK AKM (SAE
stripped), forcing the AP onto its WPA2 code path which returns an
EAPOL M1 that may contain a PSK-derived PMKID crackable offline.
### 5. Beacon loop call site (src/main.rs)
`transition_probe_attack` is called just before `m1_retrieval_attack`
on every beacon. For APs that already have PSK confirmed the gate
returns immediately with no overhead.
## Full event cycle for a beacon-SAE-only transition mode AP
beacon (SAE only, no PSK in RSN)
→ transition_probe_attack fires (beacon_count % 32 == 0)
→ unicast probe request sent to AP with its SSID
→ AP sends probe response (full RSN IE: SAE + PSK)
→ probe response handler: update_with() sets rsn_akm_psk=Some(true),
pr_station=Some(...)
→ m1_retrieval_attack fires immediately (existing hook at line ~1464)
→ OpenSystem authentication request sent
→ AP responds auth_seq=2
→ m1_retrieval_attack_phase_2: PSK-only assoc request (SAE stripped)
→ AP sends EAPOL M1 containing PSK-derived PMKID
→ PMKID written to .hc22000
Discovery and PMKID collection collapse into a single probe/response
event cycle rather than requiring a beacon that already contains PSK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
AngryOxide's M1-retrieval (PMKID) attack only fires when an AP has a confirmed PSK AKM in its RSN IE. Some WPA3-SAE Transition Mode APs advertise only SAE in their beacon RSN IE while still including PSK in their probe response RSN IE — a valid 802.11 configuration. These APs were invisible to PMKID collection because the PSK flag was never set from the beacon alone.
What this PR adds
1.
APFlags::is_sae_transition_mode()(src/devices.rs) Helper that returnstruewhen an AP advertises both SAE and PSK AKMs in its RSN IE — the canonical definition of WPA3-SAE Transition Mode. Used by attack code to distinguish transition mode from plain WPA2.2.
build_probe_request_ap_ssid()(src/tx.rs) New frame builder that sends a unicast probe request directly to a specific AP MAC address, carrying the AP's SSID. Unlike the existingbuild_probe_request_directed(broadcast + SSID) andbuild_probe_request_target(unicast + no SSID), this variant is addressed to the AP so only that AP responds, and carries the SSID so the AP replies with its full probe-response RSN IE.3.
transition_probe_attack()(src/attack.rs) New attack function that runs in the beacon processing loop. When an AP is seen advertising SAE but PSK support has not yet been confirmed (rsn_akm_psk != Some(true)) and no probe response has been received yet (pr_station.is_none()), a unicast probe request is sent to the AP every 32 beacons (~3 s at typical beacon rates) until a response arrives.Gate conditions (all must be true to fire):
4. m1_retrieval_attack / m1_retrieval_attack_phase_2 (src/attack.rs) Both functions now detect transition mode (is_sae_transition_mode()) and emit distinct status log messages:
The association request continues to advertise only PSK AKM (SAE stripped), forcing the AP onto its WPA2 code path which returns an EAPOL M1 that may contain a PSK-derived PMKID crackable offline.
5. Beacon loop call site (src/main.rs)
transition_probe_attackis called just beforem1_retrieval_attackon every beacon. For APs that already have PSK confirmed the gate returns immediately with no overhead.Full event cycle for a beacon-SAE-only transition mode AP
beacon (SAE only, no PSK in RSN)
→ transition_probe_attack fires (beacon_count % 32 == 0)
→ unicast probe request sent to AP with its SSID
→ AP sends probe response (full RSN IE: SAE + PSK)
→ probe response handler: update_with() sets rsn_akm_psk=Some(true),
pr_station=Some(...)
→ m1_retrieval_attack fires immediately (existing hook at line ~1464)
→ OpenSystem authentication request sent
→ AP responds auth_seq=2
→ m1_retrieval_attack_phase_2: PSK-only assoc request (SAE stripped)
→ AP sends EAPOL M1 containing PSK-derived PMKID
→ PMKID written to .hc22000
Discovery and PMKID collection collapse into a single probe/response event cycle rather than requiring a beacon that already contains PSK.