diff --git a/esp32_marauder/CommandLine.cpp b/esp32_marauder/CommandLine.cpp index d9337d845..74355e5d8 100644 --- a/esp32_marauder/CommandLine.cpp +++ b/esp32_marauder/CommandLine.cpp @@ -245,6 +245,8 @@ void CommandLine::runCommand(String input) { Serial.println(HELP_SEL_CMD_A); Serial.println(HELP_SSID_CMD_A); Serial.println(HELP_SSID_CMD_B); + Serial.println(HELP_SAVE_CMD); + Serial.println(HELP_LOAD_CMD); // Bluetooth sniff/scan #ifdef HAS_BT @@ -1262,6 +1264,41 @@ void CommandLine::runCommand(String input) { return; } } + else if (cmd_args.get(0) == SAVE_CMD) { + int ap_sw = this->argSearch(&cmd_args, "-a"); + int st_sw = this->argSearch(&cmd_args, "-s"); + + if (ap_sw != -1) { + #ifdef HAS_SCREEN + menu_function_obj.changeMenu(&menu_function_obj.saveAPsMenu); + #endif + wifi_scan_obj.RunSaveAPList(true); + } + else if (st_sw != -1) { + #ifdef HAS_SCREEN + menu_function_obj.changeMenu(&menu_function_obj.saveSSIDsMenu); + #endif + wifi_scan_obj.RunSaveSSIDList(true); + } + } + else if (cmd_args.get(0) == LOAD_CMD) { + int ap_sw = this->argSearch(&cmd_args, "-a"); + int st_sw = this->argSearch(&cmd_args, "-s"); + + if (ap_sw != -1) { + #ifdef HAS_SCREEN + menu_function_obj.changeMenu(&menu_function_obj.loadAPsMenu); + #endif + wifi_scan_obj.RunLoadAPList(); + } + else if (st_sw != -1) { + #ifdef HAS_SCREEN + menu_function_obj.changeMenu(&menu_function_obj.loadSSIDsMenu); + #endif + wifi_scan_obj.RunLoadSSIDList(); + } + } + // SSID stuff else if (cmd_args.get(0) == SSID_CMD) { int add_sw = this->argSearch(&cmd_args, "-a"); diff --git a/esp32_marauder/CommandLine.h b/esp32_marauder/CommandLine.h index a17ab8202..c6be7e0fe 100644 --- a/esp32_marauder/CommandLine.h +++ b/esp32_marauder/CommandLine.h @@ -77,6 +77,8 @@ const char PROGMEM ATTACK_TYPE_RR[] = "rickroll"; const char PROGMEM LIST_AP_CMD[] = "list"; const char PROGMEM SEL_CMD[] = "select"; const char PROGMEM SSID_CMD[] = "ssid"; +const char PROGMEM SAVE_CMD[] = "save"; +const char PROGMEM LOAD_CMD[] = "load"; // Bluetooth sniff/scan const char PROGMEM BT_SPAM_CMD[] = "blespam"; @@ -128,6 +130,8 @@ const char PROGMEM HELP_LIST_AP_CMD_C[] = "list -c"; const char PROGMEM HELP_SEL_CMD_A[] = "select -a/-s/-c /-f \"equals or contains \""; const char PROGMEM HELP_SSID_CMD_A[] = "ssid -a [-g /-n ]"; const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r "; +const char PROGMEM HELP_SAVE_CMD[] = "save -a/-s"; +const char PROGMEM HELP_LOAD_CMD[] = "load -a/-s"; // Bluetooth sniff/scan const char PROGMEM HELP_BT_SNIFF_CMD[] = "sniffbt"; diff --git a/esp32_marauder/MenuFunctions.cpp b/esp32_marauder/MenuFunctions.cpp index 5a7fd68ba..ae49925ce 100644 --- a/esp32_marauder/MenuFunctions.cpp +++ b/esp32_marauder/MenuFunctions.cpp @@ -1279,6 +1279,12 @@ void MenuFunctions::RunSetup() generateSSIDsMenu.list = new LinkedList(); clearSSIDsMenu.list = new LinkedList(); clearAPsMenu.list = new LinkedList(); + saveFileMenu.list = new LinkedList(); + + saveSSIDsMenu.list = new LinkedList(); + loadSSIDsMenu.list = new LinkedList(); + saveAPsMenu.list = new LinkedList(); + loadAPsMenu.list = new LinkedList(); // Work menu names mainMenu.name = text_table1[6]; @@ -1295,6 +1301,11 @@ void MenuFunctions::RunSetup() wifiSnifferMenu.name = text_table1[20]; wifiAttackMenu.name = text_table1[21]; wifiGeneralMenu.name = text_table1[22]; + saveFileMenu.name = "Save/Load Files"; + saveSSIDsMenu.name = "Save SSIDs"; + loadSSIDsMenu.name = "Load SSIDs"; + saveAPsMenu.name = "Save APs"; + loadAPsMenu.name = "Load APs"; bluetoothSnifferMenu.name = text_table1[23]; bluetoothAttackMenu.name = "Bluetooth Attacks"; generateSSIDsMenu.name = text_table1[27]; @@ -1486,6 +1497,9 @@ void MenuFunctions::RunSetup() this->changeMenu(&generateSSIDsMenu); wifi_scan_obj.RunGenerateSSIDs(); }); + this->addNodes(&wifiGeneralMenu, "Save/Load Files", TFT_CYAN, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveFileMenu); + }); #ifdef HAS_ILI9341 this->addNodes(&wifiGeneralMenu, text_table1[1], TFT_NAVY, NULL, KEYBOARD_ICO, [this](){ display_obj.clearScreen(); @@ -1640,6 +1654,47 @@ void MenuFunctions::RunSetup() this->changeMenu(clearAPsMenu.parentMenu); }); + saveSSIDsMenu.parentMenu = &saveFileMenu; + this->addNodes(&saveSSIDsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveSSIDsMenu.parentMenu); + }); + + loadSSIDsMenu.parentMenu = &saveFileMenu; + this->addNodes(&loadSSIDsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(loadSSIDsMenu.parentMenu); + }); + + saveAPsMenu.parentMenu = &saveFileMenu; + this->addNodes(&saveAPsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveAPsMenu.parentMenu); + }); + + loadAPsMenu.parentMenu = &saveFileMenu; + this->addNodes(&loadAPsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(loadAPsMenu.parentMenu); + }); + + // Save Files Menu + saveFileMenu.parentMenu = &wifiGeneralMenu; + this->addNodes(&saveFileMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveFileMenu.parentMenu); + }); + this->addNodes(&saveFileMenu, "Save SSIDs", TFT_CYAN, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveSSIDsMenu); + wifi_scan_obj.RunSaveSSIDList(true); + }); + this->addNodes(&saveFileMenu, "Load SSIDs", TFT_SKYBLUE, NULL, SD_UPDATE, [this]() { + this->changeMenu(&loadSSIDsMenu); + wifi_scan_obj.RunLoadSSIDList(); + }); + this->addNodes(&saveFileMenu, "Save APs", TFT_NAVY, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveAPsMenu); + wifi_scan_obj.RunSaveAPList(); + }); + this->addNodes(&saveFileMenu, "Load APs", TFT_BLUE, NULL, SD_UPDATE, [this]() { + this->changeMenu(&loadAPsMenu); + wifi_scan_obj.RunLoadAPList(); + }); // Build Bluetooth Menu bluetoothMenu.parentMenu = &mainMenu; // Second Menu is third menu parent diff --git a/esp32_marauder/MenuFunctions.h b/esp32_marauder/MenuFunctions.h index 489797614..0f225d929 100644 --- a/esp32_marauder/MenuFunctions.h +++ b/esp32_marauder/MenuFunctions.h @@ -152,6 +152,7 @@ class MenuFunctions // WiFi General Menu Menu htmlMenu; Menu miniKbMenu; + Menu saveFileMenu; // Bluetooth menu stuff Menu bluetoothSnifferMenu; @@ -187,6 +188,12 @@ class MenuFunctions Menu* current_menu; Menu clearSSIDsMenu; Menu clearAPsMenu; + + // Save Files Menu + Menu saveSSIDsMenu; + Menu loadSSIDsMenu; + Menu saveAPsMenu; + Menu loadAPsMenu; #ifdef HAS_GPS // GPS Menu diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index 01f024d94..f1d0eb3dc 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -952,6 +952,188 @@ void WiFiScan::startLog(String file_name) { ); } +void WiFiScan::parseBSSID(const char* bssidStr, uint8_t* bssid) { + sscanf(bssidStr, "%02X:%02X:%02X:%02X:%02X:%02X", + &bssid[0], &bssid[1], &bssid[2], + &bssid[3], &bssid[4], &bssid[5]); +} + +void WiFiScan::RunLoadAPList() { + #ifdef HAS_SD + File file = sd_obj.getFile("/APs_0.log"); + if (!file) { + Serial.println("Could not open /APs_0.log"); + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.println("Could not open /APs_0.log"); + #endif + return; + } + + DynamicJsonDocument doc(10048); + DeserializationError error = deserializeJson(doc, file); + if (error) { + Serial.print("JSON deserialize error: "); + Serial.println(error.c_str()); + file.close(); + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.println("Could not deserialize JSON"); + display_obj.tft.println(error.c_str()); + #endif + return; + } + + JsonArray array = doc.as(); + for (JsonObject obj : array) { + AccessPoint ap; + ap.essid = obj["essid"].as(); + ap.channel = obj["channel"]; + ap.selected = false; + parseBSSID(obj["bssid"], ap.bssid); + ap.stations = new LinkedList(); + access_points->add(ap); + } + + file.close(); + + //doc.clear(); + + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.print("Loaded APs: "); + display_obj.tft.println((String)access_points->size()); + #endif + Serial.print("Loaded APs:"); + Serial.println((String)access_points->size()); + #endif +} + +void WiFiScan::RunSaveAPList(bool save_as) { + if (save_as) { + sd_obj.removeFile("/APs_0.log"); + + this->startLog("APs"); + + DynamicJsonDocument jsonDocument(2048); + + JsonArray jsonArray = jsonDocument.to(); + + for (int i = 0; i < access_points->size(); i++) { + const AccessPoint& ap = access_points->get(i); + JsonObject jsonAp = jsonArray.createNestedObject(); + jsonAp["essid"] = ap.essid; + jsonAp["channel"] = ap.channel; + + char bssidStr[18]; + sprintf(bssidStr, "%02X:%02X:%02X:%02X:%02X:%02X", + ap.bssid[0], ap.bssid[1], ap.bssid[2], + ap.bssid[3], ap.bssid[4], ap.bssid[5]); + jsonAp["bssid"] = bssidStr; + } + + String jsonString; + serializeJson(jsonArray, jsonString); + + buffer_obj.append(jsonString); + + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.print("Saved APs: "); + display_obj.tft.println((String)access_points->size()); + #endif + Serial.print("Saved APs:"); + Serial.println((String)access_points->size()); + } +} + +void WiFiScan::RunLoadSSIDList() { + #ifdef HAS_SD + File log_file = sd_obj.getFile("/SSIDs_0.log"); + if (!log_file) { + Serial.println("Could not open /SSIDs_0.log"); + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.println("Could not open /SSIDs_0.log"); + #endif + return; + } + while (log_file.available()) { + String line = log_file.readStringUntil('\n'); // Read until newline character + this->addSSID(line); + } + + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.print("Loaded SSIDs: "); + display_obj.tft.println((String)ssids->size()); + #endif + + log_file.close(); + + Serial.print("Loaded SSIDs: "); + Serial.println((String)ssids->size()); + #endif +} + +void WiFiScan::RunSaveSSIDList(bool save_as) { + if (save_as) { + sd_obj.removeFile("/SSIDs_0.log"); + + this->startLog("SSIDs"); + + for (int i = 0; i < ssids->size(); i++) { + if (i < ssids->size() - 1) + buffer_obj.append(ssids->get(i).essid + "\n"); + else + buffer_obj.append(ssids->get(i).essid); + } + + #ifdef HAS_SCREEN + display_obj.tft.setTextWrap(false); + display_obj.tft.setFreeFont(NULL); + display_obj.tft.setCursor(0, 100); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_CYAN); + + display_obj.tft.print("Saved SSIDs: "); + display_obj.tft.println((String)ssids->size()); + #endif + Serial.print("Saved SSIDs: "); + Serial.println((String)ssids->size()); + } +} + void WiFiScan::RunEvilPortal(uint8_t scan_mode, uint16_t color) { startLog("evil_portal"); diff --git a/esp32_marauder/WiFiScan.h b/esp32_marauder/WiFiScan.h index a43c29b7c..b6145530e 100644 --- a/esp32_marauder/WiFiScan.h +++ b/esp32_marauder/WiFiScan.h @@ -331,6 +331,7 @@ class WiFiScan void RunLvJoinWiFi(uint8_t scan_mode, uint16_t color); void RunEvilPortal(uint8_t scan_mode, uint16_t color); bool checkMem(); + void parseBSSID(const char* bssidStr, uint8_t* bssid); public: @@ -385,6 +386,10 @@ class WiFiScan void RunClearSSIDs(); void RunClearAPs(); void RunClearStations(); + void RunSaveSSIDList(bool save_as = true); + void RunLoadSSIDList(); + void RunSaveAPList(bool save_as = true); + void RunLoadAPList(); void channelHop(); uint8_t currentScanMode = 0; void main(uint32_t currentTime); diff --git a/esp32_marauder/configs.h b/esp32_marauder/configs.h index 22c5b9fe7..f097218c8 100644 --- a/esp32_marauder/configs.h +++ b/esp32_marauder/configs.h @@ -21,7 +21,7 @@ //#define MARAUDER_REV_FEATHER //// END BOARD TARGETS - #define MARAUDER_VERSION "v0.13.9" + #define MARAUDER_VERSION "v0.13.10" //// HARDWARE NAMES #ifdef MARAUDER_M5STICKC