Skip to content

Commit 58d9664

Browse files
authored
Ble suite (#2147)
* Update platformio.ini * Update BleMenu.cpp * Create nrf_jammer_api.h * Create nrf_jammer_api.cpp * Create BLE_Suite.h * Create fastpair_crypto.h * Create fastpair_crypto.cpp * Create BLE_Suite.cpp * Create README.md * Enhance README with detailed BLE Suite information Expanded the README.md to provide detailed information about the BLE Suite module, including attack capabilities, hardware integration, and expected outcomes based on device configurations. * Update BLE_Suite.cpp * Update README.md * Create HFP_Exploit.h * Create HFP_Exploit.cpp * Update BLE_Suite.h * Refactor ScannerData structure and add HFP handling * Update HFP_Exploit.h * Refactor runUniversalAttack and HFP connection Refactor universal attack logic and improve HFP connection method. * Refactor HFP connection handling and update display text * Update BLE_Suite.cpp * Update text to include version number in BLE Suite * Update display text to include version number * Update BLE_Suite.cpp * Update BLE_Suite.h * Update cleanupAllClients call to use BLEStateManager * Remove unused classes and memory debug macros Removed AutoCleanup, BLEStateManager, and HeapMonitor classes along with related memory debugging macros. * Update print statement * Update * Add AutoCleanup class and memory monitoring features * Refactor BLE state management and cleanup process * Fix cleanup method call to use 'this' pointer * Update BLE_Suite.cpp * Refactor README.md for improved clarity and structure Updated README.md to enhance clarity and organization of BLE Suite features, attack capabilities, and recent additions. * Update BLE_Suite.cpp * Refactor BLE_Suite.cpp by removing unused preprocessor directive Remove conditional compilation for NimBLEExtAdvertising.h. * Simplify BLE scanning logic by removing preprocessor directives Removed preprocessor directives for NIMBLE_V2_PLUS in BLE_Suite.cpp to simplify scanning logic. * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Refactor BLE scanning to use cache and improve mutex handling Refactor BLE scanning logic to use a cache structure for scan results and replace mutex handling for thread safety. * Update BLE_Suite.h * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.h * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.h * Update BLE_Suite.cpp * Update BLE_Suite.h * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update README.md * Update BLE_Suite.cpp * Update README.md * Update BLE_Suite.cpp * Update BLE_Suite.h * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp * Update BLE_Suite.cpp
1 parent f8681ff commit 58d9664

11 files changed

Lines changed: 6533 additions & 48 deletions

File tree

platformio.ini

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,17 @@ build_flags =
134134
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1 ;
135135
-DCONFIG_ASYNC_TCP_USE_WDT=0 ; Disables the Watchdog timer on Async TCP, to avoid restartings during file uploads
136136
-DGEN_MQJS_HEADERS ; Enable generation of mquickjs headers
137+
; mbedtls settings for crypto operations (WhisperPair/audio exploits)
138+
-DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"
139+
-DCONFIG_MBEDTLS_ECDH_C=1
140+
-DCONFIG_MBEDTLS_AES_C=1
141+
-DCONFIG_MBEDTLS_CTR_DRBG_C=1
142+
; Additional mbedtls flags that could be useful:
143+
;-DCONFIG_MBEDTLS_ECP_C=1
144+
;-DCONFIG_MBEDTLS_SHA256_C=1
145+
;-DCONFIG_MBEDTLS_SHA512_C=1
146+
;-DCONFIG_MBEDTLS_HKDF_C=1
147+
;-DCONFIG_MBEDTLS_GCM_C=1
137148

138149
extra_scripts =
139150
pre:patch.py
@@ -249,4 +260,4 @@ lib_deps =
249260
;bitbank2/AnimatedGIF
250261
;bitbank2/PNGdec @ ^1.1.2
251262
ESP32Async/ESPAsyncWebServer
252-
;https://github.com/bmorcelli/FastLED
263+
;https://github.com/bmorcelli/FastLED

src/core/menu_items/BleMenu.cpp

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#include "BleMenu.h"
22
#include "core/display.h"
3-
#include "core/mykeyboard.h"
43
#include "core/utils.h"
54
#include "modules/badusb_ble/ducky_typer.h"
65
#include "modules/ble/ble_common.h"
76
#include "modules/ble/ble_ninebot.h"
87
#include "modules/ble/ble_spam.h"
8+
#if !defined(LITE_VERSION)
9+
#include "modules/ble/BLE_Suite.h"
10+
#endif
911
#include <globals.h>
1012

1113
void BleMenu::optionsMenu() {
@@ -14,42 +16,37 @@ void BleMenu::optionsMenu() {
1416
if (BLEConnected) {
1517
options.push_back({"Disconnect", [=]() {
1618
#if defined(CONFIG_IDF_TARGET_ESP32C5)
17-
esp_bt_controller_deinit();
19+
esp_bt_controller_deinit();
1820
#else
19-
BLEDevice::deinit();
21+
BLEDevice::deinit();
2022
#endif
21-
BLEConnected = false;
22-
delete hid_ble;
23-
hid_ble = nullptr;
24-
if (_Ask_for_restart == 1) _Ask_for_restart = 2;
25-
}});
23+
BLEConnected = false;
24+
delete hid_ble;
25+
hid_ble = nullptr;
26+
if (_Ask_for_restart == 1)
27+
_Ask_for_restart = 2;
28+
}});
2629
}
2730

