Politician
Modern WiFi auditing library for ESP32 using advanced 802.11 techniques. Captures WPA/WPA2/WPA3 handshakes via PMKID extraction and CSA injection (bypasses PMF). Harvests enterprise credentials, supports dual-band (2.4GHz/5GHz on ESP32-C6), exports to PCAPNG/Hashcat. Clean C++ API with 9 examples.
Install / Use
/learn @0ldev/PoliticianREADME
Politician
A sophisticated WiFi auditing library for ESP32 microcontrollers
Politician is an embedded C++ library designed for WiFi security auditing on ESP32 platforms. It provides a clean, modern API for capturing WPA/WPA2/WPA3 handshakes and harvesting enterprise credentials using advanced 802.11 protocol techniques.
Key Capabilities
- PMKID Capture: Extract PMKIDs from association responses without client disconnection
- CSA (Channel Switch Announcement) Injection: Modern alternative to deauthentication attacks
- Enterprise Credential Harvesting: Capture EAP-Identity frames from 802.1X networks
- Hidden Network Discovery: Automatic SSID decloaking via probe response interception
- Client Stimulation: Wake sleeping mobile devices using QoS Null Data frames
- WPA3/PMF Detection: Intelligent filtering to skip Protected Management Frame-enabled networks
- Export Formats: PCAPNG capture files; optional HC22000 text export for direct Hashcat ingestion
Architecture
The library is built around a non-blocking state machine that manages channel hopping, target selection, attack execution, and capture processing. All operations are contained within the politician namespace.
Core Components
| Component | Description |
|-----------|-------------|
| Politician | Main engine class managing the audit lifecycle |
| PoliticianFormat | PCAPNG capture serialization; auxiliary HC22000 text export |
| PoliticianStorage | Optional SD card logging and NVS persistence |
| PoliticianStress | Decoupled DoS/disruption payload delivery (opt-in) |
| PoliticianTypes | Core data structures and enumerations |
Attack Modes
Traditional deauthentication attacks are ineffective against modern WPA3 and WPA2 networks with Protected Management Frames (PMF/802.11w). Politician implements modern alternatives:
| Mode | Description | Effectiveness |
|------|-------------|---------------|
| ATTACK_PMKID | Extract PMKID via dummy authentication | Works on all WPA2/WPA3-Transition |
| ATTACK_CSA | Channel Switch Announcement injection | Bypasses PMF protections |
| ATTACK_DEAUTH | Legacy deauthentication (Reason 7) | WPA2 without PMF only |
| ATTACK_STIMULATE | QoS Null Data for sleeping clients | Non-intrusive client wake-up |
| ATTACK_PASSIVE | Listen-only mode | Zero transmission |
| ATTACK_ALL | Enable all active attack vectors | Maximum aggression |
Installation
PlatformIO
Add to your platformio.ini:
[env:myboard]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
Politician
Or clone directly into your project's lib/ directory:
cd lib/
git clone https://github.com/0ldev/Politician.git
Arduino IDE
- Download the library as a ZIP file
- In Arduino IDE: Sketch → Include Library → Add .ZIP Library
- Select the downloaded ZIP file
Quick Start
Basic Handshake Capture
#include <Arduino.h>
#include <SD.h>
#include <Politician.h>
#include <PoliticianStorage.h>
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 Reference
Politician Class
The main engine class. Must call tick() in your main loop.
Initialization
Error begin(const Config& cfg = Config());
Initialize the engine. Returns OK on success or an Error code on failure. Must be called before any other method.
Configuration Structure
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
};
Callbacks
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)
State & Stats
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
Engine Control
void setActive(bool active); // Enable or disable frame processing without full teardown
void setLogger(LogCb cb); // Redirect internal log output to a custom callback
Target & Channel Control
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); // Conti
Related Skills
node-connect
351.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
110.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
351.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
351.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
