0ldev/Politician
GitHub: 0ldev/Politician
专为 ESP32 平台设计的现代 WiFi 安全审计库,支持 WPA/WPA2/WPA3 握手包捕获、PMKID 提取、CSA 注入绕过 PMF,以及企业凭据获取,输出 PCAPNG/Hashcat 格式。
Stars: 44 | Forks: 2
# Politician
[](https://opensource.org/licenses/MIT)
[](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, 去认证攻击, 嵌入式开发, 握手包捕获, 数据擦除, 无线审计, 物联网安全, 足迹分析, 隐藏网络发现