2831
options.push_back({"Media Cmds", [=]() { MediaCommands(hid_ble, true); }});
2932
#if !defined(LITE_VERSION)
30-
options.push_back({"Presenter", [=]() { PresenterMode(hid_ble, true); }});
3133
options.push_back({"BLE Scan", ble_scan});
3234
options.push_back({"iBeacon", [=]() { ibeacon(); }});
3335
options.push_back({"Bad BLE", [=]() { ducky_setup(hid_ble, true); }});
34-
options.push_back({"BLE Keyboard", [=]() { ducky_keyboard(hid_ble, true); }});
3536
#endif
37+
options.push_back({"BLE Keyboard", [=]() { ducky_keyboard(hid_ble, true); }});
3638
options.push_back({"BLE Spam", [=]() { spamMenu(); }});
39+
40+
#if !defined(LITE_VERSION)
41+
options.push_back({"BLE Suite", [=]() { BleSuiteMenu(); }});
42+
#endif
43+
3744
#if !defined(LITE_VERSION)
3845
options.push_back({"Ninebot", [=]() { BLENinebot(); }});
3946
#endif
40-
options.push_back({"Config", [this]() { configMenu(); }});
4147
addOptionToMainMenu();
4248

43-
loopOptions(options, MENU_TYPE_SUBMENU, "Bluetooth");
44-
}
45-
46-
void BleMenu::configMenu() {
47-
options = {
48-
{"BLE Name", [this]() { setBleNameMenu(); }},
49-
{"Back", [this]() { optionsMenu(); } },
50-
};
51-
52-
loopOptions(options, MENU_TYPE_SUBMENU, "BLE Config");
49+
loopOptions(options, MENU_TYPE_SUBMENU, "Bluetooth", 0, false);
5350
}
5451

