Fix WPA/RSN detection in the WiFi bridge, and add the missing pkt_sniff.py - #12
Open
willryker wants to merge 1 commit into
Open
Fix WPA/RSN detection in the WiFi bridge, and add the missing pkt_sniff.py#12willryker wants to merge 1 commit into
willryker wants to merge 1 commit into
Conversation
wdg_wifi_bridge.py: - _auth_from_iw() only matched the literal strings "WPA2"/"WPA3", which `iw scan` never prints -- it reports modern security as an "RSN:" information element. 31 of 37 APs in a live scan were therefore classified OPEN. This is not cosmetic: the value feeds loot_manager._AUTH_MAP and is uploaded to WiGLE, so secured networks would be published as open. Map RSN->WPA2, RSN+SAE->WPA3, RSN+PSK+SAE->WPA2/WPA3, and also collect "Authentication suites" lines, since the AKM suite is the only way to tell WPA3 from WPA2. - Refuse to start the packet sniffer while a handshake capture is running, and vice versa. With a single capture radio the two fight over channel hopping, and whichever exits first drops the interface back to managed mode and kills the other mid-capture. The refusal strings deliberately read "hs capture"/"pkt sniffer": "handshake ... captur" or "packet sniffer" in bridge output would trip app.py's state detection and flip the game into a mode nothing is actually running. pkt_sniff.py (new): - The bridge dispatches this on start_sniffer/start_pkt_sniff, but it does not exist upstream, so the Pkt Sniffer menu item has always errored. Implements the contract the bridge expects: a scapy monitor-mode sniffer with 2.4/5GHz channel hopping, live AP/client/deauth lines, periodic summaries in parse_sniffer_results() format, and pcap + text loot output. - Prints with flush=True throughout; the bridge reads stdout as a pipe, so block buffering would leave the game with no output until exit. - Only restores managed mode if it was the one that set monitor, so it cannot knock the radio out from under a handshake capture already using it. - Filters group (multicast) addresses by the I/G bit. Without it every mDNS/SSDP frame an AP forwards was counted as a connected station, making the per-AP client counts meaningless. - Ranks the summary by client count before packet count, so the AP clients are actually associated to is not crowded out by beacon-heavy neighbours. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DZnaedMVnFLztkCsmWGVfv
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.
Fix WPA/RSN detection in the WiFi bridge, and add the missing pkt_sniff.py
Two independent fixes plus one new file, all in the Linux host-radio bridge path
(
wdg_wifi_bridge.py). Tested on a uConsole (CM5, Debian trixie) driving aMediaTek MT7921AU adapter in place of an ESP32.
1.
_auth_from_iw()reports almost every network as OPENiw scannever prints the literal stringsWPA2orWPA3. It reports modernsecurity as an
RSN:information element, and_auth_from_iw()only matchedthe literal version strings — so every WPA2/WPA3 network fell through to
OPEN.On a live scan here that was 31 of 37 access points misclassified.
This is not cosmetic. The value feeds
loot_manager._AUTH_MAPand is uploaded toWiGLE, so any bridge user wardriving is publishing secured networks as open
and quietly polluting a public dataset.
The fix maps
RSN→WPA2,RSN+SAE→WPA3,RSN+PSK+SAE→WPA2/WPA3, andRSN+WPA→WPA/WPA2.scan_wifi()now also collectsAuthentication suiteslines, because the AKM suite is the only way to tell WPA3from WPA2. Only tokens
loot_manager._AUTH_MAPalready knows are emitted.Verified after the change: an eero mesh reads
WPA2/WPA3, a Spectrum gatewayreads
WPA2, and a genuinely open speaker setup AP still readsOPEN.2.
pkt_sniff.pydid not exist_start_pkt()dispatchespkt_sniff.pyonstart_sniffer/start_pkt_sniff,but the file is not in the repo, so the Pkt Sniffer menu item has always failed
with
sniffer error: pkt_sniff.py not found.This adds it, matching
hs_capture.py's conventions and the contract the bridgealready expects (
--iface,--loot-dir, streamed stdout, SIGTERM shutdown):the regulatory domain rejects rather than retrying them every pass
[SNF] AP/[SNF] STA/[SNF] DEAUTHlines, periodic summaries in the"<ssid>, CH<n>: <count>"shapenetwork_manager.parse_sniffer_results()documents, and pcap + text output into the loot directory
print(..., flush=True)throughout — the bridge reads stdout as a pipe, soblock buffering would leave the game with no output until the process exits
mDNS/SSDP frame an AP forwards is counted as an associated station and the
per-AP client counts are meaningless
actually associated to is not crowded out by beacon-heavy neighbours
3. Handshake capture and the packet sniffer can destroy each other
hs_capture.pyandpkt_sniff.pyboth take the--sniffer-ifaceradio. Runtogether they fight over channel hopping, and whichever exits first drops the
interface back to managed mode, killing the other mid-capture. This is guaranteed
to bite on a single-adapter setup, where
--ifaceand--sniffer-ifaceare thesame device.
The bridge now refuses to start either while the other is active, and
pkt_sniff.pyonly restores managed mode if it was the one that set monitor.Note the refusal strings deliberately read "hs capture" / "pkt sniffer": emitting
handshake ... capturorpacket snifferwould tripapp.py's_handle_serial_line()state detection and flip the game into a mode nothing isactually running.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DZnaedMVnFLztkCsmWGVfv