Politician 1.0.0
WiFi Auditing Library for ESP32
Loading...
Searching...
No Matches
Politician.h
Go to the documentation of this file.
1#pragma once
2#include "politician_compat.h"
3#include <esp_wifi.h>
4#include <esp_wifi_types.h>
5#include <freertos/FreeRTOS.h>
6#include <freertos/task.h>
7#include <freertos/ringbuf.h>
8#include <freertos/semphr.h>
9#include "PoliticianTypes.h"
10
11namespace politician {
12
13#ifndef POLITICIAN_MAX_AP_CACHE
14#define POLITICIAN_MAX_AP_CACHE 48
15#endif
16
17#ifndef POLITICIAN_MAX_SESSIONS
18#define POLITICIAN_MAX_SESSIONS 8
19#endif
20
21#ifndef POLITICIAN_MAX_CAPTURED
22#define POLITICIAN_MAX_CAPTURED 128
23#endif
24
25#ifndef POLITICIAN_MAX_CHANNELS
26#define POLITICIAN_MAX_CHANNELS 50
27#endif
28
29// ─── 802.11 Frame Structures ──────────────────────────────────────────────────
30
31typedef struct {
32 uint16_t frame_ctrl;
33 uint16_t duration;
34 uint8_t addr1[6];
35 uint8_t addr2[6];
36 uint8_t addr3[6];
37 uint16_t seq_ctrl;
38} __attribute__((packed)) ieee80211_hdr_t;
39
40typedef struct {
41 ieee80211_hdr_t hdr;
42 uint8_t payload[0];
43} __attribute__((packed)) ieee80211_frame_t;
44
45// ─── Frame Control Masks ──────────────────────────────────────────────────────
46#define FC_TYPE_MASK 0x000C
47#define FC_SUBTYPE_MASK 0x00F0
48#define FC_TODS_MASK 0x0100
49#define FC_FROMDS_MASK 0x0200
50#define FC_TYPE_MGMT 0x0000
51#define FC_TYPE_CTRL 0x0004
52#define FC_TYPE_DATA 0x0008
53#define FC_ORDER_MASK 0x8000
54
55#define MGMT_SUB_ASSOC_REQ 0x00
56#define MGMT_SUB_ASSOC_RESP 0x10
57#define MGMT_SUB_PROBE_REQ 0x40
58#define MGMT_SUB_PROBE_RESP 0x50
59#define MGMT_SUB_BEACON 0x80
60#define MGMT_SUB_AUTH 0xB0
61#define MGMT_SUB_DISASSOC 0xA0
62#define MGMT_SUB_DEAUTH 0xC0
63
64// ─── EAPOL ────────────────────────────────────────────────────────────────────
65#define EAPOL_LLC_OFFSET 0
66#define EAPOL_ETHERTYPE_HI 0x88
67#define EAPOL_ETHERTYPE_LO 0x8E
68#define EAPOL_LLC_SIZE 8
69#define EAPOL_MIN_FRAME_LEN (EAPOL_LLC_SIZE + 4)
70
71#define EAPOL_KEY_DESC_TYPE 0
72#define EAPOL_KEY_INFO 1
73#define EAPOL_REPLAY_COUNTER 5
74#define EAPOL_KEY_NONCE 13
75#define EAPOL_KEY_MIC 77
76#define EAPOL_KEY_DATA_LEN 93
77#define EAPOL_KEY_DATA 95
78
79#define KEYINFO_TYPE_MASK 0x0007
80#define KEYINFO_PAIRWISE 0x0008
81#define KEYINFO_ACK 0x0080
82#define KEYINFO_MIC 0x0100
83#define KEYINFO_SECURE 0x0200
84#define KEYINFO_INSTALL 0x0040
85
86// ─── Politician (The Handshaker) ──────────────────────────────────────────────
87
88/**
89 * @brief The core WiFi handshake capturing engine.
90 */
92public:
93 Politician();
94
95 /**
96 * @brief Initializes the WiFi driver in promiscuous mode.
97 * @param cfg Optional configuration struct.
98 * @return OK on success, or an error code.
99 */
100 Error begin(const Config &cfg = Config());
101
102 /**
103 * @brief Sets a custom logging callback to intercept library output.
104 */
105 void setLogger(LogCb cb) { _logCb = cb; }
106
107 /**
108 * @brief Manually adds a BSSID to the "already captured" list to skip it.
109 */
110 void markCaptured(const uint8_t *bssid);
111
112 /**
113 * @brief Clears the captured BSSID list.
114 */
115 void clearCapturedList();
116
117 /**
118 * @brief Sets a list of BSSIDs that should always be ignored by the engine.
119 */
120 void setIgnoreList(const uint8_t (*bssids)[6], uint8_t count);
121
122 /**
123 * @brief Enables or disables frame processing.
124 */
125 void setActive(bool active);
126
127 /**
128 * @brief Manually sets the WiFi radio to a specific channel.
129 * @param ch Channel number (2.4GHz: 1-14, 5GHz: 36-165)
130 * @return OK on success, ERR_INVALID_CH if ch is invalid.
131 */
132 Error setChannel(uint8_t ch);
133
134 /**
135 * @brief Starts autonomous channel hopping.
136 * @param dwellMs Time in milliseconds to stay on each channel (0 = use config).
137 */
138 void startHopping(uint16_t dwellMs = 0);
139
140 /**
141 * @brief Stops autonomous channel hopping and goes idle.
142 */
143 void stopHopping();
144
145 /**
146 * @brief Full engine teardown. Aborts any in-progress attack, clears the
147 * target, stops hopping, and disables frame processing in one call.
148 * Use this instead of combining stopHopping() + clearTarget() + setActive(false).
149 */
150 void stop();
151
152 /**
153 * @brief Stops hopping and locks the radio to a specific channel.
154 * @return OK on success, or an error code.
155 */
156 Error lockChannel(uint8_t ch);
157
158 /**
159 * @brief Restricts hopping to a specific list of channels.
160 * @param channels Array of channel numbers (2.4GHz: 1-14, 5GHz: 36-165)
161 * @param count Number of channels in array
162 */
163 void setChannelList(const uint8_t *channels, uint8_t count);
164
165 /**
166 * @brief Restricts hopping to 2.4GHz, 5GHz, or both bands.
167 * @param ghz24 Include 2.4GHz channels (1-13)
168 * @param ghz5 Include 5GHz common channels (36-165)
169 */
170 void setChannelBands(bool ghz24, bool ghz5);
171
172 /**
173 * @brief Searches the AP cache by SSID and locks onto the strongest match.
174 * Equivalent to calling setTarget() on the best matching AP.
175 * @param ssid Null-terminated SSID string to search for.
176 * @return OK on success, ERR_NOT_FOUND if SSID is not in cache,
177 * ERR_ALREADY_CAPTURED if BSSID is already captured, ERR_NOT_ACTIVE if not initialized.
178 */
179 Error setTargetBySsid(const char *ssid);
180
181 /**
182 * @brief Main worker method. Must be called frequently from loop().
183 */
184 void tick();
185
186 /**
187 * @brief Configures which attack techniques are enabled globally.
188 */
189 void setAttackMask(uint8_t mask);
190
191 /**
192 * @brief Overrides the attack mask for a specific BSSID.
193 * When the engine targets this BSSID the override mask is used instead of the global mask.
194 * The override table holds up to 8 entries; oldest is evicted if full.
195 */
196 void setAttackMaskForBssid(const uint8_t *bssid, uint8_t mask);
197
198 /**
199 * @brief Clears all per-BSSID attack mask overrides.
200 */
202
203 /**
204 * @brief Configures how the engine handles disconnection when both CSA and Deauth are enabled.
205 * @param strategy STRATEGY_AUTO_FALLBACK (default) or STRATEGY_SIMULTANEOUS.
206 */
207 void setDisconnectionStrategy(DisconnectStrategy strategy) { _disconnectStrategy = strategy; }
208
209 /**
210 * @brief Focuses the engine on a single BSSID.
211 * @return OK on success, ERR_ALREADY_CAPTURED if BSSID is on the captured/ignore list.
212 */
213 Error setTarget(const uint8_t *bssid, uint8_t channel);
214
215 /**
216 * @brief Clears the specific target and resumes autonomous wardriving.
217 */
218 void clearTarget();
219
220 /** @return True if currently focusing on a specific target BSSID. */
221 bool hasTarget() const { return _hasTarget; }
222
223 /** @return True if an active attack (PMKID fishing or CSA/Deauth) is in progress. */
224 bool isAttacking() const { return _fishState != FISH_IDLE; }
225
226 /**
227 * @brief Continuously locks onto the strongest uncaptured AP in the cache.
228 * After each attack attempt (success or failure), automatically moves to the next best target.
229 * @param enable True to enable, false to disable and resume normal hopping.
230 */
231 void setAutoTarget(bool enable);
232
233 /** @brief Resets all frame and capture statistics to zero. */
234 void resetStats() { memset(&_stats, 0, sizeof(_stats)); }
235
236 /** @return The current operating channel. */
237 uint8_t getChannel() const { return _channel; }
238
239 /** @return True if the engine is currently processing frames. */
240 bool isActive() const { return _active; }
241
242 /** @return Signal strength (RSSI) of the last received frame. */
243 int8_t getLastRssi() const { return _lastRssi; }
244
245 /** @return Reference to the internal statistics counter. */
246 Stats& getStats() { return _stats; }
247
248 /** @return Reference to the internal configuration struct for runtime mutations. */
249 Config& getConfig() { return _cfg; }
250
251 /** @return Number of unique APs currently in the discovery cache. */
252 int getApCount() const;
253
254 /**
255 * @brief Reads an AP from the discovery cache by index.
256 * @param idx Zero-based index (0 to getApCount()-1).
257 * @param out Populated with the AP's details on success.
258 * @return True if idx is valid, false otherwise.
259 */
260 bool getAp(int idx, ApRecord &out) const;
261
262 /**
263 * @brief Looks up an AP in the discovery cache by BSSID.
264 * @param bssid 6-byte BSSID to search for.
265 * @param out Populated with the AP's details on success.
266 * @return True if found, false if the BSSID is not in cache.
267 */
268 bool getApByBssid(const uint8_t *bssid, ApRecord &out) const;
269
270 /**
271 * @brief Returns the number of unique clients seen associated to a given AP.
272 * @param bssid 6-byte BSSID of the AP.
273 * @return Client count (0-4), or 0 if BSSID is not in cache.
274 */
275 int getClientCount(const uint8_t *bssid) const;
276
277 /**
278 * @brief Reads a client MAC from the per-AP client table.
279 * @param bssid 6-byte BSSID of the AP.
280 * @param idx Zero-based client index (0 to getClientCount()-1).
281 * @param out_sta Output buffer for the 6-byte client MAC.
282 * @return True if idx is valid, false otherwise.
283 */
284 bool getClient(const uint8_t *bssid, int idx, uint8_t out_sta[6]) const;
285
286 using _FpHookCb = void (*)(const uint8_t *mac, const char *ssid, uint8_t ssid_len, uint8_t ch, int8_t rssi, const uint8_t *ie, uint16_t ie_len);
287 void _setFingerprintHook(_FpHookCb cb) { _fpHook = cb; }
288
289 using EapolCb = void (*)(const HandshakeRecord &rec);
290 using ApFoundCb = void (*)(const ApRecord &ap);
291 using TargetFilterCb = bool (*)(const ApRecord &ap);
292 using TargetScoreCb = int (*)(const ApRecord &ap, const char *vendor);
293 using PacketCb = void (*)(const uint8_t *payload, uint16_t len, int8_t rssi, uint8_t channel, uint32_t ts_usec);
294 using IdentityCb = void (*)(const EapIdentityRecord &rec);
295 using AttackResultCb = void (*)(const AttackResultRecord &rec);
296 using ProbeRequestCb = void (*)(const ProbeRequestRecord &rec);
297 using DisruptCb = void (*)(const DisruptRecord &rec);
298 using ClientFoundCb = void (*)(const uint8_t *bssid, const uint8_t *sta, int8_t rssi);
299
300 /**
301 * @brief Looks up the vendor name for a given MAC address (OUI).
302 * @param mac 6-byte MAC address.
303 * @return The vendor string (e.g., "Apple") or an empty string if unknown.
304 */
305 static const char* getVendor(const uint8_t *mac);
306
307 /**
308 * @brief Sets the callback for calculating a custom priority score during autoTarget.
309 */
310 void setTargetScoreCallback(TargetScoreCb cb) { _targetScoreCb = cb; }
311
312 /**
313 * @brief Injects a custom 802.11 frame.
314 * @param payload The raw 802.11 frame bytes.
315 * @param len Length of the frame.
316 * @param channel The 2.4GHz or 5GHz channel to transmit on.
317 * @param lock_ms Optional. If > 0, the engine disables hopping and stays on the channel for this duration.
318 * @param wait_for_channel If true, the frame is queued until the hopper naturally reaches the channel (stealth). If false, the engine immediately switches to the channel and fires.
319 * @return OK on success, or an error code if the queue is full or engine is not initialized.
320 */
321 Error injectCustomFrame(const uint8_t *payload, size_t len, uint8_t channel, uint32_t lock_ms = 0, bool wait_for_channel = false);
322
323 /**
324 * @brief Sets the callback for when a handshake (EAPOL or PMKID) is captured.
325 */
326 void setEapolCallback(EapolCb cb) { _eapolCb = cb; }
327
328 /**
329 * @brief Sets the callback for when a new Access Point is discovered.
330 */
331 void setApFoundCallback(ApFoundCb cb) { _apFoundCb = cb; }
332
333 /**
334 * @brief Sets an early filter callback. If it returns false, the AP is ignored completely.
335 */
336 void setTargetFilter(TargetFilterCb cb) { _filterCb = cb; }
337
338 /**
339 * @brief Sets the callback for raw promiscuous mode packets.
340 */
341 void setPacketLogger(PacketCb cb) { _packetCb = cb; }
342
343 /**
344 * @brief Sets the callback for passive 802.1X Enterprise Identity harvesting.
345 */
346 void setIdentityCallback(IdentityCb cb) { _identityCb = cb; }
347
348 /**
349 * @brief Sets the callback fired when an attack attempt exhausts all options without capturing.
350 * Useful for logging failed targets or adjusting strategy at runtime.
351 */
352 void setAttackResultCallback(AttackResultCb cb) { _attackResultCb = cb; }
353
354 /**
355 * @brief Sets the callback fired on every probe request frame.
356 * Exposes the probing client MAC and requested SSID for device history reconstruction.
357 */
358 void setProbeRequestCallback(ProbeRequestCb cb) { _probeReqCb = cb; }
359
360 /**
361 * @brief Sets the callback fired on deauthentication and disassociation frames.
362 * Exposes source, destination, BSSID, reason code, and direction for attack/roaming detection.
363 */
364 void setDisruptCallback(DisruptCb cb) { _disruptCb = cb; }
365
366 /**
367 * @brief Sets the callback fired when a new client (STA) is first seen associated to an AP.
368 * Fired at most once per unique BSSID+STA pair (tracked per AP cache entry, up to 4 clients).
369 */
370 void setClientFoundCallback(ClientFoundCb cb) { _clientFoundCb = cb; }
371
372 /**
373 * @brief Sets the callback fired when a potential evil twin or rogue AP is detected.
374 * Triggered when a newly observed BSSID advertises the same SSID as an already-cached AP on the same channel.
375 */
376 void setRogueApCallback(RogueApCb cb) { _rogueApCb = cb; }
377
378private:
379 static void IRAM_ATTR _promiscuousCb(void *buf, wifi_promiscuous_pkt_type_t type);
380 static void _workerTask(void *pvParameters);
381 static Politician *_instance;
382
383 RingbufHandle_t _rb = nullptr;
384 TaskHandle_t _task = nullptr;
385 SemaphoreHandle_t _lock = nullptr;
386
387 void _handleFrame(const wifi_promiscuous_pkt_t *pkt, wifi_promiscuous_pkt_type_t type);
388 void _handleMgmt(const ieee80211_hdr_t *hdr, const uint8_t *payload, uint16_t len, int8_t rssi);
389 void _handleData(const ieee80211_hdr_t *hdr, const uint8_t *payload, uint16_t len, int8_t rssi);
390 bool _parseEapol(const uint8_t *bssid, const uint8_t *sta,
391 const uint8_t *eapol, uint16_t len, int8_t rssi);
392 void _parseEapIdentity(const uint8_t *bssid, const uint8_t *sta,
393 const uint8_t *eapol, uint16_t len, int8_t rssi);
394 void _parseSsid(const uint8_t *ie, uint16_t ie_len, char *out, uint8_t &out_len);
395 uint8_t _classifyEnc(const uint8_t *ie, uint16_t ie_len);
396 bool _detectWpa3Only(const uint8_t *ie, uint16_t ie_len);
397 void _detectPmfFlags(const uint8_t *ie, uint16_t ie_len, bool &pmf_capable, bool &pmf_required);
398 bool _detectFt(const uint8_t *ie, uint16_t ie_len);
399
400 bool _initialized = false;
401 volatile bool _active;
402 uint8_t _channel;
403 uint8_t _rxChannel;
404 bool _hopping;
405 volatile bool _channelTrafficSeen;
406 uint32_t _lastHopMs;
407 int8_t _lastRssi;
408 uint8_t _hopIndex;
409 uint8_t _attackMask;
410 DisconnectStrategy _disconnectStrategy;
411 uint32_t _csaFallbackMs;
412
413 static const int MAX_INJECT_QUEUE = 4;
414 struct InjectFrame {
415 bool active;
416 uint8_t payload[256];
417 uint16_t len;
418 uint8_t channel;
419 uint32_t lock_ms;
420 };
421 InjectFrame _injectQueue[MAX_INJECT_QUEUE];
422
423 static const int MAX_ATTACK_OVERRIDES = 8;
424 struct AttackOverride { bool active; uint8_t bssid[6]; uint8_t mask; };
425 AttackOverride _attackOverrides[MAX_ATTACK_OVERRIDES];
426 uint8_t _getAttackMask(const uint8_t *bssid) const;
427
428 bool _hasTarget;
429 uint8_t _targetBssid[6];
430 uint8_t _targetChannel;
431
432 bool _m1Locked;
433 uint32_t _m1LockEndMs;
434
435 bool _probeLocked;
436 uint32_t _probeLockEndMs;
437
438 uint8_t _customChannels[POLITICIAN_MAX_CHANNELS];
439 uint8_t _customChannelCount;
440 Config _cfg;
441 Stats _stats;
442
443 bool _autoTarget = false;
444 bool _autoTargetActive = false;
445
446 uint8_t _lastCapBssid[6] = {};
447 uint8_t _lastCapSta[6] = {};
448 uint32_t _lastCapMs = 0;
449
450 TargetScoreCb _targetScoreCb = nullptr;
451 LogCb _logCb = nullptr;
452 ApFoundCb _apFoundCb = nullptr;
453 TargetFilterCb _filterCb = nullptr;
454 EapolCb _eapolCb = nullptr;
455 PacketCb _packetCb = nullptr;
456 IdentityCb _identityCb = nullptr;
457 AttackResultCb _attackResultCb = nullptr;
458 ProbeRequestCb _probeReqCb = nullptr;
459 DisruptCb _disruptCb = nullptr;
460 ClientFoundCb _clientFoundCb = nullptr;
461 RogueApCb _rogueApCb = nullptr;
462 _FpHookCb _fpHook = nullptr;
463
464 void _log(const char *fmt, ...);
465
466 static const int MAX_IGNORE = 128;
467 uint8_t _ignoreList[MAX_IGNORE][6];
468 uint8_t _ignoreCount;
469
470 static const int MAX_AP_CACHE = POLITICIAN_MAX_AP_CACHE;
471 struct ApCacheEntry {
472 uint8_t bssid[6];
473 char ssid[33];
474 uint8_t ssid_len;
475 uint8_t enc;
476 uint8_t channel;
477 int8_t rssi;
478 uint32_t first_seen_ms;
479 uint32_t last_seen_ms;
480 uint32_t last_probe_ms;
481 uint32_t last_stimulate_ms;
482 uint32_t last_hidden_probe_ms; // Timestamp of last directed probe for hidden SSID
483 uint8_t known_stas[4][6]; // Up to 4 persistently tracked client MACs
484 uint8_t known_sta_count;
485 uint16_t beacon_count; // Times this AP has been observed
486 uint8_t total_attempts; // Total failed attack attempts against this AP
487 char country[3]; // IE 7 country code (e.g. "US"), empty if absent
488 uint16_t beacon_interval; // Beacon interval in TUs from fixed fields
489 uint8_t max_rate_mbps; // Highest rate from Supported Rates IE (Mbps)
490 uint16_t sta_count; // Connected client count from BSS Load
491 uint8_t chan_util; // Channel utilization (0-255)
492 uint8_t venue_group; // 802.11u Venue Group
493 uint8_t venue_type; // 802.11u Venue Type
494 uint8_t network_type; // 802.11u Access Network Type
495 struct {
496 uint8_t active : 1;
497 uint8_t has_active_clients : 1;
498 uint8_t is_wpa3_only : 1;
499 uint8_t is_hidden : 1;
500 uint8_t wps_enabled : 1;
501 uint8_t pmf_capable : 1;
502 uint8_t pmf_required : 1;
503 uint8_t ft_capable : 1;
504 } flags;
505 };
506 ApCacheEntry _apCache[MAX_AP_CACHE];
507
508 ApCacheEntry* _cacheAp(const uint8_t *bssid, const char *ssid, uint8_t ssid_len,
509 uint8_t enc, uint8_t channel, int8_t rssi,
510 bool is_wpa3_only = false, bool wps = false,
511 bool pmf_capable = false, bool pmf_required = false,
512 bool ft_capable = false, uint16_t sta_count = 0, uint8_t chan_util = 0,
513 uint8_t venue_group = 0, uint8_t venue_type = 0, uint8_t network_type = 0);
514 bool _lookupSsid(const uint8_t *bssid, char *out_ssid, uint8_t &out_len);
515 bool _lookupEnc(const uint8_t *bssid, uint8_t &out_enc);
516
517 enum FishState : uint8_t { FISH_IDLE = 0, FISH_CONNECTING = 1, FISH_CSA_WAIT = 2 };
518 FishState _fishState;
519 uint32_t _fishStartMs;
520 uint8_t _fishBssid[6];
521 uint8_t _fishRetry;
522 char _fishSsid[33];
523 uint8_t _fishSsidLen;
524 uint8_t _fishChannel;
525 uint8_t _fishSta[6]; // Known client MAC for unicast deauth (zeros = unknown)
526 uint8_t _ownStaMac[6];
527 bool _fishAuthLogged;
528 bool _fishAssocLogged;
529 bool _csaSecondBurstSent;
530
531 void _startFishing(const uint8_t *bssid, const char *ssid,
532 uint8_t ssid_len, uint8_t channel);
533 void _processFishing();
534 void _randomizeMac();
535 void _sendCsaBurst();
536 void _sendDeauthBurst(uint8_t count, const uint8_t *sta = nullptr);
537 void _sendProbeRequest(const uint8_t *bssid);
538 void _recordClientForAp(const uint8_t *bssid, const uint8_t *sta, int8_t rssi = 0);
539 void _markCapturedSsidGroup(const char *ssid, uint8_t ssid_len);
540 void _markCaptured(const uint8_t *bssid);
541
542 static const int MAX_SESSIONS = POLITICIAN_MAX_SESSIONS;
543 struct Session {
544 uint8_t bssid[6];
545 uint8_t sta[6];
546 char ssid[33];
547 uint8_t ssid_len;
548 uint8_t channel;
549 int8_t rssi;
550 uint8_t anonce[32];
551 uint8_t snonce[32];
552 uint8_t m1_replay_counter[8];
553 uint8_t mic[16];
554 uint32_t created_ms;
555
556 // Dynamic EAPOL Buffer (M2, M3, M4 packed)
557 uint8_t eapol_buffer[400];
558 uint16_t m2_off, m2_len;
559 uint16_t m3_off, m3_len;
560 uint16_t m4_off, m4_len;
561
562 struct {
563 uint8_t active : 1;
564 uint8_t has_m1 : 1;
565 uint8_t has_m2 : 1;
566 uint8_t has_m3 : 1;
567 uint8_t has_m4 : 1;
568 } flags;
569 };
570 Session _sessions[MAX_SESSIONS];
571
572 Session* _findSession(const uint8_t *bssid, const uint8_t *sta);
573 Session* _createSession(const uint8_t *bssid, const uint8_t *sta);
574 void _expireSessions(uint32_t timeoutMs);
575
576 static const int MAX_CAPTURED = POLITICIAN_MAX_CAPTURED;
577 uint8_t _captured[MAX_CAPTURED][6];
578 int _capturedCount;
579
580 bool _isCaptured(const uint8_t *bssid) const;
581
582 static const uint8_t HOP_SEQ[];
583 static const uint8_t HOP_COUNT;
584};
585
586} // namespace politician
#define POLITICIAN_MAX_CHANNELS
Definition Politician.h:26
#define POLITICIAN_MAX_AP_CACHE
Definition Politician.h:14
#define POLITICIAN_MAX_SESSIONS
Definition Politician.h:18
#define POLITICIAN_MAX_CAPTURED
Definition Politician.h:22
The core WiFi handshake capturing engine.
Definition Politician.h:91
void stop()
Full engine teardown.
Error lockChannel(uint8_t ch)
Stops hopping and locks the radio to a specific channel.
void clearCapturedList()
Clears the captured BSSID list.
void markCaptured(const uint8_t *bssid)
Manually adds a BSSID to the "already captured" list to skip it.
static const char * getVendor(const uint8_t *mac)
Looks up the vendor name for a given MAC address (OUI).
void setDisruptCallback(DisruptCb cb)
Sets the callback fired on deauthentication and disassociation frames.
Definition Politician.h:364
Error injectCustomFrame(const uint8_t *payload, size_t len, uint8_t channel, uint32_t lock_ms=0, bool wait_for_channel=false)
Injects a custom 802.11 frame.
void(*)(const uint8_t *bssid, const uint8_t *sta, int8_t rssi) ClientFoundCb
Definition Politician.h:298
bool getClient(const uint8_t *bssid, int idx, uint8_t out_sta[6]) const
Reads a client MAC from the per-AP client table.
void clearAttackMaskOverrides()
Clears all per-BSSID attack mask overrides.
void setAutoTarget(bool enable)
Continuously locks onto the strongest uncaptured AP in the cache.
int getClientCount(const uint8_t *bssid) const
Returns the number of unique clients seen associated to a given AP.
void resetStats()
Resets all frame and capture statistics to zero.
Definition Politician.h:234
void tick()
Main worker method.
int8_t getLastRssi() const
Definition Politician.h:243
void setProbeRequestCallback(ProbeRequestCb cb)
Sets the callback fired on every probe request frame.
Definition Politician.h:358
void setPacketLogger(PacketCb cb)
Sets the callback for raw promiscuous mode packets.
Definition Politician.h:341
Error setTargetBySsid(const char *ssid)
Searches the AP cache by SSID and locks onto the strongest match.
void setLogger(LogCb cb)
Sets a custom logging callback to intercept library output.
Definition Politician.h:105
void(*)(const uint8_t *mac, const char *ssid, uint8_t ssid_len, uint8_t ch, int8_t rssi, const uint8_t *ie, uint16_t ie_len) _FpHookCb
Definition Politician.h:286
void(*)(const HandshakeRecord &rec) EapolCb
Definition Politician.h:289
void(*)(const ApRecord &ap) ApFoundCb
Definition Politician.h:290
void setActive(bool active)
Enables or disables frame processing.
void setChannelBands(bool ghz24, bool ghz5)
Restricts hopping to 2.4GHz, 5GHz, or both bands.
void setRogueApCallback(RogueApCb cb)
Sets the callback fired when a potential evil twin or rogue AP is detected.
Definition Politician.h:376
void setApFoundCallback(ApFoundCb cb)
Sets the callback for when a new Access Point is discovered.
Definition Politician.h:331
bool isAttacking() const
Definition Politician.h:224
void(*)(const AttackResultRecord &rec) AttackResultCb
Definition Politician.h:295
void(*)(const ProbeRequestRecord &rec) ProbeRequestCb
Definition Politician.h:296
uint8_t getChannel() const
Definition Politician.h:237
void setDisconnectionStrategy(DisconnectStrategy strategy)
Configures how the engine handles disconnection when both CSA and Deauth are enabled.
Definition Politician.h:207
void _setFingerprintHook(_FpHookCb cb)
Definition Politician.h:287
void(*)(const EapIdentityRecord &rec) IdentityCb
Definition Politician.h:294
void stopHopping()
Stops autonomous channel hopping and goes idle.
void setClientFoundCallback(ClientFoundCb cb)
Sets the callback fired when a new client (STA) is first seen associated to an AP.
Definition Politician.h:370
bool(*)(const ApRecord &ap) TargetFilterCb
Definition Politician.h:291
void setAttackMaskForBssid(const uint8_t *bssid, uint8_t mask)
Overrides the attack mask for a specific BSSID.
void(*)(const uint8_t *payload, uint16_t len, int8_t rssi, uint8_t channel, uint32_t ts_usec) PacketCb
Definition Politician.h:293
void setTargetFilter(TargetFilterCb cb)
Sets an early filter callback.
Definition Politician.h:336
void setTargetScoreCallback(TargetScoreCb cb)
Sets the callback for calculating a custom priority score during autoTarget.
Definition Politician.h:310
void setIgnoreList(const uint8_t(*bssids)[6], uint8_t count)
Sets a list of BSSIDs that should always be ignored by the engine.
void setEapolCallback(EapolCb cb)
Sets the callback for when a handshake (EAPOL or PMKID) is captured.
Definition Politician.h:326
Error setTarget(const uint8_t *bssid, uint8_t channel)
Focuses the engine on a single BSSID.
bool hasTarget() const
Definition Politician.h:221
void setIdentityCallback(IdentityCb cb)
Sets the callback for passive 802.1X Enterprise Identity harvesting.
Definition Politician.h:346
Error setChannel(uint8_t ch)
Manually sets the WiFi radio to a specific channel.
void(*)(const DisruptRecord &rec) DisruptCb
Definition Politician.h:297
bool getApByBssid(const uint8_t *bssid, ApRecord &out) const
Looks up an AP in the discovery cache by BSSID.
void clearTarget()
Clears the specific target and resumes autonomous wardriving.
bool getAp(int idx, ApRecord &out) const
Reads an AP from the discovery cache by index.
Error begin(const Config &cfg=Config())
Initializes the WiFi driver in promiscuous mode.
bool isActive() const
Definition Politician.h:240
void startHopping(uint16_t dwellMs=0)
Starts autonomous channel hopping.
void setAttackResultCallback(AttackResultCb cb)
Sets the callback fired when an attack attempt exhausts all options without capturing.
Definition Politician.h:352
void setAttackMask(uint8_t mask)
Configures which attack techniques are enabled globally.
void setChannelList(const uint8_t *channels, uint8_t count)
Restricts hopping to a specific list of channels.
int(*)(const ApRecord &ap, const char *vendor) TargetScoreCb
Definition Politician.h:292
void(* LogCb)(const char *msg)
void(* RogueApCb)(const RogueApRecord &rec)
ieee80211_hdr_t hdr
Definition Politician.h:41
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.
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.
Cumulative frame and capture counters for the engine session.