5552
void BleMenu::drawIcon(float scale) {
@@ -141,29 +138,4 @@ void BleMenu::drawIcon(float scale) {
141138
bruceConfig.priColor,
142139
bruceConfig.bgColor
143140
);
144-
}
145-
146-
/*********************************************************************
147-
** Function: setBleNameMenu
148-
** Handles Menu to set BLE Gap Name
149-
**********************************************************************/
150-
void BleMenu::setBleNameMenu() {
151-
const String defaultBleName = "Keyboard_" + String((uint8_t)(ESP.getEfuseMac() >> 32), HEX);
152-
153-
const bool isDefault = bruceConfigPins.bleName == defaultBleName;
154-
155-
options = {
156-
{"Default", [=]() { bruceConfigPins.setBleName(defaultBleName); }, isDefault },
157-
{"Custom",
158-
[=]() {
159-
String newBleName = keyboard(bruceConfigPins.bleName, 30, "BLE Device Name:");
160-
if (newBleName != "\x1B") {
161-
if (!newBleName.isEmpty()) bruceConfigPins.setBleName(newBleName);
162-
else displayError("BLE Name cannot be empty", true);
163-
}
164-
}, !isDefault},
165-
};
166-
addOptionToMainMenu();
167-
168-
loopOptions(options, isDefault ? 0 : 1);
169-
}
141+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#include "nrf_jammer_api.h"
2+
#include "nrf_jammer.h"
3+
#include "core/display.h"
4+
#include "modules/ble/BLE_Suite.h"
5+
#include <RF24.h>
6+
#include <freertos/FreeRTOS.h>
7+
#include <freertos/task.h>
8+
9+
static bool nrf24Initialized = false;
10+
static bool bleJammingActive = false;
11+
static BLEJamMode currentMode = BLE_JAM_ADV_CHANNELS;
12+
static rf24_pa_dbm_e currentPowerLevel = RF24_PA_MAX;
13+
static unsigned long lastChannelHop = 0;
14+
static int currentChannelIndex = 0;
15+
static int targetChannel = 0;
16+
static bool isHopping = false;
17+
static unsigned long jamStartTime = 0;
18+
19+
static byte bleAdvertisingChannels[] = {37, 38, 39};
20+
static byte bleDataChannels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
21+
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36};
22+
23+
bool isNRF24Available() {
24+
if (!nrf24Initialized) {
25+
NRF24_MODE mode = nrf_setMode();
26+
if (nrf_start(mode)) {
27+
if (CHECK_NRF_SPI(mode)) {
28+
NRFradio.setPALevel(RF24_PA_MAX);
29+
NRFradio.setAddressWidth(3);
30+
NRFradio.setPayloadSize(2);
31+
NRFradio.setDataRate(RF24_2MBPS);
32+
}
33+
nrf24Initialized = true;
34+
}
35+
}
36+
return nrf24Initialized;
37+
}
38+
39+
bool startBLEJammer(BLEJamMode mode, int param) {
40+
if (!isNRF24Available()) return false;
41+
currentMode = mode;
42+
NRF24_MODE nrfMode = nrf_setMode();
43+
if (!CHECK_NRF_SPI(nrfMode)) return false;
44+
45+
switch(mode) {
46+
case BLE_JAM_ADV_CHANNELS:
47+
NRFradio.startConstCarrier(currentPowerLevel, bleAdvertisingChannels[0]);
48+
isHopping = false;
49+
break;
50+
case BLE_JAM_ALL_CHANNELS:
51+
NRFradio.startConstCarrier(currentPowerLevel, 0);
52+
isHopping = false;
53+
break;
54+
case BLE_JAM_TARGET_CHANNEL:
55+
if (param >= 0 && param <= 39) {
56+
targetChannel = param;
57+
NRFradio.startConstCarrier(currentPowerLevel, targetChannel);
58+
isHopping = false;
59+
}
60+
break;
61+
case BLE_JAM_HOP_ADV:
62+
NRFradio.startConstCarrier(currentPowerLevel, bleAdvertisingChannels[0]);
63+
isHopping = true;
64+
currentChannelIndex = 0;
65+
break;
66+
case BLE_JAM_HOP_ALL:
67+
NRFradio.startConstCarrier(currentPowerLevel, 0);
68+
isHopping = true;
69+
currentChannelIndex = 0;
70+
break;
71+
case BLE_JAM_CONNECT_ATTACK:
72+
isHopping = false;
73+
jamStartTime = millis();
74+
break;
75+
}
76+
77+
bleJammingActive = true;
78+
jamStartTime = millis();
79+
return true;
80+
}
81+
82+
void updateBLEJammer() {
83+
if (!bleJammingActive) return;
84+
if (isHopping && (millis() - lastChannelHop > 100)) {
85+
byte* channels = NULL;
86+
int channelCount = 0;
87+
if (currentMode == BLE_JAM_HOP_ADV) {
88+
channels = bleAdvertisingChannels;
89+
channelCount = 3;
90+
} else if (currentMode == BLE_JAM_HOP_ALL) {
91+
if (currentChannelIndex < 36) {
92+
channels = bleDataChannels;
93+
channelCount = 36;
94+
} else {
95+
channels = bleAdvertisingChannels;
96+
channelCount = 3;
97+
}
98+
}
99+
if (channels && channelCount > 0) {
100+
currentChannelIndex = (currentChannelIndex + 1) % channelCount;
101+
NRFradio.setChannel(channels[currentChannelIndex]);
102+
lastChannelHop = millis();
103+
}
104+
}
105+
}
106+
107+
void stopBLEJammer() {
108+
if (!bleJammingActive) return;
109+
NRF24_MODE mode = nrf_setMode();
110+
if (CHECK_NRF_SPI(mode)) NRFradio.stopConstCarrier();
111+
bleJammingActive = false;
112+
isHopping = false;
113+
currentChannelIndex = 0;
114+
}
115+
116+
bool isBLEJammingActive() {
117+
return bleJammingActive;
118+
}
119+
120+
int getCurrentBLEChannel() {
121+
if (!bleJammingActive) return -1;
122+
if (currentMode == BLE_JAM_TARGET_CHANNEL) return targetChannel;
123+
if (isHopping) {
124+
if (currentMode == BLE_JAM_HOP_ADV && currentChannelIndex < 3) {
125+
return bleAdvertisingChannels[currentChannelIndex];
126+
} else if (currentMode == BLE_JAM_HOP_ALL) {
127+
if (currentChannelIndex < 36) {
128+
return bleDataChannels[currentChannelIndex];
129+
} else {
130+
return bleAdvertisingChannels[currentChannelIndex - 36];
131+
}
132+
}
133+
}
134+
return -1;
135+
}
136+
137+
void setBLEJammingPower(int powerLevel) {
138+
rf24_pa_dbm_e paLevel = RF24_PA_MIN;
139+
if (powerLevel == 0) paLevel = RF24_PA_MIN;
140+
else if (powerLevel == 1) paLevel = RF24_PA_LOW;
141+
else if (powerLevel == 2) paLevel = RF24_PA_HIGH;
142+
else if (powerLevel == 3) paLevel = RF24_PA_MAX;
143+
else return;
144+
145+
currentPowerLevel = paLevel;
146+
if (bleJammingActive) {
147+
stopBLEJammer();
148+
startBLEJammer(currentMode, targetChannel);
149+
}
150+
}
151+
152+
bool jamBLEChannel(int channel) {
153+
if (channel < 0 || channel > 39) return false;
154+
return startBLEJammer(BLE_JAM_TARGET_CHANNEL, channel);
155+
}
156+
157+
bool jamBLEAdvertisingChannels() {
158+
return startBLEJammer(BLE_JAM_ADV_CHANNELS);
159+
}
160+
161+
bool jamBLEConnectionChannel(NimBLEAddress target) {
162+
return startBLEJammer(BLE_JAM_ADV_CHANNELS);
163+
}
164+
165+
bool jamDuringConnect(NimBLEAddress target) {
166+
if (!isNRF24Available()) return false;
167+
startBLEJammer(BLE_JAM_ADV_CHANNELS);
168+
String connectionMethod = "";
169+
NimBLEClient* pClient = attemptConnectionWithStrategies(target, connectionMethod);
170+
stopBLEJammer();
171+
if (pClient) {
172+
pClient->disconnect();
173+
NimBLEDevice::deleteClient(pClient);
174+
return true;
175+
}
176+
return false;
177+
}

src/modules/NRF24/nrf_jammer_api.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef NRF_JAMMER_API_H
2+
#define NRF_JAMMER_API_H
3+
4+
#include "modules/NRF24/nrf_common.h"
5+
#include <NimBLEDevice.h>
6+
7+
enum BLEJamMode {
8+
BLE_JAM_ADV_CHANNELS = 0,
9+
BLE_JAM_ALL_CHANNELS,
10+
BLE_JAM_TARGET_CHANNEL,
11+
BLE_JAM_HOP_ADV,
12+
BLE_JAM_HOP_ALL,
13+
BLE_JAM_CONNECT_ATTACK
14+
};
15+
16+
bool isNRF24Available();
17+
bool startBLEJammer(BLEJamMode mode, int param = 0);
18+
void updateBLEJammer();
19+
void stopBLEJammer();
20+
bool isBLEJammingActive();
21+
int getCurrentBLEChannel();
22+
void setBLEJammingPower(int powerLevel);
23+
bool jamBLEChannel(int channel);
24+
bool jamBLEAdvertisingChannels();
25+
bool jamBLEConnectionChannel(NimBLEAddress target);
26+
bool jamDuringConnect(NimBLEAddress target);
27+
28+
#endif

0 commit comments

Comments
 (0)