diff --git a/.github/workflows/build_push.yml b/.github/workflows/build_push.yml index c1579c48a..a47a52460 100644 --- a/.github/workflows/build_push.yml +++ b/.github/workflows/build_push.yml @@ -112,7 +112,7 @@ jobs: uses: actions/checkout@v2 with: repository: h2zero/NimBLE-Arduino - ref: 1.2.0 + ref: 1.3.5 path: CustomNimBLE-Arduino - name: Install Adafruit_NeoPixel diff --git a/esp32_marauder/Assets.h b/esp32_marauder/Assets.h index c52dd11d7..c50e55be9 100644 --- a/esp32_marauder/Assets.h +++ b/esp32_marauder/Assets.h @@ -203,7 +203,13 @@ PROGMEM static const unsigned char menu_icons[][66] = { 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F}, {0xFF, 0xFF, 0xFD, 0xBF, 0x0B, 0xD0, 0xE7, 0xE7, 0xEF, 0xF7, 0xCF, 0xF3, // DISABLED TOUCH: 34 0xAF, 0xF5, 0x6F, 0xF6, 0x6F, 0xF6, 0xAF, 0xF5, 0xCF, 0xF3, 0x0F, 0xF0, - 0xE7, 0xE7, 0x0B, 0xD0, 0xFD, 0xBF, 0xFF, 0xFF} + 0xE7, 0xE7, 0x0B, 0xD0, 0xFD, 0xBF, 0xFF, 0xFF}, + {0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0x0F, 0xFE, 0x3F, 0xF3, 0xF9, 0x3F, // FLIPPER: 35 + 0x8D, 0xF7, 0x3F, 0x7D, 0xEE, 0x3F, 0xC6, 0x2D, 0x38, 0xBB, 0x9D, 0x3B, + 0xBB, 0x63, 0x38, 0x87, 0x3C, 0x3E, 0xFB, 0x0F, 0x3F, 0xFF, 0x81, 0x3F, + 0xFF, 0x3F, 0x38, 0xFF, 0xFF, 0x3C, 0xFF, 0x07, 0x3E, 0xFF, 0xEB, 0x3F, + 0xFF, 0xEF, 0x3F, 0xFF, 0xEF, 0x3F, 0xFF, 0xDF, 0x3F, 0xFF, 0xFF, 0x3F, + 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F} }; /*#ifndef MARAUDER_MINI diff --git a/esp32_marauder/CommandLine.cpp b/esp32_marauder/CommandLine.cpp index 9d69730ed..a2f16da7b 100644 --- a/esp32_marauder/CommandLine.cpp +++ b/esp32_marauder/CommandLine.cpp @@ -242,6 +242,7 @@ void CommandLine::runCommand(String input) { Serial.println(HELP_LIST_AP_CMD_A); Serial.println(HELP_LIST_AP_CMD_B); Serial.println(HELP_LIST_AP_CMD_C); + Serial.println(HELP_LIST_AP_CMD_D); Serial.println(HELP_SEL_CMD_A); Serial.println(HELP_SSID_CMD_A); Serial.println(HELP_SSID_CMD_B); @@ -252,6 +253,7 @@ void CommandLine::runCommand(String input) { #ifdef HAS_BT Serial.println(HELP_BT_SNIFF_CMD); Serial.println(HELP_BT_SPAM_CMD); + Serial.println(HELP_BT_SPOOFAT_CMD); //Serial.println(HELP_BT_SWIFTPAIR_SPAM_CMD); //Serial.println(HELP_BT_SAMSUNG_SPAM_CMD); //Serial.println(HELP_BT_SPAM_ALL_CMD); @@ -846,16 +848,73 @@ void CommandLine::runCommand(String input) { // Bluetooth scan if (cmd_args.get(0) == BT_SNIFF_CMD) { #ifdef HAS_BT - Serial.println("Starting Bluetooth scan. Stop with " + (String)STOPSCAN_CMD); - #ifdef HAS_SCREEN - display_obj.clearScreen(); - menu_function_obj.drawStatusBar(); - #endif - wifi_scan_obj.StartScan(BT_SCAN_ALL, TFT_GREEN); + int bt_type_sw = this->argSearch(&cmd_args, "-t"); + + // Specifying type of bluetooth sniff + if (bt_type_sw != -1) { + String bt_type = cmd_args.get(bt_type_sw + 1); + + bt_type.toLowerCase(); + + // Airtag sniff + if (bt_type == "airtag") { + Serial.println("Starting Airtag sniff. Stop with " + (String)STOPSCAN_CMD); + #ifdef HAS_SCREEN + display_obj.clearScreen(); + menu_function_obj.drawStatusBar(); + #endif + wifi_scan_obj.StartScan(BT_SCAN_AIRTAG, TFT_WHITE); + } + else if (bt_type == "flipper") { + Serial.println("Starting Flipper sniff. Stop with " + (String)STOPSCAN_CMD); + #ifdef HAS_SCREEN + display_obj.clearScreen(); + menu_function_obj.drawStatusBar(); + #endif + wifi_scan_obj.StartScan(BT_SCAN_FLIPPER, TFT_ORANGE); + } + } + // General bluetooth sniff + else { + Serial.println("Starting Bluetooth scan. Stop with " + (String)STOPSCAN_CMD); + #ifdef HAS_SCREEN + display_obj.clearScreen(); + menu_function_obj.drawStatusBar(); + #endif + wifi_scan_obj.StartScan(BT_SCAN_ALL, TFT_GREEN); + } #else Serial.println("Bluetooth not supported"); #endif } + else if (cmd_args.get(0) == BT_SPOOFAT_CMD) { + int at_sw = this->argSearch(&cmd_args, "-t"); + if (at_sw != -1) { + #ifdef HAS_BT + int target_mac = cmd_args.get(at_sw + 1).toInt(); + if (target_mac < airtags->size()) { + for (int i = 0; i < airtags->size(); i++) { + AirTag at = airtags->get(i); + if (i == target_mac) + at.selected = true; + else + at.selected = false; + airtags->set(i, at); + } + Serial.println("Spoofing Airtag: " + airtags->get(target_mac).mac); + #ifdef HAS_SCREEN + display_obj.clearScreen(); + menu_function_obj.drawStatusBar(); + #endif + wifi_scan_obj.StartScan(BT_SPOOF_AIRTAG, TFT_WHITE); + } + else { + Serial.println("Provided index is out of range: " + (String)target_mac); + return; + } + #endif + } + } else if (cmd_args.get(0) == BT_SPAM_CMD) { int bt_type_sw = this->argSearch(&cmd_args, "-t"); if (bt_type_sw != -1) { @@ -1072,6 +1131,7 @@ void CommandLine::runCommand(String input) { int ap_sw = this->argSearch(&cmd_args, "-a"); int ss_sw = this->argSearch(&cmd_args, "-s"); int cl_sw = this->argSearch(&cmd_args, "-c"); + int at_sw = this->argSearch(&cmd_args, "-t"); // List APs if (ap_sw != -1) { @@ -1118,6 +1178,12 @@ void CommandLine::runCommand(String input) { } this->showCounts(count_selected); } + // List airtags + else if (at_sw != -1) { + for (int i = 0; i < airtags->size(); i++) { + Serial.println("[" + (String)i + "]MAC: " + airtags->get(i).mac); + } + } else { Serial.println("You did not specify which list to show"); return; diff --git a/esp32_marauder/CommandLine.h b/esp32_marauder/CommandLine.h index da0698fec..350ed601d 100644 --- a/esp32_marauder/CommandLine.h +++ b/esp32_marauder/CommandLine.h @@ -31,6 +31,7 @@ extern WiFiScan wifi_scan_obj; extern Settings settings_obj; extern LedInterface led_obj; extern LinkedList* access_points; +extern LinkedList* airtags; extern LinkedList* ssids; extern LinkedList* stations; extern const String PROGMEM version_number; @@ -83,6 +84,7 @@ const char PROGMEM LOAD_CMD[] = "load"; // Bluetooth sniff/scan const char PROGMEM BT_SPAM_CMD[] = "blespam"; const char PROGMEM BT_SNIFF_CMD[] = "sniffbt"; +const char PROGMEM BT_SPOOFAT_CMD[] = "spoofat"; //const char PROGMEM BT_SOUR_APPLE_CMD[] = "sourapple"; //const char PROGMEM BT_SWIFTPAIR_SPAM_CMD[] = "swiftpair"; //const char PROGMEM BT_SAMSUNG_SPAM_CMD[] = "samsungblespam"; @@ -127,6 +129,7 @@ const char PROGMEM HELP_ATTACK_CMD[] = "attack -t or contains \""; const char PROGMEM HELP_SSID_CMD_A[] = "ssid -a [-g /-n ]"; const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r "; @@ -134,8 +137,9 @@ 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"; +const char PROGMEM HELP_BT_SNIFF_CMD[] = "sniffbt [-t] "; const char PROGMEM HELP_BT_SPAM_CMD[] = "blespam -t "; +const char PROGMEM HELP_BT_SPOOFAT_CMD[] = "spoofat -t "; //const char PROGMEM HELP_BT_SOUR_APPLE_CMD[] = "sourapple"; //const char PROGMEM HELP_BT_SWIFTPAIR_SPAM_CMD[] = "swiftpair"; //const char PROGMEM HELP_BT_SAMSUNG_SPAM_CMD[] = "samsungblespam"; diff --git a/esp32_marauder/MenuFunctions.cpp b/esp32_marauder/MenuFunctions.cpp index bd79696b6..fbc8aad69 100644 --- a/esp32_marauder/MenuFunctions.cpp +++ b/esp32_marauder/MenuFunctions.cpp @@ -304,8 +304,10 @@ MenuFunctions::MenuFunctions() } // GFX Function to build a list showing all APs scanned - void MenuFunctions::addAPGFX(){ + void MenuFunctions::addAPGFX(String type){ + extern WiFiScan wifi_scan_obj; extern LinkedList* access_points; + extern LinkedList* airtags; lv_obj_t * list1 = lv_list_create(lv_scr_act(), NULL); lv_obj_set_size(list1, 160, 200); @@ -319,24 +321,111 @@ MenuFunctions::MenuFunctions() list_btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, text09); lv_obj_set_event_cb(list_btn, ap_list_cb); - for (int i = 0; i < access_points->size(); i++) { - char buf[access_points->get(i).essid.length() + 1] = {}; - access_points->get(i).essid.toCharArray(buf, access_points->get(i).essid.length() + 1); - - list_btn = lv_list_add_btn(list1, LV_SYMBOL_WIFI, buf); - lv_btn_set_checkable(list_btn, true); - lv_obj_set_event_cb(list_btn, ap_list_cb); - - if (access_points->get(i).selected) - lv_btn_toggle(list_btn); + if (type == "AP") { + for (int i = 0; i < access_points->size(); i++) { + char buf[access_points->get(i).essid.length() + 1] = {}; + access_points->get(i).essid.toCharArray(buf, access_points->get(i).essid.length() + 1); + + list_btn = lv_list_add_btn(list1, LV_SYMBOL_WIFI, buf); + lv_btn_set_checkable(list_btn, true); + lv_obj_set_event_cb(list_btn, ap_list_cb); + + if (access_points->get(i).selected) + lv_btn_toggle(list_btn); + } + } + else if (type == "Airtag") { + for (int i = 0; i < airtags->size(); i++) { + char buf[airtags->get(i).mac.length() + 1] = {}; + airtags->get(i).mac.toCharArray(buf, airtags->get(i).mac.length() + 1); + + list_btn = lv_list_add_btn(list1, LV_SYMBOL_BLUETOOTH, buf); + lv_btn_set_checkable(list_btn, true); + lv_obj_set_event_cb(list_btn, at_list_cb); + + //if (airtags->get(i).selected) + // lv_btn_toggle(list_btn); + } } } + void at_list_cb(lv_obj_t * btn, lv_event_t event) { + extern MenuFunctions menu_function_obj; + extern WiFiScan wifi_scan_obj; + extern LinkedList* airtags; + extern Display display_obj; + String btn_text = lv_list_get_btn_text(btn); + String display_string = ""; + + // Button is clicked + if (event == LV_EVENT_CLICKED) { + if (btn_text != text09) { + } + // It's the back button + else { + Serial.println("Exiting..."); + lv_obj_del_async(lv_obj_get_parent(lv_obj_get_parent(btn))); + + for (int i = 0; i < airtags->size(); i++) { + if (airtags->get(i).selected) { + Serial.println("Selected: " + (String)airtags->get(i).mac); + } + } + + printf("LV_EVENT_CANCEL\n"); + menu_function_obj.deinitLVGL(); + wifi_scan_obj.StartScan(WIFI_SCAN_OFF); + display_obj.exit_draw = true; // set everything back to normal + } + } + + if (event == LV_EVENT_VALUE_CHANGED) { + if (lv_btn_get_state(btn) == LV_BTN_STATE_CHECKED_RELEASED) { + bool do_that_thang = false; + for (int i = 0; i < airtags->size(); i++) { + if (airtags->get(i).mac == btn_text) { + Serial.println("Selecting Airtag: " + (String)airtags->get(i).mac); + AirTag at = airtags->get(i); + at.selected = true; + airtags->set(i, at); + do_that_thang = true; + } + else { + AirTag at = airtags->get(i); + at.selected = false; + airtags->set(i, at); + } + } + // Start spoofing airtag + if (do_that_thang) { + menu_function_obj.deinitLVGL(); + lv_obj_del_async(lv_obj_get_parent(lv_obj_get_parent(btn))); + wifi_scan_obj.StartScan(WIFI_SCAN_OFF); + display_obj.clearScreen(); + menu_function_obj.orientDisplay(); + display_obj.clearScreen(); + menu_function_obj.drawStatusBar(); + wifi_scan_obj.StartScan(BT_SPOOF_AIRTAG, TFT_WHITE); + } + } + else { + for (int i = 0; i < airtags->size(); i++) { + if (airtags->get(i).mac == btn_text) { + Serial.println("Deselecting Airtag: " + (String)airtags->get(i).mac); + AirTag at = airtags->get(i); + at.selected = false; + airtags->set(i, at); + } + } + } + } + } void ap_list_cb(lv_obj_t * btn, lv_event_t event) { extern LinkedList* access_points; extern MenuFunctions menu_function_obj; + extern WiFiScan wifi_scan_obj; String btn_text = lv_list_get_btn_text(btn); String display_string = ""; @@ -586,12 +675,14 @@ void MenuFunctions::main(uint32_t currentTime) (wifi_scan_obj.currentScanMode == WIFI_ATTACK_BEACON_LIST) || (wifi_scan_obj.currentScanMode == BT_SCAN_ALL) || (wifi_scan_obj.currentScanMode == BT_SCAN_AIRTAG) || + (wifi_scan_obj.currentScanMode == BT_SCAN_FLIPPER) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SOUR_APPLE) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SWIFTPAIR_SPAM) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SPAM_ALL) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SAMSUNG_SPAM) || (wifi_scan_obj.currentScanMode == BT_ATTACK_GOOGLE_SPAM) || (wifi_scan_obj.currentScanMode == BT_ATTACK_FLIPPER_SPAM) || + (wifi_scan_obj.currentScanMode == BT_SPOOF_AIRTAG) || (wifi_scan_obj.currentScanMode == BT_SCAN_WAR_DRIVE) || (wifi_scan_obj.currentScanMode == BT_SCAN_WAR_DRIVE_CONT) || (wifi_scan_obj.currentScanMode == BT_SCAN_SKIMMERS)) @@ -652,12 +743,14 @@ void MenuFunctions::main(uint32_t currentTime) (wifi_scan_obj.currentScanMode == WIFI_ATTACK_BEACON_LIST) || (wifi_scan_obj.currentScanMode == BT_SCAN_ALL) || (wifi_scan_obj.currentScanMode == BT_SCAN_AIRTAG) || + (wifi_scan_obj.currentScanMode == BT_SCAN_FLIPPER) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SOUR_APPLE) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SWIFTPAIR_SPAM) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SPAM_ALL) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SAMSUNG_SPAM) || (wifi_scan_obj.currentScanMode == BT_ATTACK_GOOGLE_SPAM) || (wifi_scan_obj.currentScanMode == BT_ATTACK_FLIPPER_SPAM) || + (wifi_scan_obj.currentScanMode == BT_SPOOF_AIRTAG) || (wifi_scan_obj.currentScanMode == BT_SCAN_WAR_DRIVE) || (wifi_scan_obj.currentScanMode == BT_SCAN_WAR_DRIVE_CONT) || (wifi_scan_obj.currentScanMode == BT_SCAN_SKIMMERS) || @@ -1227,6 +1320,7 @@ void MenuFunctions::RunSetup() { extern LinkedList* access_points; extern LinkedList* stations; + extern LinkedList* airtags; this->disable_touch = false; @@ -1265,6 +1359,9 @@ void MenuFunctions::RunSetup() #endif wifiGeneralMenu.list = new LinkedList(); wifiAPMenu.list = new LinkedList(); + #ifdef HAS_BT + airtagMenu.list = new LinkedList(); + #endif #ifndef HAS_ILI9341 wifiStationMenu.list = new LinkedList(); #endif @@ -1323,6 +1420,9 @@ void MenuFunctions::RunSetup() clearSSIDsMenu.name = text_table1[28]; clearAPsMenu.name = text_table1[29]; wifiAPMenu.name = "Access Points"; + #ifdef HAS_BT + airtagMenu.name = "Select Airtag"; + #endif #ifndef HAS_ILI9341 wifiStationMenu.name = "Select Stations"; #endif @@ -1663,6 +1763,7 @@ void MenuFunctions::RunSetup() this->changeMenu(wifiAPMenu.parentMenu); }); + // Select Stations on Mini v1 /* this->addNodes(&wifiGeneralMenu, "Select Stations", TFT_CYAN, NULL, KEYBOARD_ICO, [this](){ @@ -1739,7 +1840,7 @@ void MenuFunctions::RunSetup() for (int x = 0; x < access_points->get(i).stations->size(); x++) { int cur_ap_sta = access_points->get(i).stations->get(x); - this->addNodes(&wifiStationMenu, wifi_scan_obj.macToString(stations->get(cur_ap_sta)), TFT_CYAN, NULL, KEYBOARD_ICO, [this, i, cur_ap_sta, x](){ + this->addNodes(&wifiStationMenu, macToString(stations->get(cur_ap_sta)), TFT_CYAN, NULL, KEYBOARD_ICO, [this, i, cur_ap_sta, x](){ Station new_sta = stations->get(cur_ap_sta); new_sta.selected = !stations->get(cur_ap_sta).selected; @@ -1853,6 +1954,11 @@ void MenuFunctions::RunSetup() this->drawStatusBar(); wifi_scan_obj.StartScan(BT_SCAN_ALL, TFT_GREEN); }); + this->addNodes(&bluetoothSnifferMenu, "Flipper Sniff", TFT_ORANGE, NULL, FLIPPER, [this]() { + display_obj.clearScreen(); + this->drawStatusBar(); + wifi_scan_obj.StartScan(BT_SCAN_FLIPPER, TFT_ORANGE); + }); this->addNodes(&bluetoothSnifferMenu, "Airtag Sniff", TFT_WHITE, NULL, BLUETOOTH_SNIFF, [this]() { display_obj.clearScreen(); this->drawStatusBar(); @@ -1903,7 +2009,7 @@ void MenuFunctions::RunSetup() this->drawStatusBar(); wifi_scan_obj.StartScan(BT_ATTACK_GOOGLE_SPAM, TFT_PURPLE); }); - this->addNodes(&bluetoothAttackMenu, "Flipper BLE Spam", TFT_ORANGE, NULL, LANGUAGE, [this]() { + this->addNodes(&bluetoothAttackMenu, "Flipper BLE Spam", TFT_ORANGE, NULL, FLIPPER, [this]() { display_obj.clearScreen(); this->drawStatusBar(); wifi_scan_obj.StartScan(BT_ATTACK_FLIPPER_SPAM, TFT_ORANGE); @@ -1914,6 +2020,68 @@ void MenuFunctions::RunSetup() wifi_scan_obj.StartScan(BT_ATTACK_SPAM_ALL, TFT_MAGENTA); }); + #ifdef HAS_ILI9341 + this->addNodes(&bluetoothAttackMenu, "Spoof Airtag", TFT_WHITE, NULL, ATTACKS, [this](){ + display_obj.clearScreen(); + wifi_scan_obj.currentScanMode = LV_ADD_SSID; + wifi_scan_obj.StartScan(LV_ADD_SSID, TFT_WHITE); + addAPGFX("Airtag"); + }); + #endif + + #ifndef HAS_ILI9341 + #ifdef HAS_BT + // Select Airtag on Mini + this->addNodes(&bluetoothAttackMenu, "Spoof Airtag", TFT_WHITE, NULL, ATTACKS, [this](){ + // Clear nodes and add back button + airtagMenu.list->clear(); + this->addNodes(&airtagMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(airtagMenu.parentMenu); + }); + + // Add buttons for all airtags + // Find out how big our menu is going to be + int menu_limit; + if (airtags->size() <= BUTTON_ARRAY_LEN) + menu_limit = airtags->size(); + else + menu_limit = BUTTON_ARRAY_LEN; + + // Create the menu nodes for all of the list items + for (int i = 0; i < menu_limit; i++) { + this->addNodes(&airtagMenu, airtags->get(i).mac, TFT_WHITE, NULL, BLUETOOTH, [this, i](){ + AirTag new_at = airtags->get(i); + new_at.selected = true; + + airtags->set(i, new_at); + + // Set all other airtags to "Not Selected" + for (int x = 0; x < airtags->size(); x++) { + if (x != i) { + AirTag new_atx = airtags->get(x); + new_atx.selected = false; + airtags->set(x, new_atx); + } + } + + // Start the spoof + display_obj.clearScreen(); + this->drawStatusBar(); + wifi_scan_obj.StartScan(BT_SPOOF_AIRTAG, TFT_WHITE); + + }); + } + this->changeMenu(&airtagMenu); + }); + + airtagMenu.parentMenu = &bluetoothAttackMenu; + this->addNodes(&airtagMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(airtagMenu.parentMenu); + }); + #endif + + #endif + // Device menu deviceMenu.parentMenu = &mainMenu; this->addNodes(&deviceMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { diff --git a/esp32_marauder/MenuFunctions.h b/esp32_marauder/MenuFunctions.h index 8b016ca6c..9599e20a0 100644 --- a/esp32_marauder/MenuFunctions.h +++ b/esp32_marauder/MenuFunctions.h @@ -72,6 +72,7 @@ extern Settings settings_obj; #define STATUS_GPS 32 #define GPS_MENU 33 #define DISABLE_TOUCH 34 +#define FLIPPER 35 PROGMEM void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p); PROGMEM bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data); @@ -83,6 +84,7 @@ PROGMEM static void ta_event_cb(lv_obj_t * ta, lv_event_t event); PROGMEM static void add_ssid_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event); PROGMEM static void html_list_cb(lv_obj_t * btn, lv_event_t event); PROGMEM static void ap_list_cb(lv_obj_t * btn, lv_event_t event); +PROGMEM static void at_list_cb(lv_obj_t * btn, lv_event_t event); PROGMEM static void station_list_cb(lv_obj_t * btn, lv_event_t event); PROGMEM static void setting_dropdown_cb(lv_obj_t * btn, lv_event_t event); @@ -151,6 +153,9 @@ class MenuFunctions #endif Menu wifiGeneralMenu; Menu wifiAPMenu; + #ifdef HAS_BT + Menu airtagMenu; + #endif #ifndef HAS_ILI9341 Menu wifiStationMenu; #endif @@ -220,7 +225,7 @@ class MenuFunctions void selectEPHTMLGFX(); void updateStatusBar(); void addSSIDGFX(); - void addAPGFX(); + void addAPGFX(String type = "AP"); void addStationGFX(); void buildButtons(Menu* menu, int starting_index = 0, String button_name = ""); void changeMenu(Menu* menu); diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index 289472470..cdd2add74 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -10,6 +10,7 @@ LinkedList* ssids; LinkedList* access_points; LinkedList* stations; LinkedList* airtags; +LinkedList* flippers; extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3){ if (arg == 31337) @@ -38,7 +39,7 @@ extern "C" { switch (Type) { case Microsoft: { - const char* Name = this->generateRandomName(); + const char* Name = generateRandomName(); uint8_t name_len = strlen(Name); @@ -176,6 +177,18 @@ extern "C" { break; } + + case Airtag: { + for (int i = 0; i < airtags->size(); i++) { + if (airtags->get(i).selected) { + AdvData.addData(std::string((char*)airtags->get(i).payload.data(), airtags->get(i).payloadSize)); + + break; + } + } + + break; + } default: { Serial.println("Please Provide a Company Type"); break; @@ -244,6 +257,7 @@ extern "C" { AirTag airtag; airtag.mac = mac; airtag.payload.assign(payLoad, payLoad + len); + airtag.payloadSize = len; airtags->add(airtag); @@ -262,6 +276,76 @@ extern "C" { #endif } } + else if (wifi_scan_obj.currentScanMode == BT_SCAN_FLIPPER) { + uint8_t* payLoad = advertisedDevice->getPayload(); + size_t len = advertisedDevice->getPayloadLength(); + + bool match = false; + String color = ""; + for (int i = 0; i <= len - 4; i++) { + if (payLoad[i] == 0x81 && payLoad[i+1] == 0x30) { + match = true; + color = "Black"; + break; + } + if (payLoad[i] == 0x82 && payLoad[i+1] == 0x30) { + match = true; + color = "White"; + break; + } + if (payLoad[i] == 0x83 && payLoad[i+1] == 0x30) { + color = "Transparent"; + match = true; + break; + } + } + + if (match) { + String mac = advertisedDevice->getAddress().toString().c_str(); + String name = advertisedDevice->getName().c_str(); + mac.toUpperCase(); + + for (int i = 0; i < flippers->size(); i++) { + if (mac == flippers->get(i).mac) + return; + } + + int rssi = advertisedDevice->getRSSI(); + Serial.print("RSSI: "); + Serial.print(rssi); + Serial.print(" MAC: "); + Serial.println(mac); + Serial.print("Name: "); + Serial.println(name); + + Flipper flipper; + flipper.mac = mac; + flipper.name = name; + + flippers->add(flipper); + + + /*#ifdef HAS_SCREEN + //display_string.concat("RSSI: "); + display_string.concat((String)rssi); + display_string.concat(" Flipper: "); + display_string.concat(name); + uint8_t temp_len = display_string.length(); + for (uint8_t i = 0; i < 40 - temp_len; i++) + { + display_string.concat(" "); + } + display_obj.display_buffer->add(display_string); + #endif*/ + + #ifdef HAS_SCREEN + display_obj.display_buffer->add(String("Flipper: ") + name + ", "); + display_obj.display_buffer->add(" MAC: " + String(mac) + ", "); + display_obj.display_buffer->add(" RSSI: " + String(rssi) + ", "); + display_obj.display_buffer->add(" Color: " + String(color) + " "); + #endif + } + } else if (wifi_scan_obj.currentScanMode == BT_SCAN_ALL) { if (buf >= 0) { @@ -414,13 +498,13 @@ WiFiScan::WiFiScan() { } -String WiFiScan::macToString(const Station& station) { +/*String WiFiScan::macToString(const Station& station) { char macStr[18]; // 6 pairs of hex digits + 5 colons + null terminator snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", station.mac[0], station.mac[1], station.mac[2], station.mac[3], station.mac[4], station.mac[5]); return String(macStr); -} +}*/ void WiFiScan::RunSetup() { if (ieee80211_raw_frame_sanity_check(31337, 0, 0) == 1) @@ -432,6 +516,7 @@ void WiFiScan::RunSetup() { access_points = new LinkedList(); stations = new LinkedList(); airtags = new LinkedList(); + flippers = new LinkedList(); #ifdef HAS_BT watch_models = new WatchModel[26] { @@ -510,6 +595,14 @@ int WiFiScan::clearAirtags() { return num_cleared; } +int WiFiScan::clearFlippers() { + int num_cleared = flippers->size(); + while (flippers->size() > 0) + flippers->remove(0); + Serial.println("Flippers: " + (String)flippers->size()); + return num_cleared; +} + int WiFiScan::clearSSIDs() { int num_cleared = ssids->size(); ssids->clear(); @@ -683,7 +776,7 @@ void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color) this->startWiFiAttacks(scan_mode, color, text_table4[47]); else if (scan_mode == WIFI_ATTACK_AP_SPAM) this->startWiFiAttacks(scan_mode, color, " AP Beacon Spam "); - else if ((scan_mode == BT_SCAN_ALL) || (BT_SCAN_AIRTAG)){ + else if ((scan_mode == BT_SCAN_ALL) || (scan_mode == BT_SCAN_AIRTAG) || (scan_mode == BT_SCAN_FLIPPER)){ #ifdef HAS_BT RunBluetoothScan(scan_mode, color); #endif @@ -697,7 +790,8 @@ void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color) (scan_mode == BT_ATTACK_SPAM_ALL) || (scan_mode == BT_ATTACK_SAMSUNG_SPAM) || (scan_mode == BT_ATTACK_GOOGLE_SPAM) || - (scan_mode == BT_ATTACK_FLIPPER_SPAM)) { + (scan_mode == BT_ATTACK_FLIPPER_SPAM) || + (scan_mode == BT_SPOOF_AIRTAG)) { #ifdef HAS_BT RunSwiftpairSpam(scan_mode, color); #endif @@ -816,6 +910,7 @@ bool WiFiScan::shutdownWiFi() { bool WiFiScan::shutdownBLE() { #ifdef HAS_BT if (this->ble_initialized) { + Serial.println("Shutting down BLE"); pAdvertising->stop(); pBLEScan->stop(); @@ -879,12 +974,14 @@ void WiFiScan::StopScan(uint8_t scan_mode) else if ((currentScanMode == BT_SCAN_ALL) || (currentScanMode == BT_SCAN_AIRTAG) || + (currentScanMode == BT_SCAN_FLIPPER) || (currentScanMode == BT_ATTACK_SOUR_APPLE) || (currentScanMode == BT_ATTACK_SWIFTPAIR_SPAM) || (currentScanMode == BT_ATTACK_SPAM_ALL) || (currentScanMode == BT_ATTACK_SAMSUNG_SPAM) || (currentScanMode == BT_ATTACK_GOOGLE_SPAM) || (currentScanMode == BT_ATTACK_FLIPPER_SPAM) || + (currentScanMode == BT_SPOOF_AIRTAG) || (currentScanMode == BT_SCAN_WAR_DRIVE) || (currentScanMode == BT_SCAN_WAR_DRIVE_CONT) || (currentScanMode == BT_SCAN_SKIMMERS)) @@ -2011,7 +2108,7 @@ void WiFiScan::executeSourApple() { #endif } -void WiFiScan::generateRandomName(char *name, size_t length) { +/*void WiFiScan::generateRandomName(char *name, size_t length) { static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz"; // Generate the first character as uppercase @@ -2022,9 +2119,9 @@ void WiFiScan::generateRandomName(char *name, size_t length) { name[i] = alphabet[rand() % (sizeof(alphabet) - 1)]; } name[length - 1] = '\0'; // Null-terminate the string -} +}*/ -const char* WiFiScan::generateRandomName() { +/*const char* WiFiScan::generateRandomName() { const char* charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; int len = rand() % 10 + 1; // Generate a random length between 1 and 10 char* randomName = (char*)malloc((len + 1) * sizeof(char)); // Allocate memory for the random name @@ -2033,9 +2130,9 @@ const char* WiFiScan::generateRandomName() { } randomName[len] = '\0'; // Null-terminate the string return randomName; -} +}*/ -void WiFiScan::generateRandomMac(uint8_t* mac) { +/*void WiFiScan::generateRandomMac(uint8_t* mac) { // Set the locally administered bit and unicast bit for the first byte mac[0] = 0x02; // The locally administered bit is the second least significant bit @@ -2043,6 +2140,56 @@ void WiFiScan::generateRandomMac(uint8_t* mac) { for (int i = 1; i < 6; i++) { mac[i] = random(0, 255); } +}*/ + +void WiFiScan::setBaseMacAddress(uint8_t macAddr[6]) { + // Use ESP-IDF function to set the base MAC address + esp_err_t err = esp_base_mac_addr_set(macAddr); + + // Check for success or handle errors + if (err == ESP_OK) { + return; + } else if (err == ESP_ERR_INVALID_ARG) { + Serial.println("Error: Invalid MAC address argument."); + } else { + Serial.printf("Error: Failed to set MAC address. Code: %d\n", err); + } +} + +void WiFiScan::executeSpoofAirtag() { + #ifdef HAS_BT + for (int i = 0; i < airtags->size(); i++) { + if (airtags->get(i).selected) { + + uint8_t macAddr[6]; + + convertMacStringToUint8(airtags->get(i).mac, macAddr); + + macAddr[5] -= 2; + + // Do this because ESP32 BT addr is Base MAC + 2 + + this->setBaseMacAddress(macAddr); + + NimBLEDevice::init(""); + + NimBLEServer *pServer = NimBLEDevice::createServer(); + + pAdvertising = pServer->getAdvertising(); + + //NimBLEAdvertisementData advertisementData = getSwiftAdvertisementData(); + NimBLEAdvertisementData advertisementData = this->GetUniversalAdvertisementData(Airtag); + pAdvertising->setAdvertisementData(advertisementData); + pAdvertising->start(); + delay(10); + pAdvertising->stop(); + + NimBLEDevice::deinit(); + + break; + } + } + #endif } void WiFiScan::executeSwiftpairSpam(EBLEPayloadType type) { @@ -2050,7 +2197,9 @@ void WiFiScan::executeSwiftpairSpam(EBLEPayloadType type) { uint8_t macAddr[6]; generateRandomMac(macAddr); - esp_base_mac_addr_set(macAddr); + //esp_base_mac_addr_set(macAddr); + + this->setBaseMacAddress(macAddr); NimBLEDevice::init(""); @@ -2457,6 +2606,8 @@ void WiFiScan::RunSwiftpairSpam(uint8_t scan_mode, uint16_t color) { display_obj.tft.drawCentreString("BLE Spam Google",120,16,2); else if (scan_mode == BT_ATTACK_FLIPPER_SPAM) display_obj.tft.drawCentreString("BLE Spam Flipper", 120, 16, 2); + else if (scan_mode == BT_SPOOF_AIRTAG) + display_obj.tft.drawCentreString("BLE Spoof Airtag", 120, 16, 2); display_obj.touchToExit(); #endif display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK); @@ -2481,7 +2632,7 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) } NimBLEDevice::init(""); pBLEScan = NimBLEDevice::getScan(); //create new scan - if ((scan_mode == BT_SCAN_ALL) || (BT_SCAN_AIRTAG)) + if ((scan_mode == BT_SCAN_ALL) || (scan_mode == BT_SCAN_AIRTAG) || (scan_mode == BT_SCAN_FLIPPER)) { #ifdef HAS_SCREEN display_obj.TOP_FIXED_AREA_2 = 48; @@ -2495,6 +2646,8 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) display_obj.tft.drawCentreString(text_table4[41],120,16,2); else if (scan_mode == BT_SCAN_AIRTAG) display_obj.tft.drawCentreString("Airtag Sniff",120,16,2); + else if (scan_mode == BT_SCAN_FLIPPER) + display_obj.tft.drawCentreString("Flipper Sniff", 120, 16, 2); display_obj.touchToExit(); #endif display_obj.tft.setTextColor(TFT_CYAN, TFT_BLACK); @@ -2506,6 +2659,10 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) this->clearAirtags(); pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanAllCallback(), true); } + else if (scan_mode == BT_SCAN_FLIPPER) { + this->clearFlippers(); + pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanAllCallback(), true); + } } else if ((scan_mode == BT_SCAN_WAR_DRIVE) || (scan_mode == BT_SCAN_WAR_DRIVE_CONT)) { #ifdef HAS_GPS @@ -4906,7 +5063,8 @@ void WiFiScan::main(uint32_t currentTime) (currentScanMode == BT_ATTACK_SPAM_ALL) || (currentScanMode == BT_ATTACK_SAMSUNG_SPAM) || (currentScanMode == BT_ATTACK_GOOGLE_SPAM) || - (currentScanMode == BT_ATTACK_FLIPPER_SPAM)) { + (currentScanMode == BT_ATTACK_FLIPPER_SPAM) || + (currentScanMode == BT_SPOOF_AIRTAG)) { #ifdef HAS_BT if (currentTime - initTime >= 1000) { initTime = millis(); @@ -4942,6 +5100,10 @@ void WiFiScan::main(uint32_t currentTime) if ((currentScanMode == BT_ATTACK_FLIPPER_SPAM) || (currentScanMode == BT_ATTACK_SPAM_ALL)) this->executeSwiftpairSpam(FlipperZero); + + if (currentScanMode == BT_SPOOF_AIRTAG) + this->executeSpoofAirtag(); + #endif } else if (currentScanMode == WIFI_SCAN_WAR_DRIVE) { diff --git a/esp32_marauder/WiFiScan.h b/esp32_marauder/WiFiScan.h index 2cddbc995..3cf52fa61 100644 --- a/esp32_marauder/WiFiScan.h +++ b/esp32_marauder/WiFiScan.h @@ -4,6 +4,7 @@ #define WiFiScan_h #include "configs.h" +#include "utils.h" #include #include @@ -95,6 +96,8 @@ #define BT_ATTACK_GOOGLE_SPAM 41 #define BT_ATTACK_FLIPPER_SPAM 42 #define BT_SCAN_AIRTAG 43 +#define BT_SPOOF_AIRTAG 44 +#define BT_SCAN_FLIPPER 45 #define GRAPH_REFRESH 100 @@ -146,18 +149,25 @@ esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, b };*/ -struct mac_addr { +/*struct mac_addr { unsigned char bytes[6]; }; struct Station { uint8_t mac[6]; bool selected; -}; +};*/ struct AirTag { String mac; // MAC address of the AirTag std::vector payload; // Payload data + uint16_t payloadSize; + bool selected; +}; + +struct Flipper { + String mac; + String name; }; class WiFiScan @@ -271,7 +281,8 @@ class WiFiScan Apple, Samsung, Google, - FlipperZero + FlipperZero, + Airtag }; #ifdef HAS_BT @@ -300,10 +311,11 @@ class WiFiScan void clearMacHistory(); void executeWarDrive(); void executeSourApple(); + void executeSpoofAirtag(); void executeSwiftpairSpam(EBLEPayloadType type); void startWardriverWiFi(); - void generateRandomMac(uint8_t* mac); - void generateRandomName(char *name, size_t length); + //void generateRandomMac(uint8_t* mac); + //void generateRandomName(char *name, size_t length); String processPwnagotchiBeacon(const uint8_t* frame, int length); void startWiFiAttacks(uint8_t scan_mode, uint16_t color, String title_string); @@ -380,6 +392,7 @@ class WiFiScan int clearSSIDs(); int clearAPs(); int clearAirtags(); + int clearFlippers(); int clearStations(); bool addSSID(String essid); int generateSSIDs(int count = 20); @@ -407,12 +420,13 @@ class WiFiScan void main(uint32_t currentTime); void StartScan(uint8_t scan_mode, uint16_t color = 0); void StopScan(uint8_t scan_mode); - const char* generateRandomName(); + void setBaseMacAddress(uint8_t macAddr[6]); + //const char* generateRandomName(); bool save_serial = false; void startPcap(String file_name); void startLog(String file_name); - String macToString(const Station& station); + //String macToString(const Station& station); static void getMAC(char *addr, uint8_t* data, uint16_t offset); static void pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type); diff --git a/esp32_marauder/configs.h b/esp32_marauder/configs.h index a752223b7..d63472129 100644 --- a/esp32_marauder/configs.h +++ b/esp32_marauder/configs.h @@ -8,10 +8,10 @@ //// BOARD TARGETS //#define MARAUDER_M5STICKC - #define MARAUDER_MINI + //#define MARAUDER_MINI //#define MARAUDER_V4 //#define MARAUDER_V6 - //#define MARAUDER_V6_1 + #define MARAUDER_V6_1 //#define MARAUDER_KIT //#define GENERIC_ESP32 //#define MARAUDER_FLIPPER diff --git a/esp32_marauder/utils.h b/esp32_marauder/utils.h new file mode 100644 index 000000000..a9e6ad69e --- /dev/null +++ b/esp32_marauder/utils.h @@ -0,0 +1,79 @@ +#pragma once +#ifndef utils_h +#define utils_h + +#include + +struct mac_addr { + unsigned char bytes[6]; +}; + +struct Station { + uint8_t mac[6]; + bool selected; +}; + +void generateRandomName(char *name, size_t length) { + static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz"; + + // Generate the first character as uppercase + name[0] = 'A' + (rand() % 26); + + // Generate the remaining characters as lowercase + for (size_t i = 1; i < length - 1; ++i) { + name[i] = alphabet[rand() % (sizeof(alphabet) - 1)]; + } + name[length - 1] = '\0'; // Null-terminate the string +} + +const char* generateRandomName() { + const char* charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int len = rand() % 10 + 1; // Generate a random length between 1 and 10 + char* randomName = (char*)malloc((len + 1) * sizeof(char)); // Allocate memory for the random name + for (int i = 0; i < len; ++i) { + randomName[i] = charset[rand() % strlen(charset)]; // Select random characters from the charset + } + randomName[len] = '\0'; // Null-terminate the string + return randomName; +} + +void generateRandomMac(uint8_t* mac) { + // Set the locally administered bit and unicast bit for the first byte + mac[0] = 0x02; // The locally administered bit is the second least significant bit + + // Generate the rest of the MAC address + for (int i = 1; i < 6; i++) { + mac[i] = random(0, 255); + } +} + +String macToString(const Station& station) { + char macStr[18]; // 6 pairs of hex digits + 5 colons + null terminator + snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", + station.mac[0], station.mac[1], station.mac[2], + station.mac[3], station.mac[4], station.mac[5]); + return String(macStr); +} + +String macToString(uint8_t macAddr[6]) { + char macStr[18]; // 17 characters for "XX:XX:XX:XX:XX:XX" + 1 null terminator + snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", + macAddr[0], macAddr[1], macAddr[2], + macAddr[3], macAddr[4], macAddr[5]); + return String(macStr); +} + +void convertMacStringToUint8(const String& macStr, uint8_t macAddr[6]) { + // Ensure the input string is in the format "XX:XX:XX:XX:XX:XX" + if (macStr.length() != 17) { + Serial.println("Invalid MAC address format"); + return; + } + + // Parse the MAC address string and fill the uint8_t array + for (int i = 0; i < 6; i++) { + macAddr[i] = (uint8_t)strtol(macStr.substring(i * 3, i * 3 + 2).c_str(), nullptr, 16); + } +} + +#endif \ No newline at end of file diff --git a/pictures/icons/flipper_22.bmp b/pictures/icons/flipper_22.bmp new file mode 100644 index 000000000..486454ed0 Binary files /dev/null and b/pictures/icons/flipper_22.bmp differ diff --git a/pictures/xbm/flipper_22.xbm b/pictures/xbm/flipper_22.xbm new file mode 100644 index 000000000..b83bd085a --- /dev/null +++ b/pictures/xbm/flipper_22.xbm @@ -0,0 +1,9 @@ +#define 46b478bd979f4b9aa1ef9da6d23af832GZGcJCdnPjHIQppj_width 22 +#define 46b478bd979f4b9aa1ef9da6d23af832GZGcJCdnPjHIQppj_height 22 +static char 46b478bd979f4b9aa1ef9da6d23af832GZGcJCdnPjHIQppj_bits[] = { + 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0x0F, 0xFE, 0x3F, 0xF3, 0xF9, 0x3F, + 0x8D, 0xF7, 0x3F, 0x7D, 0xEE, 0x3F, 0xC6, 0x2D, 0x38, 0xBB, 0x9D, 0x3B, + 0xBB, 0x63, 0x38, 0x87, 0x3C, 0x3E, 0xFB, 0x0F, 0x3F, 0xFF, 0x81, 0x3F, + 0xFF, 0x3F, 0x38, 0xFF, 0xFF, 0x3C, 0xFF, 0x07, 0x3E, 0xFF, 0xEB, 0x3F, + 0xFF, 0xEF, 0x3F, 0xFF, 0xEF, 0x3F, 0xFF, 0xDF, 0x3F, 0xFF, 0xFF, 0x3F, + 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, };