/** * @file enhanced_web_server.c * @brief ESP32-C5 Toolkit - Full Featured Web Interface * * Features from all projects combined: * - Dual-band WiFi Scanner (2.4GHz + 5GHz) * - Dual-band Deauth Engine (simultaneous attack) * - Channel Usage Visualization (Chart.js) * - Signal Analysis & RSSI Graphs * - Packet Sniffer * - Reconnaissance Dashboard */ #include "esp_http_server.h" #include "esp_log.h" #include "esp_wifi.h" #include "esp_system.h" #include "esp_timer.h" #include "cJSON.h" #include "deauth_engine.h" #include #include #define TAG "EnhancedWeb" // Store last scan results static wifi_ap_record_t *last_scan_results = NULL; static uint16_t last_scan_count = 0; // Store channel stats static int channel_24ghz[14] = {0}; // Channels 1-13 (+1 for index) static int channel_5ghz[200] = {0}; // 5GHz channels indexed by number static int rssi_history[50] = {0}; // Last 50 RSSI readings static int rssi_index = 0; // ============================================================================ // EMBEDDED HTML - Full Featured Dashboard // ============================================================================ static const char* get_enhanced_html(void) { static const char html[] = "" "" "" "" "" "ESP32-C5 TOOLKIT" "" "" "" "" "
" "" "
" "" "
" "

📊 System Dashboard

" "
" "
--
Free Heap
" "
--
Networks Found
" "
IDLE
Deauth Status
" "
" "

📈 Signal Strength History

" "

🌐 Quick Actions

" "" "" "" "
" "
" "" "
" "

🔍 Dual-Band WiFi Scanner

" "
" "" "" "
" "
" "

📶 2.4 GHz Networks

" "

📡 5 GHz Networks

" "
" "

📋 All Networks

" "
" "" "
" "

⚡ Dual-Band Deauth Engine

" "
⚠ WARNING: Use ONLY on networks YOU OWN! Unauthorized use is ILLEGAL!
" "
💡 This attacks BOTH 2.4GHz and 5GHz targets SIMULTANEOUSLY by rapid channel switching.
" "⚠ WiFi AP will be OFFLINE during attack and auto-restore after.
" "

🎯 Selected Targets

Scan networks first, then select targets

" "

⚙ Attack Configuration

" "

Duration: seconds

" "

10-300 seconds recommended. AP auto-restores after attack.

" "
" "
" "" "" "
" "

📊 Attack Statistics

No attack running

" "
" "" "
" "

📶 Channel Utilization Map

" "

📶 2.4 GHz Channels (1-13)

" "

📡 5 GHz Channels

" "

📊 Channel Details

" "
" "" "
" "

🕵 Network Reconnaissance

" "

📋 Network Intelligence

Scan networks to gather intelligence

" "

🔒 Security Analysis

" "

📶 Vendor Detection

" "
" "" "
" "

⚙ System Settings

" "

💻 System Info

Loading...
" "

🔄 Device Control

