Politician 1.0.0
WiFi Auditing Library for ESP32
Loading...
Searching...
No Matches
PoliticianTypes.h
Go to the documentation of this file.
1#pragma once
2#include <stdint.h>
3#include "politician_compat.h"
4
5namespace politician {
6
7// ─── Compile-Time Feature Gates ──────────────────────────────────────────────
8// Define these before including Politician.h or via build flags (e.g. -DNAME)
9// #define POLITICIAN_NO_DB // Strip 14KB OUI Database (Vendor lookups)
10// #define POLITICIAN_NO_PCAPNG // Strip PCAPNG serialization logic
11// #define POLITICIAN_NO_HC22000 // Strip Hashcat mode 22000 formatter
12// #define POLITICIAN_NO_LOGGING // Strip all internal Serial _log() output
13
14// ─── Capture Types ────────────────────────────────────────────────────────────
15#define CAP_PMKID 0x01 // PMKID fishing (fake association)
16#define CAP_EAPOL 0x02 // Passive EAPOL (natural client reconnection)
17#define CAP_EAPOL_CSA 0x03 // EAPOL triggered by CSA beacon injection
18#define CAP_EAPOL_HALF 0x04 // M2-only capture (no anonce) — active attack pivot triggered
19#define CAP_EAPOL_GROUP 0x05 // Non-pairwise EAPOL-Key (GTK rotation)
20#define CAP_SAE 0x06 // WPA3 SAE (Simultaneous Authentication of Equals) Commit/Confirm frame
21
22// ─── Attack Selection Bits ────────────────────────────────────────────────────
23#define ATTACK_PMKID 0x01 // PMKID fishing
24#define ATTACK_CSA 0x02 // CSA beacon injection
25#define ATTACK_PASSIVE 0x04 // Passive EAPOL capture
26#define ATTACK_DEAUTH 0x08 // Classic Reason 7 Deauthentication
27#define ATTACK_STIMULATE 0x10 // Zero-delay QoS Null Client Stimulation
28#define ATTACK_ALL 0x1F
29
30// ─── Capture Filters ──────────────────────────────────────────────────────────
31// NOTE: Logging High-Frequency Intel (like Beacons) via standard SPI (SD.h) will
32// create massive blocking delays (20-50ms per flush) that destroy the hopper's
33// attack loop. If you enable LOG_FILTER_BEACONS or LOG_FILTER_ALL, you MUST
34// use a board wired for SDMMC (4-bit DMA) for non-blocking background writes.
35#define LOG_FILTER_HANDSHAKES 0x01 // EAPOLs, PMKIDs (Crackable info, SPI Safe)
36#define LOG_FILTER_PROBES 0x02 // Probe Requests & Responses (Scouting, SPI Safe)
37#define LOG_FILTER_BEACONS 0x04 // Beacons (Network Mapping, SDMMC ONLY!)
38#define LOG_FILTER_PROBE_REQ 0x08 // Probe Requests as raw EPBs (Client Device History, SPI Safe)
39#define LOG_FILTER_MGMT_DISRUPT 0x10 // Deauth/Disassoc frames as raw EPBs (Attack Detection, SPI Safe)
40#define LOG_FILTER_ALL 0xFF // Everything (SDMMC ONLY!)
41
42// ─── Logging Callback ─────────────────────────────────────────────────────────
43typedef void (*LogCb)(const char *msg);
44
45// ─── Callbacks ────────────────────────────────────────────────────────────────
46struct ApRecord;
47struct HandshakeRecord;
50struct DisruptRecord;
51
52typedef void (*ApFoundCb)(const ApRecord &ap);
53typedef int (*TargetScoreCb)(const ApRecord &ap, const char *vendor); // Returns a priority score for autoTarget
54typedef void (*PacketCb)(const uint8_t *payload, uint16_t len, int8_t rssi, uint8_t channel, uint32_t ts_usec);
55typedef void (*EapolCb)(const HandshakeRecord &rec);
56typedef void (*IdentityCb)(const EapIdentityRecord &rec);
57typedef void (*ProbeRequestCb)(const ProbeRequestRecord &rec);
58typedef void (*DisruptCb)(const DisruptRecord &rec);
59
60// ─── Error Codes ──────────────────────────────────────────────────────────────
69
70/**
71 * @brief Configuration for the Politician engine.
72 */
73struct Config {
74 uint16_t hop_dwell_ms = 200; // Time per channel
75 bool smart_hopping = true; // Dynamic channel dwell time based on traffic
76 uint16_t hop_min_dwell_ms = 50; // Minimum dwell if no traffic is seen
77 uint16_t hop_max_dwell_ms = 400; // Maximum dwell if traffic is active
78 uint32_t m1_lock_ms = 800; // How long to stay on channel after seeing M1
79 uint32_t fish_timeout_ms = 2000; // Time for PMKID association
80 uint8_t fish_max_retries = 2; // PMKID retries before giving up or CSA
81 uint32_t csa_wait_ms = 4000; // How long to wait for reconnect after CSA
82 uint8_t csa_beacon_count = 8; // Number of CSA beacons to burst
83 uint8_t deauth_burst_count = 16; // Number of classic Deauth frames to send
84 uint16_t probe_aggr_interval_s = 30; // Seconds to wait between attacking same AP
85 uint32_t session_timeout_ms = 60000; // How long orphaned handshakes live in RAM
86 bool capture_half_handshakes = false; // Save M2-only captures and pivot to active attack
87 bool skip_immune_networks = true; // Ignore Pure WPA3 / PMF Required networks
88 uint8_t csa_deauth_count = 15; // Number of standard deauths to append
89 uint8_t capture_filter = LOG_FILTER_HANDSHAKES | LOG_FILTER_PROBES; // Exclude Beacons by default to save SD storage
90 int8_t min_rssi = -100; // Ignore APs with signal weaker than this (dBm)
91 uint32_t ap_expiry_ms = 300000; // Evict APs not seen for this long (0 = never expire)
92 bool unicast_deauth = true; // Send deauth to known client MAC instead of broadcast
93 uint32_t probe_hidden_interval_ms = 0; // How often to probe hidden APs for SSID (0 = disabled, opt-in)
94 uint8_t deauth_reason = 7; // 802.11 reason code for deauth frames (7=Class 3 from non-assoc)
95 bool deauth_reason_cycling = true; // Cycle through effective reason codes during burst (fuzzing)
96 bool capture_group_keys = false; // Fire eapolCb with CAP_EAPOL_GROUP on GTK rotation frames
97 uint8_t min_beacon_count = 0; // Min times AP must be seen before attack/apFoundCb (0 = no minimum)
98 uint8_t max_total_attempts = 0; // Permanently skip BSSID after this many failed attacks (0 = unlimited)
99 uint8_t sta_filter[6] = {}; // Only record EAPOL sessions from this client MAC (zero = no filter)
100 char ssid_filter[33] = {}; // Only cache APs matching this SSID (empty = no filter)
101 bool ssid_filter_exact = true; // True = exact SSID match, false = substring match
102 uint8_t enc_filter_mask = 0xFF; // Bitmask of enc types to cache: bit0=open,1=WEP,2=WPA,3=WPA2/3,4=Ent
103 bool require_active_clients = false; // Skip attack initiation if no active clients seen on AP
104};
105
106// ─── AP Record ────────────────────────────────────────────────────────────────
107/** @brief Snapshot of a discovered Access Point from the internal cache. Populated by getAp(), getApByBssid(), and the ApFoundCb callback. */
108struct ApRecord {
109 uint8_t bssid[6];
110 char ssid[33];
111 uint8_t ssid_len;
112 uint8_t channel;
113 int8_t rssi;
114 uint8_t enc; // 0=open, 1=WEP, 2=WPA, 3=WPA2/WPA3, 4=Enterprise
115 bool wps_enabled; // WPS IE detected in beacon/probe-response
116 bool pmf_capable; // MFPC bit set in RSN Capabilities (PMF supported)
117 bool pmf_required; // MFPR bit set in RSN Capabilities (PMF mandatory)
118 uint8_t total_attempts; // Number of failed attack attempts recorded
119 bool captured; // True if BSSID is on the captured or ignore list
120 bool ft_capable; // 802.11r FT AKM advertised (FT-PSK or FT-EAP)
121 uint32_t first_seen_ms; // millis() timestamp when this AP was first observed
122 uint32_t last_seen_ms; // millis() timestamp of the most recent beacon or probe response
123 char country[3]; // ISO 3166-1 alpha-2 country code from IE 7 (e.g. "US"), empty if absent
124 uint16_t beacon_interval; // Advertised beacon interval in TUs (1 TU = 1024 µs), 0 if unknown
125 uint8_t max_rate_mbps; // Highest legacy data rate from Supported Rates IEs (Mbps), 0 if unknown
126 bool is_hidden; // True if AP broadcasts an empty SSID (hidden network)
127 uint16_t sta_count; // Connected client count from BSS Load IE (if present)
128 uint8_t chan_util; // Channel utilization from BSS Load IE (0-255)
129 uint8_t venue_group; // 802.11u Venue Group (e.g., 2=Education, 10=Residential)
130 uint8_t venue_type; // 802.11u Venue Type (e.g., 8=University, 1=Coffee Shop)
131 uint8_t network_type; // 802.11u Access Network Type (1=Free Public, 2=Chargeable, etc.)
132};
133
134// ─── Frame Stats ──────────────────────────────────────────────────────────────
135/** @brief Cumulative frame and capture counters for the engine session. Accessible via getStats(), reset with resetStats(). */
136struct Stats {
137 uint32_t total;
138 uint32_t mgmt;
139 uint32_t ctrl;
140 uint32_t data;
141 uint32_t eapol;
142 uint32_t pmkid_found;
143 uint32_t sae_found;
144 uint32_t beacons;
145 uint32_t captures;
146 uint32_t failed_pmkid; // PMKID retries exhausted without capture
147 uint32_t failed_csa; // CSA/Deauth wait expired without EAPOL
148 volatile uint32_t dropped; // Frames dropped due to ringbuffer overflow
149 uint32_t rb_max; // Max observed ringbuffer usage (bytes)
150 uint16_t channel_frames[14]; // Frames received per 2.4GHz channel (index 0 = ch1, index 13 = ch14)
151};
152
153// ─── Handshake Record ─────────────────────────────────────────────────────────
154/** @brief A captured handshake or PMKID record delivered to the EapolCb callback. The @p type field identifies the capture path; fields not relevant to that path are zeroed. */
156 uint8_t type; // CAP_PMKID / CAP_EAPOL / ...
157 uint8_t channel;
158 int8_t rssi;
159 uint8_t bssid[6];
160 uint8_t sta[6];
161 char ssid[33];
162 uint8_t ssid_len;
163 uint8_t enc; // 0=open, 1=WEP, 2=WPA, 3=WPA2/WPA3, 4=Enterprise
164 // PMKID path
165 uint8_t pmkid[16];
166 // EAPOL path
167 uint8_t anonce[32];
168 uint8_t snonce[32];
169 uint8_t mic[16];
170 union {
171 uint8_t eapol_m2[256];
172 uint8_t sae_data[256];
173 };
174 uint8_t eapol_m3[256];
175 uint8_t eapol_m4[256];
176 union {
177 uint16_t eapol_m2_len;
178 uint16_t sae_len;
179 };
180 uint16_t eapol_m3_len;
181 uint16_t eapol_m4_len;
185 bool has_m3;
186 bool has_m4;
187 bool is_full; // True if this is a complete 4-way sequence or full SAE exchange
188 uint8_t sae_seq; // SAE Auth Sequence (1=Commit, 2=Confirm)
189};
190
191// ─── Disconnection Strategy ───────────────────────────────────────────────────
192enum DisconnectStrategy : uint8_t {
193 STRATEGY_AUTO_FALLBACK = 0, // CSA first, fallback to Deauth halfway through wait window
194 STRATEGY_SIMULTANEOUS = 1, // CSA and Deauth simultaneously (Legacy behavior)
195};
196
197// ─── Attack Result ────────────────────────────────────────────────────────────
198enum AttackResult : uint8_t {
199 RESULT_PMKID_EXHAUSTED = 1, // All PMKID retries failed, no PMKID captured
200 RESULT_CSA_EXPIRED = 2, // CSA/Deauth wait window closed, no EAPOL captured
201};
202
203/** @brief Identifies the AP and failure reason for a failed attack, delivered to the AttackResultCb callback. */
205 uint8_t bssid[6];
206 char ssid[33];
207 uint8_t ssid_len;
209};
210
211typedef void (*AttackResultCb)(const AttackResultRecord &rec);
212typedef void (*ClientFoundCb)(const uint8_t *bssid, const uint8_t *sta, int8_t rssi);
213
214/**
215 * @brief Fired when a second BSSID advertising the same SSID is observed on the same channel.
216 * This indicates a potential evil twin or rogue AP. Both the known AP and the newcomer are included.
217 */
219 uint8_t known_bssid[6]; // BSSID of the first AP already cached with this SSID
220 uint8_t rogue_bssid[6]; // BSSID of the newly observed AP sharing the same SSID
221 char ssid[33]; // The shared SSID
222 uint8_t ssid_len;
223 uint8_t channel; // Channel on which the conflict was detected
224 int8_t rssi; // Signal strength of the rogue AP (dBm)
225};
226
227typedef void (*RogueApCb)(const RogueApRecord &rec); // Fired when an evil twin / rogue AP is detected
228
229// ─── 802.1X Enterprise Identity Record ─────────────────────────────────────────
230/** @brief A harvested 802.1X Enterprise plaintext identity, delivered to the IdentityCb callback. */
232 uint8_t bssid[6]; // Access Point MAC
233 uint8_t client[6]; // Enterprise Client MAC
234 char identity[65]; // The Plaintext Identity / Email Address
235 uint8_t channel;
236 int8_t rssi;
237};
238
239// ─── Probe Request Record ─────────────────────────────────────────────────────
240/** @brief A probe request frame observed on the air, delivered to the ProbeRequestCb callback. */
242 uint8_t client[6]; // Probing device MAC
243 uint8_t channel;
244 int8_t rssi;
245 char ssid[33]; // Requested SSID (empty = wildcard probe)
246 uint8_t ssid_len;
247 bool rand_mac; // True if locally administered bit is set (iOS/Android MAC randomization)
248};
249
250// ─── Disruption Record ────────────────────────────────────────────────────────
251/** @brief A deauthentication or disassociation frame observed on the air, delivered to the DisruptCb callback. */
253 uint8_t src[6]; // Frame source MAC
254 uint8_t dst[6]; // Frame destination MAC
255 uint8_t bssid[6]; // BSSID (addr3)
256 uint16_t reason; // 802.11 reason code
257 uint8_t subtype; // MGMT_SUB_DEAUTH (0xC0) or MGMT_SUB_DISASSOC (0xA0)
258 uint8_t channel;
259 int8_t rssi;
260 bool rand_mac; // True if source MAC has locally administered bit set (randomized)
261};
262
263// ─── Device Fingerprint ───────────────────────────────────────────────────────
264
265// match_flags bits (reported in DeviceRecord)
266#define FP_MATCH_OUI 0x01
267#define FP_MATCH_PROBE_SSID 0x02
268#define FP_MATCH_HT_CAP 0x04
269#define FP_MATCH_RATES 0x08
270#define FP_MATCH_IE_FLAGS 0x10
271
272// ie_flags / ie_flags_mask bits (in DeviceFingerprint)
273#define FP_IEF_NO_HT 0x01 // IE 45 (HT Capabilities) absent
274#define FP_IEF_NO_EXT_CAP 0x02 // IE 127 (Extended Capabilities) absent
275#define FP_IEF_HAS_WMM 0x04 // WMM vendor IE (00:50:F2:01) present
276#define FP_IEF_HAS_WPS 0x08 // WPS vendor IE (00:50:F2:04) present
277
278/** @brief One fingerprint entry in the built-in or user-defined database. */
280 const char* vendor;
281 const char* model;
282 uint8_t oui[3];
283 const char* probeSsid;
284 uint8_t confidence;
285 // IE-based signals — zero values mean "don't check this signal"
286 uint8_t ht_cap_info[2]; // expected HT Capabilities Info bytes 0–1
287 uint8_t ht_cap_mask[2]; // bitmask: which bits of ht_cap_info to compare
288 uint8_t rate_sig[4]; // first 4 bytes of Supported Rates IE
289 uint8_t ie_flags; // expected IE presence flags (FP_IEF_*)
290 uint8_t ie_flags_mask; // which ie_flags bits to check
291};
292
293/** @brief A matched device, delivered to the DeviceFoundCb callback. */
295 uint8_t mac[6];
296 char vendor[32];
297 char model[32];
298 uint8_t channel;
299 int8_t rssi;
300 uint8_t confidence;
301 uint8_t match_flags;
302};
303
304} // namespace politician
#define LOG_FILTER_HANDSHAKES
#define LOG_FILTER_PROBES
void(* EapolCb)(const HandshakeRecord &rec)
uint16_t channel_frames[14]
uint32_t probe_hidden_interval_ms
void(* AttackResultCb)(const AttackResultRecord &rec)
int(* TargetScoreCb)(const ApRecord &ap, const char *vendor)
void(* ProbeRequestCb)(const ProbeRequestRecord &rec)
void(* LogCb)(const char *msg)
uint16_t probe_aggr_interval_s
void(* RogueApCb)(const RogueApRecord &rec)
void(* ApFoundCb)(const ApRecord &ap)
void(* IdentityCb)(const EapIdentityRecord &rec)
void(* ClientFoundCb)(const uint8_t *bssid, const uint8_t *sta, int8_t rssi)
void(* PacketCb)(const uint8_t *payload, uint16_t len, int8_t rssi, uint8_t channel, uint32_t ts_usec)
volatile uint32_t dropped
void(* DisruptCb)(const DisruptRecord &rec)
Snapshot of a discovered Access Point from the internal cache.
Identifies the AP and failure reason for a failed attack, delivered to the AttackResultCb callback.
Configuration for the Politician engine.
One fingerprint entry in the built-in or user-defined database.
A matched device, delivered to the DeviceFoundCb callback.
A deauthentication or disassociation frame observed on the air, delivered to the DisruptCb callback.
A harvested 802.1X Enterprise plaintext identity, delivered to the IdentityCb callback.
A captured handshake or PMKID record delivered to the EapolCb callback.
A probe request frame observed on the air, delivered to the ProbeRequestCb callback.
Fired when a second BSSID advertising the same SSID is observed on the same channel.
Cumulative frame and capture counters for the engine session.