From 05eb6d74a5710310517cac2a4da8f676c2c36a2c Mon Sep 17 00:00:00 2001 From: Just Call Me Koko Date: Wed, 29 Oct 2025 15:32:07 -0400 Subject: [PATCH] Add airtag monitor --- esp32_marauder/MenuFunctions.cpp | 9 +++- esp32_marauder/WiFiScan.cpp | 77 ++++++++++++++++++++++++-------- esp32_marauder/WiFiScan.h | 2 + 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/esp32_marauder/MenuFunctions.cpp b/esp32_marauder/MenuFunctions.cpp index a16a9ed..7a1c67c 100644 --- a/esp32_marauder/MenuFunctions.cpp +++ b/esp32_marauder/MenuFunctions.cpp @@ -909,6 +909,7 @@ 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_AIRTAG_MON) || (wifi_scan_obj.currentScanMode == BT_SCAN_FLIPPER) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SOUR_APPLE) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SWIFTPAIR_SPAM) || @@ -998,11 +999,12 @@ void MenuFunctions::main(uint32_t currentTime) (wifi_scan_obj.currentScanMode == WIFI_ATTACK_SLEEP) || (wifi_scan_obj.currentScanMode == WIFI_ATTACK_SLEEP_TARGETED) || (wifi_scan_obj.currentScanMode == WIFI_ATTACK_MIMIC) || - (wifi_scan_obj.currentScanMode == WIFI_ATTACK_FUNNY_BEACON) || + (wifi_scan_obj.currentScanMode == WIFI_ATTACK_FUNNY_BEACON) || (wifi_scan_obj.currentScanMode == WIFI_ATTACK_RICK_ROLL) || (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_AIRTAG_MON) || (wifi_scan_obj.currentScanMode == BT_SCAN_FLIPPER) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SOUR_APPLE) || (wifi_scan_obj.currentScanMode == BT_ATTACK_SWIFTPAIR_SPAM) || @@ -3068,6 +3070,11 @@ void MenuFunctions::RunSetup() this->drawStatusBar(); wifi_scan_obj.StartScan(BT_SCAN_AIRTAG, TFT_WHITE); }); + this->addNodes(&bluetoothSnifferMenu, "Airtag Monitor", TFTWHITE, NULL, BLUETOOTH_SNIFF, [this]() { + display_obj.clearScreen(); + this->drawStatusBar(); + wifi_scan_obj.StartScan(BT_SCAN_AIRTAG_MON, TFT_WHITE); + }); #ifdef HAS_GPS if (gps_obj.getGpsModuleStatus()) { this->addNodes(&bluetoothSnifferMenu, "BT Wardrive", TFTCYAN, NULL, BLUETOOTH_SNIFF, [this]() { diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index 9d7e637..339af17 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -223,7 +223,8 @@ extern "C" { String display_string = ""; - if (wifi_scan_obj.currentScanMode == BT_SCAN_AIRTAG) { + if ((wifi_scan_obj.currentScanMode == BT_SCAN_AIRTAG) || + (wifi_scan_obj.currentScanMode == BT_SCAN_AIRTAG_MON)) { uint8_t* payLoad = advertisedDevice->getPayload(); size_t len = advertisedDevice->getPayloadLength(); @@ -239,16 +240,22 @@ extern "C" { } } + int rssi = advertisedDevice->getRSSI(); + if (match) { String mac = advertisedDevice->getAddress().toString().c_str(); mac.toUpperCase(); for (int i = 0; i < airtags->size(); i++) { - if (mac == airtags->get(i).mac) + // Airtag is in list already. Update RSSI + if (mac == airtags->get(i).mac) { + AirTag old_airtag = airtags->get(i); + old_airtag.rssi = rssi; + airtags->set(i, old_airtag); return; + } } - int rssi = advertisedDevice->getRSSI(); Serial.print("RSSI: "); Serial.print(rssi); Serial.print(" MAC: "); @@ -265,22 +272,25 @@ extern "C" { airtag.mac = mac; airtag.payload.assign(payLoad, payLoad + len); airtag.payloadSize = len; + airtag.rssi = rssi; airtags->add(airtag); - #ifdef HAS_SCREEN - //display_string.concat("RSSI: "); - display_string.concat((String)rssi); - display_string.concat(" MAC: "); - display_string.concat(mac); - 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 + if (wifi_scan_obj.currentScanMode != BT_SCAN_AIRTAG_MON) { + #ifdef HAS_SCREEN + //display_string.concat("RSSI: "); + display_string.concat((String)rssi); + display_string.concat(" MAC: "); + display_string.concat(mac); + 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 + } } } else if (wifi_scan_obj.currentScanMode == BT_SCAN_FLIPPER) { @@ -1059,7 +1069,11 @@ void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color) this->startWiFiAttacks(scan_mode, color, "Sleep Targeted"); else if (scan_mode == WIFI_ATTACK_AP_SPAM) this->startWiFiAttacks(scan_mode, color, " AP Beacon Spam "); - else if ((scan_mode == BT_SCAN_ALL) || (scan_mode == BT_SCAN_AIRTAG) || (scan_mode == BT_SCAN_FLIPPER) || (scan_mode == BT_SCAN_ANALYZER)){ + else if ((scan_mode == BT_SCAN_ALL) || + (scan_mode == BT_SCAN_AIRTAG) || + (scan_mode == BT_SCAN_AIRTAG_MON) || + (scan_mode == BT_SCAN_FLIPPER) || + (scan_mode == BT_SCAN_ANALYZER)) { #ifdef HAS_BT RunBluetoothScan(scan_mode, color); #endif @@ -1375,6 +1389,7 @@ void WiFiScan::StopScan(uint8_t scan_mode) else if ((currentScanMode == BT_SCAN_ALL) || (currentScanMode == BT_SCAN_AIRTAG) || + (currentScanMode == BT_SCAN_AIRTAG_MON) || (currentScanMode == BT_SCAN_FLIPPER) || (currentScanMode == BT_ATTACK_SOUR_APPLE) || (currentScanMode == BT_ATTACK_SWIFTPAIR_SPAM) || @@ -3823,7 +3838,10 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) } NimBLEDevice::init(""); pBLEScan = NimBLEDevice::getScan(); //create new scan - if ((scan_mode == BT_SCAN_ALL) || (scan_mode == BT_SCAN_AIRTAG) || (scan_mode == BT_SCAN_FLIPPER)) + if ((scan_mode == BT_SCAN_ALL) || + (scan_mode == BT_SCAN_AIRTAG) || + (scan_mode == BT_SCAN_AIRTAG_MON) || + (scan_mode == BT_SCAN_FLIPPER)) { #ifdef HAS_SCREEN display_obj.TOP_FIXED_AREA_2 = 48; @@ -3837,6 +3855,8 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) display_obj.tft.drawCentreString(text_table4[41],TFT_WIDTH / 2,16,2); else if (scan_mode == BT_SCAN_AIRTAG) display_obj.tft.drawCentreString("Airtag Sniff",TFT_WIDTH / 2,16,2); + else if (scan_mode == BT_SCAN_AIRTAG_MON) + display_obj.tft.drawCentreString("Airtag Monitor",TFT_WIDTH / 2,16,2); else if (scan_mode == BT_SCAN_FLIPPER) display_obj.tft.drawCentreString("Flipper Sniff", TFT_WIDTH / 2, 16, 2); #ifdef HAS_ILI9341 @@ -3848,7 +3868,7 @@ void WiFiScan::RunBluetoothScan(uint8_t scan_mode, uint16_t color) #endif if (scan_mode == BT_SCAN_ALL) pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanAllCallback(), false); - else if (scan_mode == BT_SCAN_AIRTAG) { + else if ((scan_mode == BT_SCAN_AIRTAG) || (scan_mode == BT_SCAN_AIRTAG_MON)) { this->clearAirtags(); pBLEScan->setAdvertisedDeviceCallbacks(new bluetoothScanAllCallback(), true); } @@ -8577,6 +8597,27 @@ void WiFiScan::main(uint32_t currentTime) else if (currentScanMode == WIFI_SCAN_RDP) { this->pingScan(WIFI_SCAN_RDP); } + else if (currentScanMode == BT_SCAN_AIRTAG_MON) { + if (currentTime - initTime >= this->channel_hop_delay * 500) { + initTime = millis(); + + #ifdef HAS_SCREEN + display_obj.tft.fillRect(0, + (STATUS_BAR_WIDTH * 2) + 1 + EXT_BUTTON_WIDTH, + TFT_WIDTH, + TFT_HEIGHT - STATUS_BAR_WIDTH + 1, + TFT_BLACK); + + display_obj.tft.setCursor(0, (STATUS_BAR_WIDTH * 2) + CHAR_WIDTH + EXT_BUTTON_WIDTH); + display_obj.tft.setTextSize(1); + display_obj.tft.setTextColor(TFT_WHITE, TFT_BLACK); + + for (int y = 0; y < airtags->size(); y++) { + display_obj.tft.println((String)airtags->get(y).rssi + ": " + airtags->get(y).mac); + } + #endif + } + } else if (currentScanMode == WIFI_SCAN_SIG_STREN) { #ifdef HAS_ILI9341 this->signalAnalyzerLoop(currentTime); diff --git a/esp32_marauder/WiFiScan.h b/esp32_marauder/WiFiScan.h index 53049b8..8748e01 100644 --- a/esp32_marauder/WiFiScan.h +++ b/esp32_marauder/WiFiScan.h @@ -136,6 +136,7 @@ #define WIFI_SCAN_SMTP 67 #define WIFI_SCAN_RDP 68 #define WIFI_HOSTSPOT 69 // Nice +#define BT_SCAN_AIRTAG_MON 70 #define WIFI_ATTACK_FUNNY_BEACON 99 @@ -216,6 +217,7 @@ struct AirTag { std::vector payload; // Payload data uint16_t payloadSize; bool selected; + int8_t rssi; }; struct Flipper {