Matheus-Garbelini / braktooth_esp32_bluetooth_classic_attacks

A Series of Baseband & LMP Exploits against Bluetooth Classic Controllers
https://braktooth.com
449 stars 85 forks source link

Firmware restarts if sending packet from rx_post_dissection(), but works if sending from tx_post_dissection() #27

Open jsmif opened 1 year ago

jsmif commented 1 year ago

Is it not allowed to send packets from within rx_post_dissection()? I didn't see any other example exploit modules that do that, and the exploit guide PDF only shows an example of sending from within rx_pre_dissection(), but I think I need to wait until post-dissection so I know I'm dealing with the LMP_name_res. And when I do a simple case of this, it seems to crash if sent from rx_post_dissection(), but work if send from tx_post_dissection()


static uint8_t packet[] = {0x99, 0x03, 0x17, 0x00,              // Baseband + ACL Header
                           0x02, 0x00};                         // LSB TID = 0 + LMP opcode (0x01) and name offset (0)

static int rx_post_dissection(uint8_t *pkt_buf, int pkt_length, void *p)
{
    if (packet_read_filter(filter_lmp_features_res))
    {
        wd_log_y("LMP_features_res RX detected");
        module_request_t *m = (module_request_t *)p;
        m->tx_count = 1;
        m->pkt_buf = packet;
        m->pkt_len = sizeof(packet);
        return 0;
    }

The below is the aborted sequence that seems like the firmware's crashing or something after the LMP_name_req is sent (or attempted to be sent):

Starting RFCOMM Query
[Baseband] TX --> FHS
[Modules] LMP_features_req TX detected
[LMP] TX --> LMP_features_req
[Modules] LMP_features_res RX detected
[LMP] RX <-- LMP_features_res
[LMP] TX --> LMP_features_req_ext
0:[LMP] TX --> LMP_name_req
[!] ESP32 Driver Startup/Restart
[ESP32BT] Discovering Serial Port
[ESP32BT] Probing /dev/ttyUSB0 at 4000000 baudrate...
[ESP32BT] No response
[ESP32BT] Probing /dev/ttyUSB1 at 4000000 baudrate...
[ESP32BT] No response
[ESP32BT] Firmware version: 1.3.0

If I instead move the packet sending to when the LMP_features_req is sent, rather than when the LMP_features_rsp is received, it works fine. But that's still problematic, because for a LMP_name_req, it'd make the most sense to send the next req after the res is processed, to determine if the next one's even needed or not. I can probably work around this by setting a global flag or something and keeping the send in the tx callback, but I'm just wondering if I'm doing something obviously wrong which is why it's not possible to send from the rx, or whether it's just not supported. Thanks in advance.


This is just a curiosity thing, but what's the difference between returning 0 vs. 1 in the callbacks?

And where can I find the BDADDR that was connected to (from within an exploit module), so I can add it to logs or output different logs per BDADDR?