" "
" "
" "" ""; return html; } // ============================================================================ // HANDLERS // ============================================================================ static esp_err_t root_handler(httpd_req_t *req) { ESP_LOGI(TAG, "Serving enhanced dashboard"); const char* html = get_enhanced_html(); httpd_resp_set_type(req, "text/html"); httpd_resp_send(req, html, strlen(html)); return ESP_OK; } static esp_err_t scan_handler(httpd_req_t *req) { ESP_LOGI(TAG, "WiFi scan requested"); // Reset channel stats memset(channel_24ghz, 0, sizeof(channel_24ghz)); memset(channel_5ghz, 0, sizeof(channel_5ghz)); // Start scan wifi_scan_config_t scan_config = { .ssid = NULL, .bssid = NULL, .channel = 0, .show_hidden = true, .scan_type = WIFI_SCAN_TYPE_ACTIVE, .scan_time.active.min = 100, .scan_time.active.max = 300 }; esp_err_t err = esp_wifi_scan_start(&scan_config, true); if (err != ESP_OK) { httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"status\":\"error\",\"networks\":[]}"); return ESP_OK; } uint16_t ap_count = 0; esp_wifi_scan_get_ap_num(&ap_count); if (last_scan_results) free(last_scan_results); last_scan_results = malloc(sizeof(wifi_ap_record_t) * ap_count); last_scan_count = ap_count; esp_wifi_scan_get_ap_records(&ap_count, last_scan_results); // Build JSON cJSON *root = cJSON_CreateObject(); cJSON *networks = cJSON_CreateArray(); for (int i = 0; i < ap_count; i++) { cJSON *ap = cJSON_CreateObject(); cJSON_AddStringToObject(ap, "ssid", (char*)last_scan_results[i].ssid); cJSON_AddNumberToObject(ap, "rssi", last_scan_results[i].rssi); cJSON_AddNumberToObject(ap, "channel", last_scan_results[i].primary); // BSSID char bssid[18]; snprintf(bssid, sizeof(bssid), "%02x:%02x:%02x:%02x:%02x:%02x", last_scan_results[i].bssid[0], last_scan_results[i].bssid[1], last_scan_results[i].bssid[2], last_scan_results[i].bssid[3], last_scan_results[i].bssid[4], last_scan_results[i].bssid[5]); cJSON_AddStringToObject(ap, "bssid", bssid); // Band cJSON_AddStringToObject(ap, "band", last_scan_results[i].primary > 14 ? "5GHz" : "2.4GHz"); // Security const char* security; switch (last_scan_results[i].authmode) { case WIFI_AUTH_OPEN: security = "Open"; break; case WIFI_AUTH_WEP: security = "WEP"; break; case WIFI_AUTH_WPA_PSK: security = "WPA"; break; case WIFI_AUTH_WPA2_PSK: security = "WPA2"; break; case WIFI_AUTH_WPA_WPA2_PSK: security = "WPA/WPA2"; break; case WIFI_AUTH_WPA3_PSK: security = "WPA3"; break; case WIFI_AUTH_WPA2_WPA3_PSK: security = "WPA2/WPA3"; break; default: security = "Unknown"; } cJSON_AddStringToObject(ap, "security", security); // Update channel stats if (last_scan_results[i].primary <= 13) { channel_24ghz[last_scan_results[i].primary]++; } // Store RSSI for history rssi_history[rssi_index] = last_scan_results[i].rssi; rssi_index = (rssi_index + 1) % 50; cJSON_AddItemToArray(networks, ap); } cJSON_AddItemToObject(root, "networks", networks); cJSON_AddNumberToObject(root, "count", ap_count); char *json = cJSON_PrintUnformatted(root); httpd_resp_set_type(req, "application/json"); httpd_resp_send(req, json, strlen(json)); free(json); cJSON_Delete(root); ESP_LOGI(TAG, "Found %d networks", ap_count); return ESP_OK; } static esp_err_t deauth_start_handler(httpd_req_t *req) { ESP_LOGI(TAG, "Deauth start requested"); char buf[512]; int ret = httpd_req_recv(req, buf, sizeof(buf) - 1); if (ret <= 0) { httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"status\":\"error\",\"message\":\"No data\"}"); return ESP_OK; } buf[ret] = '\0'; cJSON *root = cJSON_Parse(buf); if (!root) { httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"status\":\"error\",\"message\":\"Invalid JSON\"}"); return ESP_OK; } deauth_target_t target_24 = {0}; deauth_target_t target_5 = {0}; // Parse 2.4GHz target cJSON *t24 = cJSON_GetObjectItem(root, "target_24ghz"); if (t24) { cJSON *ssid = cJSON_GetObjectItem(t24, "ssid"); cJSON *bssid = cJSON_GetObjectItem(t24, "bssid"); cJSON *channel = cJSON_GetObjectItem(t24, "channel"); if (cJSON_IsString(ssid) && cJSON_IsString(bssid) && cJSON_IsNumber(channel)) { strncpy(target_24.ssid, ssid->valuestring, sizeof(target_24.ssid) - 1); sscanf(bssid->valuestring, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &target_24.bssid[0], &target_24.bssid[1], &target_24.bssid[2], &target_24.bssid[3], &target_24.bssid[4], &target_24.bssid[5]); target_24.channel = (uint8_t)channel->valueint; target_24.active = true; } } // Parse 5GHz target cJSON *t5 = cJSON_GetObjectItem(root, "target_5ghz"); if (t5) { cJSON *ssid = cJSON_GetObjectItem(t5, "ssid"); cJSON *bssid = cJSON_GetObjectItem(t5, "bssid"); cJSON *channel = cJSON_GetObjectItem(t5, "channel"); if (cJSON_IsString(ssid) && cJSON_IsString(bssid) && cJSON_IsNumber(channel)) { strncpy(target_5.ssid, ssid->valuestring, sizeof(target_5.ssid) - 1); sscanf(bssid->valuestring, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &target_5.bssid[0], &target_5.bssid[1], &target_5.bssid[2], &target_5.bssid[3], &target_5.bssid[4], &target_5.bssid[5]); target_5.channel = (uint8_t)channel->valueint; target_5.active = true; } } // Get duration cJSON *dur = cJSON_GetObjectItem(root, "duration"); uint32_t duration = cJSON_IsNumber(dur) ? dur->valueint : 30; cJSON_Delete(root); // Start attack bool success = deauth_start_attack( target_24.active ? &target_24 : NULL, target_5.active ? &target_5 : NULL, duration ); httpd_resp_set_type(req, "application/json"); if (success) { httpd_resp_sendstr(req, "{\"status\":\"ok\",\"message\":\"Dual-band attack started\"}"); } else { httpd_resp_sendstr(req, "{\"status\":\"error\",\"message\":\"Failed to start attack\"}"); } return ESP_OK; } static esp_err_t deauth_stop_handler(httpd_req_t *req) { deauth_stop_attack(); httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"status\":\"ok\",\"message\":\"Attack stopped\"}"); return ESP_OK; } static esp_err_t sysinfo_handler(httpd_req_t *req) { cJSON *root = cJSON_CreateObject(); cJSON_AddStringToObject(root, "chip", "ESP32-C5"); cJSON_AddNumberToObject(root, "heap", esp_get_free_heap_size()); cJSON_AddStringToObject(root, "version", "2.0.0"); cJSON_AddBoolToObject(root, "attack_running", deauth_is_running()); char *json = cJSON_PrintUnformatted(root); httpd_resp_set_type(req, "application/json"); httpd_resp_send(req, json, strlen(json)); free(json); cJSON_Delete(root); return ESP_OK; } static esp_err_t reboot_handler(httpd_req_t *req) { httpd_resp_set_type(req, "application/json"); httpd_resp_sendstr(req, "{\"status\":\"ok\"}"); vTaskDelay(pdMS_TO_TICKS(500)); esp_restart(); return ESP_OK; } // ============================================================================ // URI HANDLERS // ============================================================================ static httpd_uri_t uri_root = {.uri = "/", .method = HTTP_GET, .handler = root_handler}; static httpd_uri_t uri_scan = {.uri = "/api/scan", .method = HTTP_GET, .handler = scan_handler}; static httpd_uri_t uri_deauth_start = {.uri = "/api/deauth/start", .method = HTTP_POST, .handler = deauth_start_handler}; static httpd_uri_t uri_deauth_stop = {.uri = "/api/deauth/stop", .method = HTTP_GET, .handler = deauth_stop_handler}; static httpd_uri_t uri_sysinfo = {.uri = "/api/system-info", .method = HTTP_GET, .handler = sysinfo_handler}; static httpd_uri_t uri_reboot = {.uri = "/api/reboot", .method = HTTP_GET, .handler = reboot_handler}; static httpd_handle_t server = NULL; httpd_handle_t start_webserver(void) { httpd_config_t config = HTTPD_DEFAULT_CONFIG(); config.stack_size = 8192; config.max_uri_handlers = 10; ESP_LOGI(TAG, "Starting enhanced web server"); if (httpd_start(&server, &config) == ESP_OK) { httpd_register_uri_handler(server, &uri_root); httpd_register_uri_handler(server, &uri_scan); httpd_register_uri_handler(server, &uri_deauth_start); httpd_register_uri_handler(server, &uri_deauth_stop); httpd_register_uri_handler(server, &uri_sysinfo); httpd_register_uri_handler(server, &uri_reboot); ESP_LOGI(TAG, "Enhanced web server started at http://192.168.4.1"); return server; } ESP_LOGE(TAG, "Failed to start web server"); return NULL; } void stop_webserver(void) { if (server) { httpd_stop(server); server = NULL; } } void init_web_server(void) { start_webserver(); }