Skip to content

Commit 4263116

Browse files
chore: merge PR BruceDevices#2823 [skip ci]
2 parents 26dcb89 + 5aace77 commit 4263116

13 files changed

Lines changed: 6164 additions & 578 deletions

src/modules/ble/BLE_Suite.cpp

Lines changed: 1544 additions & 271 deletions
Large diffs are not rendered by default.

src/modules/ble/BLE_Suite.h

Lines changed: 237 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
/*
2+
* BLE Suite v4.0 - Complete BLE attack and analysis toolkit
3+
* Author: Ninja-jr
4+
* Version: 4.0
5+
* Last Updated: 07/09/2026
6+
*
7+
* Contains: Smart device recon, connection caching, graduated connection
8+
* strategies, robust GATT client, device fingerprinting,
9+
* attack orchestration with rollback, BLE mirage/spoofing,
10+
* attack scheduler, attack logging with JSON export,
11+
* vulnerability scanning, HID attacks, FastPair exploits,
12+
* HFP attacks, Audio attacks, DuckyScript injection,
13+
* BLE Sniffer, Samsung detection, and expanded model database.
14+
*/
115
#ifndef BLE_SUITE_H
216
#define BLE_SUITE_H
317
#if !defined(LITE_VERSION)
@@ -14,6 +28,7 @@
1428
#include <freertos/semphr.h>
1529
#include <functional>
1630
#include <vector>
31+
#include <map>
1732

1833
extern volatile int tftWidth;
1934
extern volatile int tftHeight;
@@ -28,10 +43,10 @@ bool check(int key);
2843
// BLE Scan Constants
2944
//=============================================================================
3045

31-
#define ACTIVE_SCAN_TIME 8
46+
#define ACTIVE_SCAN_TIME 10
3247
#define PASSIVE_SCAN_TIME 8
33-
#define SCAN_INT 100
34-
#define SCAN_WINDOW 99
48+
49+
// SCAN_INT and SCAN_WINDOW are defined in ble_common.h
3550

3651
//=============================================================================
3752
// Enums
@@ -50,12 +65,24 @@ enum FastPairExploitType {
5065
FP_EXPLOIT_ALL
5166
};
5267

68+
enum ConnectionPhase {
69+
CONN_PROBE,
70+
CONN_FAST,
71+
CONN_AGGRESSIVE,
72+
CONN_EXPLOIT,
73+
CONN_RECONNECT
74+
};
75+
76+
// FastPair version is defined in fastpair_crypto.h
77+
typedef FastPairProtocolVersion FastPairVersion;
78+
5379
//=============================================================================
5480
// DeviceInfo and DeviceSnapshot structures
5581
//=============================================================================
5682

5783
struct DeviceInfo {
5884
String address;
85+
uint8_t addressType = BLE_ADDR_PUBLIC;
5986
String name;
6087
int rssi;
6188
bool hasFastPair;
@@ -69,6 +96,7 @@ struct DeviceSnapshot {
6996
uint32_t timestamp;
7097
std::vector<String> names;
7198
std::vector<String> addresses;
99+
std::vector<uint8_t> addressTypes;
72100
std::vector<int> rssi;
73101
std::vector<bool> fastPair;
74102
std::vector<bool> hfp;
@@ -77,12 +105,89 @@ struct DeviceSnapshot {
77105
DeviceSnapshot() : version(0), count(0), timestamp(0) {}
78106
};
79107

108+
//=============================================================================
109+
// Device Scoring and Caching Structures
110+
//=============================================================================
111+
112+
struct DeviceScore {
113+
int rssi;
114+
int stability;
115+
uint32_t lastSeen;
116+
float rssiVariance;
117+
int attackPotential;
118+
};
119+
120+
struct CachedConnection {
121+
String address;
122+
std::vector<String> serviceUUIDs;
123+
std::vector<String> characteristicUUIDs;
124+
uint16_t mtuSize;
125+
uint32_t lastConnected;
126+
uint8_t connectionAttempts;
127+
bool isBonded;
128+
uint32_t averageResponseTime;
129+
uint16_t preferredParams[4];
130+
};
131+
132+
struct ConnectionResult {
133+
bool success;
134+
ConnectionPhase phase;
135+
String method;
136+
uint32_t durationMs;
137+
uint32_t connectionId;
138+
String errorMessage;
139+
uint8_t quality;
140+
};
141+
142+
struct DevicePersonality {
143+
String address;
144+
uint32_t responseTime;
145+
uint8_t mtuPreference;
146+
bool supportsNotifications;
147+
bool supportsIndications;
148+
std::vector<String> characteristicOrder;
149+
uint32_t appearance;
150+
uint8_t addressType;
151+
uint32_t firstSeen;
152+
uint32_t lastSeen;
153+
uint32_t seenCount;
154+
};
155+
156+
struct AttackStep {
157+
String name;
158+
bool (*execute)(NimBLEAddress);
159+
bool (*canRevert)(NimBLEAddress);
160+
bool (*revert)(NimBLEAddress);
161+
int priority;
162+
uint32_t timeoutMs;
163+
};
164+
165+
struct AttackResult {
166+
bool success;
167+
String attackName;
168+
uint32_t durationMs;
169+
String failureReason;
170+
std::vector<String> diagnostics;
171+
uint8_t connectionQuality;
172+
};
173+
174+
struct AttackLogEntry {
175+
uint32_t timestamp;
176+
String target;
177+
String attackType;
178+
bool success;
179+
String details;
180+
uint32_t durationMs;
181+
uint8_t connectionQuality;
182+
};
183+
80184
//=============================================================================
81185
// SelectedDevice for passing device info to attacks
82186
//=============================================================================
83187

84188
struct SelectedDevice {
85189
String address;
190+
uint8_t addressType = BLE_ADDR_PUBLIC;
86191
String name;
87192
int rssi;
88193
bool hasFastPair;
@@ -97,6 +202,7 @@ struct SelectedDevice {
97202
struct ScannerData {
98203
std::vector<String> deviceNames;
99204
std::vector<String> deviceAddresses;
205+
std::vector<uint8_t> deviceAddressTypes;
100206
std::vector<int> deviceRssi;
101207
std::vector<bool> deviceFastPair;
102208
std::vector<bool> deviceHasHFP;
@@ -111,7 +217,7 @@ struct ScannerData {
111217
ScannerData();
112218
~ScannerData();
113219
void
114-
addDevice(const String &name, const String &address, int rssi, bool fastPair, bool hasHFP, uint8_t type);
220+
addDevice(const String &name, const String &address, int rssi, bool fastPair, bool hasHFP, uint8_t type, uint8_t addrType = BLE_ADDR_PUBLIC);
115221
void clear();
116222
size_t size();
117223
DeviceSnapshot *getSnapshot();
@@ -128,9 +234,12 @@ struct CharacteristicInfo {
128234
struct DeviceProfile {
129235
String address;
130236
bool connected;
237+
int errorCode = 0;
238+
String errorReason = "";
131239
bool hasFastPair;
132240
bool hasAVRCP;
133241
bool hasHID;
242+
bool hasHFP;
134243
bool hasBattery;
135244
bool hasDeviceInfo;
136245
std::vector<String> services;
@@ -214,12 +323,28 @@ class BLEStateManager {
214323

215324
class BLEAttackManager {
216325
public:
217-
void prepareForConnection();
326+
void prepareForConnection(bool enableAuth = false);
218327
void cleanupAfterAttack();
219-
bool connectToDevice(NimBLEAddress target, NimBLEClient **outClient, bool useExploitHandshake = false);
328+
bool connectToDevice(NimBLEAddress target, NimBLEClient **outClient, bool useExploitHandshake = false, int *outError = nullptr);
220329
DeviceProfile profileDevice(NimBLEAddress target);
221330
};
222331

332+
//=============================================================================
333+
// Robust GATT Client Class
334+
//=============================================================================
335+
336+
class RobustGATTClient {
337+
public:
338+
bool writeCharacteristic(NimBLERemoteCharacteristic *ch,
339+
uint8_t *data,
340+
size_t len,
341+
bool response = true,
342+
int retries = 2);
343+
std::string readCharacteristic(NimBLERemoteCharacteristic *ch, int retries = 2);
344+
bool discoverServicesWithRetry(NimBLEClient *client, int maxRetries = 2);
345+
bool waitForNotification(NimBLERemoteCharacteristic *ch, uint32_t timeoutMs = 1000);
346+
};
347+
223348
//=============================================================================
224349
// FastPair Structures and Functions
225350
//=============================================================================
@@ -240,15 +365,13 @@ struct FastPairModelInfo {
240365
const char *deviceType;
241366
};
242367

243-
// v3.1: Samsung MAC OUI detection
368+
extern const FastPairModelInfo fastpair_models[];
369+
244370
extern const char *SAMSUNG_MAC_OUIS[];
245371
extern const int SAMSUNG_MAC_OUIS_COUNT;
246372
bool isSamsungDevice(const NimBLEAddress &address);
247373
bool isSamsungDevice(const String &mac);
248374

249-
// v3.1: FastPair version detection
250-
enum FastPairVersion { FP_VERSION_UNKNOWN = 0, FP_VERSION_1, FP_VERSION_2, FP_VERSION_3 };
251-
252375
FastPairVersion detectFastPairVersion(NimBLEAddress target);
253376

254377
//=============================================================================
@@ -488,6 +611,58 @@ class DoSAttackServiceClass {
488611
bool advertisingSpam(NimBLEAddress target);
489612
};
490613

614+
//=============================================================================
615+
// Attack Orchestrator Class
616+
//=============================================================================
617+
618+
class AttackOrchestrator {
619+
private:
620+
std::vector<AttackStep> steps;
621+
std::vector<AttackResult> results;
622+
String currentTarget;
623+
624+
public:
625+
AttackOrchestrator();
626+
void addStep(const AttackStep &step);
627+
bool executeChain(NimBLEAddress target);
628+
bool executeChainWithRollback(NimBLEAddress target);
629+
std::vector<AttackResult> getResults();
630+
void clearSteps();
631+
bool canRevertChain();
632+
bool revertChain();
633+
};
634+
635+
//=============================================================================
636+
// BLE Mirage Class
637+
//=============================================================================
638+
639+
class BLEMirage {
640+
private:
641+
struct MirageInstance {
642+
String address;
643+
String name;
644+
String originalName;
645+
uint32_t modelId;
646+
uint32_t startTime;
647+
bool active;
648+
NimBLEAdvertising *advertising;
649+
};
650+
std::vector<MirageInstance> instances;
651+
std::map<String, String> knownDeviceNames;
652+
653+
String generatePlausibleName(const String &address);
654+
655+
public:
656+
BLEMirage();
657+
~BLEMirage();
658+
bool spawnMirage(const String &targetAddress, const String &targetName);
659+
void createMirageNetwork(int count);
660+
void stopMirage(const String &address);
661+
void stopAll();
662+
bool isMirageActive(const String &address);
663+
void updateKnownName(const String &address, const String &name);
664+
};
665+
491666
//=============================================================================
492667
// Debug Memory Macros
493668
//=============================================================================
@@ -520,12 +695,62 @@ class HeapMonitor {
520695
#define MEM_CHECK()
521696
#endif
522697

698+
//=============================================================================
699+
// Connection Management Functions
700+
//=============================================================================
701+
702+
ConnectionResult graduatedConnect(NimBLEAddress target);
703+
bool hasCachedConnection(NimBLEAddress target);
704+
bool reconnectCached(NimBLEAddress target);
705+
CachedConnection *getCachedConnection(const String &address);
706+
void cacheDeviceProfile(const String &addr, NimBLEClient *client);
707+
void setOptimalParams(NimBLEClient *client, const String &deviceType);
708+
int calculateDeviceScore(const String &addr);
709+
uint32_t getDeviceScore(const String &addr);
710+
711+
//=============================================================================
712+
// Attack Logging Functions
713+
//=============================================================================
714+
715+
void logAttackResult(const AttackLogEntry &entry);
716+
bool exportAttackLog();
717+
std::vector<AttackLogEntry> getAttackLog();
718+
void clearAttackLog();
719+
720+
//=============================================================================
721+
// UI Extension Functions
722+
//=============================================================================
723+
724+
void drawAttackFlow(const String &title, const String &status, int progress);
725+
void showDevicePersonalityScreen(const DevicePersonality &personality);
726+
void showAttackLogScreen();
727+
728+
//=============================================================================
729+
// New Attack Functions
730+
//=============================================================================
731+
732+
void runSmartRecon(NimBLEAddress target);
733+
void runOrchestratedAttack(NimBLEAddress target);
734+
void runMirageAttack(NimBLEAddress target);
735+
void runDeviceFingerprinting(NimBLEAddress target);
736+
void runAttackScheduler(NimBLEAddress target);
737+
738+
//=============================================================================
739+
// Device Name Resolution
740+
//=============================================================================
741+
742+
String resolveBleDeviceName(const NimBLEAdvertisedDevice* device);
743+
523744
//=============================================================================
524745
// Function Declarations
525746
//=============================================================================
526747

527748
void cleanupBLEStack();
528749

750+
extern int g_lastBleError;
751+
extern int g_lastBleDisconnectReason;
752+
String getBleErrorDescription(int reason);
753+
529754
NimBLEClient *attemptConnectionWithStrategies(NimBLEAddress target, String &connectionMethod);
530755
void BleSuiteMenu();
531756
void showAttackMenuWithTarget(NimBLEAddress target);
@@ -580,10 +805,11 @@ void executeAudioTest(int testIndex, NimBLEAddress target);
580805
void showAttackProgress(const char *message, uint16_t color = bruceConfig.priColor);
581806
void showAttackResult(bool success, const char *message = nullptr);
582807
bool confirmAttack(const char *targetName);
808+
bool performBleScan(const char *title = "SELECT TARGET");
583809
String selectTargetFromScan(const char *title);
584810
String selectMultipleTargetsFromScan(const char *title, std::vector<NimBLEAddress> &targets);
585811
String getScriptFromUser();
586-
NimBLEAddress parseAddress(const String &addressInfo);
812+
NimBLEAddress parseAddress(const String &addressInfo, uint8_t defaultType = 0xFF);
587813
bool requireSimpleConfirmation(const char *message);
588814
int8_t showAdaptiveMessage(
589815
const char *line1, const char *btn1, const char *btn2, const char *btn3, uint16_t color,

0 commit comments

Comments
 (0)