Mach IPC Security on macOS
简介
这是为数不多的关于 XNU 内核的文章之一。由于主要的 XNU 文章已经很长,我决定将 Mach 进程间通信的内容单独发布,以免读者(和我自己)感到不知所措。
Mach
任务和线程(在 BSD 层被映射为进程和线程)。任务之间通过 Mach IPC 进行通信。
Mach IPC 具有单向通信通道。
Mach IPC
它使任务(进程)能够通过端口异步交换信息。主要组件:
-
端口:内核保护的通信通道(类似管道) -
端口权限:定义与端口交互的权限(句柄) -
消息:在端口之间交换的结构化数据包 -
服务:在引导服务器中为给定端口注册的名称 -
引导服务器:服务注册和发现( launchd
)
还有 MIG(Mach 接口生成器),虽然对通信不是必需的,但它简化了编码过程并使其更安全。
Mach 的 IPC 部分:`osfmk/ipc/`[1]、`/osfmk/mach/`[2]和`osfmk/kern/`[3]。
端口
它存在于内核内存中并维护一个消息队列。它可用于发送/接收消息,具有全局唯一标识符(名称,例如0x103
)和特定的安全权限(发送/接收/单次发送)。
`/osfmk/ipc/ipc_port.h`[4]
端口权限
端口权限是端口的句柄,它授予发送(入队)或接收(出队)消息的能力(类似于文件描述符)。
`libsyscall/mach/mach_right.c`[5]
消息
通过端口流动的实际数据包。它包含头部和主体(要发送的数据)。它可以用于发送端口权限(权限委派)。
mach_msg_header_t[6]
`/osfmk/mach/message.h`[7]
头部是标准化的,而主体可以包含任何数据结构 — 这就是为什么我们有 MIG 等工具。
Mach Interface Generator
MIG 是一个自动创建正确 IPC 代码的工具。可以将 MIG 视为自动翻译器(因为手动编写 IPC 很困难/容易出错)。
`osfmk/kern/ipc_mig.h`[8]
为什么使用 MIG?
没有 MIG 的开发者需要:
-
手动将数据结构打包到消息主体中 -
确保正确的字节对齐和填充 -
处理架构差异(32 位 vs 64 位,字节序) -
管理内存分配和释放 -
处理类型转换 -
处理所有错误情况
MIG 通过隐藏底层 mach_msg 复杂性来简化 IPC 开发。这在本文的Mach IPC 编程部分的示例中有所展示。
任务特殊端口
XNU 中的某些端口是特权端口,提供对关键系统服务和功能的访问。一些端口在任务创建期间自动分配(`task_create`[9])。SIP 和授权保护大多数端口。
`xnu/osfmk/mach/task_special_ports.h`[10]
这两个端口对通信至关重要。
TASK_BOOTSTRAP_PORT
每个任务创建时都会获得的特殊端口。它提供了与launchd
通信的SEND
权限。通过这个端口,我们的进程可以:
-
使用 bootstrap_check_in
注册自己的服务 -
使用 bootstrap_look_up
获取其他服务端口的SEND
权限
// How to get the bootstrap port for our program:
mach_port_t bootstrap;
task_get_special_port(mach_task_self(),
TASK_BOOTSTRAP_PORT,
&bootstrap);
它继承自父进程,最终来自作为 PID 1 的**
launchd
**。
TASK_KERNEL_PORT
`mach_task_self`[11]返回当前任务的TASK_KERNEL_PORT
。它是我们自己任务端口的SEND
权限。我们可以用它与自己交互。
每个任务都有它。这是内核识别新子任务的端口。如果我们有对它的SEND 权限,我们就可以注入该任务。
Mach IPC 流程
我们有四个阶段(图表没有显示第 1 阶段,稍后会描述):
-
当服务器启动时,它在引导服务器中注册其端口。 -
当客户端在引导服务器中搜索服务时。 -
当客户端向服务发送消息时。 -
当客户端从服务器接收消息时。
通信可以不使用 MIG 完成,但通常会使用它。
引导阶段(端口发现)
客户端需要在通信开始前找到服务器的端口。这在**引导阶段(服务注册)**点中有描述。之后:
-
客户端使用 bootstrap_look_up
获取服务器端口的发送权限 -
内核验证并返回适当的端口权限
通信阶段(消息发送)
-
客户端的 MIG 生成代码创建消息 -
客户端调用 mach_msg_send()
发送消息 -
内核将消息复制到服务器的消息队列 -
服务器收到待处理消息的通知 -
服务器的 MIG 代码解包接收到的消息 -
服务器处理请求
通信阶段(回复)
-
处理请求后,服务器的 MIG 代码创建响应 -
服务器调用 mach_msg_send()
发送响应消息 -
内核管理消息传输 -
客户端接收并解包响应
引导阶段(服务注册)
这由launchd
管理。它允许不同进程首次相互通信。工作原理如下:
-
每个进程都可以与 launchd
(引导服务器)通信 -
进程 A 创建通信通道( 端口
)并在launchd
中以名称注册(例如com.example.service
) -
然后进程 B 可以使用该名称向 launchd
请求访问进程 A
// Process A registering
kern_return_t kr;
kr = bootstrap_check_in(bootstrap_port,
"com.example.myservice", // service name
service_port); // port to register
// Process B looking up
mach_port_t service_port;
kr = bootstrap_look_up(bootstrap_port,
"com.example.myservice", // service name
&service_port); // will receive the port
macOS 上的 Bootstrap 使用 launchd 作为中央协调器,通过让进程通过共享服务器注册和请求(查找)通信通道(端口),实现进程间的首次通信。
访问控制 — 授予端口权限
进程可以通过launchd
交换端口权限(SEND
/RECEIVE
)。
-
进程 A 创建一个具有 RECEIVE
权限的端口,生成一个SEND
权限,并在launchd
中以name
(例如com.whatever.name
)注册。 -
进程 B 可以通过 launchd
查找这个name
来获取SEND
权限,从而实现与进程 A 的直接 Mach 消息通信。
// Process A (Server)
mach_port_t server_port;
// Create port with RECEIVE right
kern_return_t kr = mach_port_allocate(
mach_task_self(), // our task
MACH_PORT_RIGHT_RECEIVE, // want receive right
&server_port // port name to create
);
// Create SEND right
mach_port_insert_right(
mach_task_self(), // our task
server_port, // port
server_port, // same port
MACH_MSG_TYPE_MAKE_SEND // convert to send right
);
// Register with launchd
bootstrap_check_in(
bootstrap_port, // launchd port
"com.example.service", // service name
server_port // port with send right
);
// Process B (Client)
mach_port_t client_port;
bootstrap_look_up(
bootstrap_port, // launchd port
"com.example.service", // service name
&client_port // receives send right
);
只有端口的 RECEIVE 权限持有者才能为该端口生成 SEND 权限。*接收者(只能有一个)控制谁可以向其发送消息。
任务安全性
默认情况下,launchd
不限制谁可以注册服务。此外,任何进程都可以查找并获取其端口的 SEND 权限。这就是为什么:
-
系统服务(位于 /System/Library/LaunchDaemons
和/System/Library/LaunchAgents
中)受 SIP 保护 -
授权保护系统服务功能 -
用户服务默认可被冒充
进程 B 始终可以通过 bootstrap_lookup 获取 SEND 权限。安全检查应该在进程 A 接收来自进程 B 的消息时进行。
系统服务保护 — Bootstrap 和 SIP
launchd
在引导阶段保护系统服务:
-
它创建并持有其名称的 RECEIVE
权限 -
当服务启动时,必须注册( bootstrap_check_in
) -
launchd
验证二进制路径是否与列表匹配(受 SIP 保护) -
如果路径有效, launchd
传输RECEIVE
权限
// System Service checkin
mach_port_t service_port;
bootstrap_check_in( // same as bootstrap_register - which is deprecated
bootstrap_port,
"com.apple.systemservice", // must match plist
&service_port // receives the RECEIVE right
);
这意味着进程无法注册系统服务名称(launchd 已经持有它们),只有合法的二进制文件才能注册并获得 RECEIVE 权限。用户只能获得 SEND 权限,且无法冒充系统服务(受 SIP 保护)。
系统服务保护 — 授权
SIP 保护服务注册过程,防止冒充。但是,这些服务中仍然有一些函数隐藏在 Mach 消息之后。
我们始终可以获得 SEND 权限并发送消息,但服务会根据我们进程拥有的授权来拒绝未经授权的请求。
Taskgated
当内核被请求获取进程的任务端口时,它会通过launchd
调用这个守护进程来做出决定。它是task_for_pid
访问控制守护进程,每个进程都可以通过`TASK_ACCESS_PORT`[12]与之通信。
# DaemonPLIST:
/System/Library/LaunchDaemons/com.apple.taskgated.plist
其逻辑中允许 task_for_pid 的漏洞对任务安全性来说是致命的。
任务注入绕过
`task_for_pid`[13]允许一个进程获取另一个进程的任务端口。然后,我们可以使用`mach_vm_allocate`[14]、`mach_vm_write`[15]、`mach_vm_protect`[16]和`thread_create_running`[17]进行注入。但是有一些规则:
-
作为 root 用户,我们可以注入到任何非 Apple 平台二进制文件(`is_platform_binary`[18])或未使用强化运行时[19]编译的应用程序中。 -
具有 com.apple.security.get-task-allow
的应用程序的任务端口可以被任何其他进程访问,但必须在相同的用户级别运行。 -
如果我们攻破了具有 com.apple.system-task-ports
的应用程序,我们就可以获取除内核之外任何进程的任务端口。
除此之外,我们还有内核任务端口(task_for_pid(0)),它受到严格限制,但如果被攻破,就能完全控制系统。
Mach IPC 编程
这里,我提供了一个简单的客户端 - 服务器 Mach IPC 通信示例,包括使用和不使用 MIG 的版本,以及使用分布式对象[20]的版本。
分布式对象、XPC 或 NSNotification 都是建立在 Mach 之上的,为低级 IPC 机制提供了更高级别的访问方式。
不使用 MIG 的客户端 - 服务器示例
只需要`client.c`[21]和`server.c`[22]。我们可以像编译普通 C 程序一样编译它:
gcc server.c -o server
gcc client.c -o client
我们可以看到,我们直接使用mach_msg
来接收消息,开发者至少在三个地方可能会出错:
server.c[23]
对于客户端来说,我们同样直接使用mach_msg
来发送消息,开发者至少在四个地方可能会出错:
client.c[24]
在客户端和服务器端都有大量代码需要维护。规范的每次改变都迫使开发者必须修改这两个文件。
使用 MIG 的客户端 - 服务器示例
我们不直接在`client.c`[25]和`server.c`[26]中编写 IPC 代码,而是在一个定义文件中声明函数和结构:
message.defs[27]
然后,我们可以使用 MIG 生成服务器和客户端代码,这些代码将能够相互通信以调用send_message
函数:
mig message.defs
# message.h - Header file with type declarations and function prototypes
# messageUser.c - Client-side IPC codeto be used by client.c
# messageServer.c - Server-side IPC codeto be used by server.c
现在,开发者只需要声明函数原型,然后使用 MIG 子系统生成的处理函数message_server
:
server.c[28]
客户端只需要一行导入 MIG 生成的例程:
client.c[29]
客户端和服务器的工作方式与之前相同:
MIG 自动编写 IPC 粘合代码,让开发者可以专注于服务器/客户端逻辑。
使用分布式对象的客户端 - 服务器示例
Objective-C 运行时支持分布式对象[30]的 IPC。
以下是使用已弃用的 API`NSConnection`[31]的示例:
client.m[32]
server.m[33]
还有`CFMessagePort`[34],虽然没有正式弃用,但与`NSConnection`[35]一样被视为遗留 API:
server.m[36]
client.m[37]
要从 Obj-C 更直接地访问 Mach 端口,我们可以使用`NSMachPort`[38]:
server.m[39]
client.m[40]
本节的目的不是教授如何编程分布式对象,而是要提醒注意有多少高级 API 是建立在 Mach IPC 之上的,还有更多例如NSDistributedNotificationCenter[41]或NSXPCConnection[42](XPC[43])。
Swift — Kass
还有一个用 Swift 编写的很酷的安全研究工具。我们也可以用它来构建客户端 - 服务器并以多种其他方式与内核交互:
Kass - Noah Gregory 编写的安全研究工具。[44]
我鼓励所有对 Mach 感兴趣的人阅读该存储库的文档,因为它远超出本文的范围,是学习 Swift 版 Mach 的绝佳入门材料。
IPC 表
每个进程都有一个由`ipc_entry`[45]条目组成的结构。每个条目将端口名称(数值)映射到内核中相应的 Mach 端口对象和关联的端口权限(如发送/接收)。
// Example entry in a process's IPC table (WindowServer is just an example, it could be any kernel port object)
struct ipc_entry {
ie_object = 0xfffff80123456789 // Points to WindowServer's port
ie_bits = 0x00010003 // Generation 1, SEND right, 3 references
ie_index = 42 // Port name base is 42
}
IPC 表最初有 32 个条目[46],当进程想要共享端口时可以增长。内核会在接收进程的 IPC 表中创建新条目,授予特定权限。条目 0 始终保留(作为空闲列表的头部)。
ie_object
这是指向内核中实际 Mach 端口对象的指针。
-
当我们使用 mach_port_allocate
创建新端口时,会创建一个新的内核端口对象,ie_object
指向它。 -
在 WindowServer
连接的条目中,ie_object
会指向允许我们的应用程序与WindowServer
通信的 Mach 端口。
对于 NULL 条目(空闲/未使用),
ie_object
会被设置为IO_NULL
。
ie_bits
这个字段将多个信息打包在一起:
如果恶意进程试图猜测端口名称,它需要同时猜测索引和正确的生成号,这使得攻击变得更加困难。
ie_index
这是端口名称/标识符号码。例如,一个端口可能有索引42
,使其名称为0x2A
。与生成号结合,完整的端口名称可能看起来像0x1002A
(生成号16
,索引42
)
当我们在调试输出中看到像 0x1003 这样的端口名称时,最后的数字(3)是索引,前面的数字(100)包含生成号。
macOS 上的 Mach IPC 侦察
在 macOS 上,每个服务都必须通过launchd
进行注册(bootstrap)才能工作,因此我们可以使用launchtl
工具进行主动侦察:
# ShowallSystem Services running:
launchctl list
launchctl print system
# Inspect user services
launchctl print user/$UID
# Oneliner to list all services
launchctl list | awk 'NR>1{print $3}'; launchctl print user/$UID | grep -Eo '(com|org).[a-zA-Z0-9._-]+.[a-zA-Z0-9._-]+'| sort -u
# Find port by its service name
sudo launchctl dumpstate | grep com_example_service
# Show process info
sudo launchctl procinfo $PID
# Resolve System Service name of the port for the PID
sudo launchctl resolveport PID PORT
# Locations
/System/Library/LaunchDaemons
/System/Library/LaunchAgents
/Library/LaunchDaemons
/Library/LaunchAgents
$HOME/Library/LaunchAgents
还有一个用于列举Mach 端口的工具lsmp
:
# Showall ports forall tasks in the server
sudo lsmp -a
# Showall ports for the given process
sudo lsmp -p $(pgrep PROCESS_NAME)
在禁用 SIP 的情况下,我们还可以使用dtrace
(和[ktrace
](https://man.freebsd.org/cgi/man.cgi?ktrace(1 "ktrace
"))):
# Tracing mach_traps in crimson_server
sudo dtrace -n 'mach_trap::: /execname == "crimson_server"/ { printf("%s %dn", execname, arg0); }'
# Show timestamps and process names whenever a Mach port is registered through the notification system
sudo dtrace -n 'notify*:::register_mach_port { printf("%Y: %s registered mach portn", walltimestamp, execname); }'
另请参阅 taskinfo 和 taskpolicy 命令。
使用 IPC 表
我们还可以使用现有的 APImach_port_space_info
、mach_task_self
和task_for_pid
来枚举给定 PID 的所有端口:
port_inspector[47]
然而,即使拥有 root 权限,我们也无法对系统服务使用 task_for_pid,这使得这个方法用处不大。使用 lsmp -p 会更好,因为它通过 com.apple.system-task-ports.read 权限被允许这样做。
正向服务查找
我们可以使用bootstrap_look_up
来检查是否有任何端口注册在给定的服务名下,并检查我们的进程对它的权限:(根据设计,我们应该总是获得 SEND 权限)
service_lookup[48]
遗憾的是,没有 API 可以从端口号 (名称) 获取服务名称。Mach IPC 系统和引导服务器只提供正向查找 (服务名称 -> 端口号),而不提供反向查找 (端口号 -> 服务名称)。
特殊任务端口权限
我们可以使用`task_get_special_port`[49] MIG 例程。我创建了一个用于枚举我们对这些端口的任务权限的工具[50]。第一个结果很有趣:
enum_special_port_rights_self.c[51]
我还制作了一个用于检查其他 PID 权限的版本,它不会抛出这个安全错误:
enum_special_port_rights_pid.c[52]
所以,
mach_task_self
给我们访问自己的TASK_KERNEL_PORT
的权限,但是试图通过task_get_special_port
再次获取它会被安全策略阻止。
逆向工程 Mach IPC
对于结构,我们可以使用开源的`osfmk/`[53] 目录:
-
IPC (进程间通信): osfmk/ipc/
-
线程和任务管理: osfmk/kern/
-
虚拟内存管理: osfmk/vm/
-
底层硬件抽象: osfmk/arm/
另请参阅 Mach API 集合[54] 和 Mach 枚举。[55]
调试
我们感兴趣的断点是mach_msg
和mach_msg_overwrite
,因为它们用于发送和接收消息:
br set -n mach_msg
br set -n mach_msg_overwrite # For MIG
例如,当调试我们简单的客户端 - 服务器示例[56]时,我们可以在命中断点后立即看到栈上的内容:
然而,我们可以做得更好,通过基于适当的 Objective-C 类型而不是硬编码偏移量来导航消息内存布局:
# Import Foundation and use Objc++
expr -l objc++ -O -- @import Foundation
# Cast the x0 to a Mach message header
p *(mach_msg_header_t *)$x0
# Skip over the mach_msg_header_t (+1) and cast message content to char
p (char *)((mach_msg_header_t *)$x0 + 1)
同样,我们可以为使用 MIG 的客户端 - 服务器示例[57]设置断点,但这次我们需要使用mach_msg_overwrite
,因为mach_msg
不会被命中:
使用之前的技巧,我们可以解析 Mach 消息头部,但这对内容不起作用。我们还可以观察到使用的 MIG 子系统 ID:
MIG 消息不像我们之前的示例那样是简单的文本 — 它们是 RPC 数据。在我们可以将其转换为消息结构之前,我们需要理解它。
调试 MIG
该结构由 MIG 生成,但大多数情况下,我们没有源代码。然而,我们可以使用msgh_id
来找到它实现的例程:
然后,我们可以在反编译的代码中找到它,并找到处理请求的函数。如下所示,该函数接受 3 个参数:
# I hided casts on the image
SERVER_send_message(
*(unsigned int*)(a1 +12), # Firstparameteratoffset12
*(_QWORD *)(a1 +28), # Secondparameteratoffset28
*(unsigned int*)(a1 +40) # Third parameteratoffset40
);
在调试和读取消息内容时,我们需要从x0
寄存器查看这些特定的偏移量。让我们尝试读取它们:
# MIG message structure contains:
p/x *(unsigned int*)($x0 +12) # offset12: Port/ID (0xd03)
p/x *(unsigned long *)($x0 +28) # offset28: Message pointer (0x100014000)
p/x *(unsigned int*)($x0 +40) # offset40: Length (0x13)
我们还可以通过查看 MIG 子系统 400 ID 例程(函数)的实现来了解消息内容的位置:
关键是,尽管基于 Mach 的每个实现都有其特点,但我们始终可以从消息头部(mach_msg_header_t[58])结构开始逆向工程分析。
静态分析
当我们想要快速识别给定程序是否在其代码中实现了 Mach IPC 时,以下函数可以被视为Mach 特征[59]:
//===============================
// 1. Message Handling Functions
//===============================
// Core message sending/receiving
mach_msg // Primary function for sending/receivingMach messages
mach_msg_overwrite // Variant that can reuse buffer space for efficiency
mach_msg_server // Framework for handling MIG-generated message servers
_NDR_record // Network Data Representation for MIG
// Message structure manipulation
mach_msg_type_number_t // Used for managing message size and buffer lengths
mach_msg_header_t // Basic message header structure
mach_msg_trailer_t // Message trailer for security/audit information
//===============================
// 2. Service Management
//===============================
// Service registration
bootstrap_check_in // Register a service with launchd
bootstrap_register // Legacy registration method
bootstrap_look_up // Find a registered service by name
// Port management
mach_port_insert_right // Add a port right to a task
mach_port_allocate // Create new port rights
mach_port_deallocate // Clean up port rights
//===============================
// 3. Task Operations
//===============================
// Task port access
mach_task_self // Get the task port for current task
task_set_special_port // Configure special ports for a task
task_get_special_port // Retrieve special ports from a task
// Task manipulation
task_for_pid // Get task port for a process ID
pid_for_task // Get process ID for a task port
我在这篇文章中也详细描述了如何识别 MIG 子系统:
Snake&Apple VI — AMFI[60]
# Look for _NDR_record
CrimsonUroboros -p PATH_TO_BIN --mig
使用 MIG 比看起来要容易得多。我们只需要寻找子系统(msgh_id)并跟踪交叉引用到其背后的函数实现即可。
反编译
对于服务器端,大多数情况下,我们应该检查bootstrap_check_in
或bootstrap_register
,并分析随后的mach_msg
逻辑:
同样地,对于客户端,我们需要检查bootstrap_look_up
:
这是一般的逆向工程流程,但具体取决于实现方式和开发者的想象力。通常情况下,总会涉及 mach_msg 或 mach_msg_overwrite
结语
这篇文章并不算短。但仍有许多内容被省略了,比如特权端口或使用task_for_pid
进行任务注入的示例。
虽然我已经将带有注释的代码上传到了代码库[61],但 shellcode 编写和进程注入技术值得单独写一篇文章。
此外,我还没有写到同样建立在 Mach 之上的 XPC。
所有这些主题都会在未来关于进程注入和 XPC 的文章中出现。
参考资料
我没有专注于 Mach IPC 中的低级漏洞。如果你对此感兴趣,我认为可以从**Ian Beer[62]**的演讲开始:
https://youtu.be/D1jNCy7-g9k
在撰写本文时,我阅读了许多安全领域优秀专家写的关于 Mach IPC 的长短文章。以下是这些文章:
-
**Ignacio Sanmillan[63]**的Mach IPC 笔记[64] -
**Jonathan Bar Or[65]**的macOS 入门 — Mach 端口[66] -
**Robert Sesek[67]**的Mach 凭证介绍[68] -
**Noah Gregory[69]**的Kass:一个安全研究工具[70] -
**HackTricks[71]**的macOS IPC — 进程间通信[72]
对于漏洞研究,这些演讲非常出色:
-
**Ian Beer[73]**的审计和利用 Apple IPC[74] -
**Ian Beer[75]**的iOS 上的异常导向利用[76] -
**Ian Beer[77]**的在 XNU 中分裂原子[78] -
**Samuel Groß[79]**的macOS IPC 中间人攻击[80] -
**Dillon Franke[81]**的以 Mach 速度进行模糊测试[82] -
**tihmstar[83]**的XNU 堆利用:从内核漏洞到内核控制[84]
我还参考了一些苹果官方文档和其他各种手册:
-
Mach 概述[85] -
分布式对象介绍[86] -
GNU Mach 参考手册[87] -
Mach 3 内核接口[88] -
Mach 端口 — Darling 文档[89]
关于 Mach 最好的书籍:**Jonathan Levin[90]**的*OS 内部原理第二卷[91]:
另外,如果你对 MIG 感兴趣,可以阅读Snake&Apple VI — AMFI[92]
参考资料
osfmk/ipc/
:https://github.com/apple-oss-distributions/xnu/tree/main/osfmk/ipc
/osfmk/mach/
:https://github.com/apple-oss-distributions/xnu/tree/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach
osfmk/kern/
:https://github.com/apple-oss-distributions/xnu/tree/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/kern
/osfmk/ipc/ipc_port.h
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/ipc/ipc_port.h#L119
libsyscall/mach/mach_right.c
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/libsyscall/mach/mach_right.c
mach_msg_header_t:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/message.h#L596-L603
[7]/osfmk/mach/message.h
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/message.h#L653
osfmk/kern/ipc_mig.h
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/kern/ipc_mig.h#L128
task_create
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/task.defs#L100
xnu/osfmk/mach/task_special_ports.h
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/task_special_ports.h#L70-L98
mach_task_self
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/kern/ipc_tt.c#L1411-L1457
TASK_ACCESS_PORT
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/task_special_ports.h#L92
task_for_pid
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/bsd/kern/kern_proc.c#L5377
mach_vm_allocate
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/libsyscall/mach/mach_vm.c#L47
mach_vm_write
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/vm/vm_user.c#L692
mach_vm_protect
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/vm/vm_user.c#L307C1-L307C16
thread_create_running
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/kern/thread.c#L1832
is_platform_binary
:https://developer.apple.com/documentation/endpointsecurity/es_process_t/is_platform_binary?language=objc
强化运行时:https://developer.apple.com/documentation/xcode/configuring-the-hardened-runtime
[20]分布式对象:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DistrObjects/DistrObjects.html#//apple_ref/doc/uid/10000102-SW1
[21]client.c
:https://github.com/Karmaz95/Snake_Apple/blob/main/X.%20NU/custom/mach_ipc/client_server_no_mig/client.c
server.c
:https://github.com/Karmaz95/Snake_Apple/blob/main/X.%20NU/custom/mach_ipc/client_server_no_mig/server.c
server.c:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_no_mig/server.c#L26-L52
[24]client.c:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_no_mig/client.c#L43-L74
[25]client.c
:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_mig/client.c#L27
server.c
:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_mig/server.c#L37
message.defs:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_mig/message.defs#L15-L17
[28]server.c:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_mig/server.c#L37
[29]client.c:https://github.com/Karmaz95/Snake_Apple/blob/25dd6a7ef26bfeef6513705613071aa105ab9b29/X.%20NU/custom/mach_ipc/client_server_mig/client.c#L27
[30]分布式对象:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DistrObjects/DistrObjects.html#//apple_ref/doc/uid/10000102-SW1
[31]NSConnection
:https://developer.apple.com/documentation/foundation/nsconnection
client.m:https://github.com/Karmaz95/Snake_Apple/blob/5e6daa4a9259b8f548176ac5438da2e28e47b7a8/X.%20NU/custom/mach_ipc/client_server_NSConnection/client.m#L10
[33]server.m:https://github.com/Karmaz95/Snake_Apple/blob/5e6daa4a9259b8f548176ac5438da2e28e47b7a8/X.%20NU/custom/mach_ipc/client_server_NSConnection/server.m#L18
[34]CFMessagePort
:https://developer.apple.com/documentation/corefoundation/cfmessageport?language=objc
NSConnection
:https://developer.apple.com/documentation/foundation/nsconnection
server.m:https://github.com/Karmaz95/Snake_Apple/blob/043c2714f1ddd12a00fcfc64941d56bac30540c4/X.%20NU/custom/mach_ipc/client_server_CFMessagePort/server.m#L12
[37]client.m:https://github.com/Karmaz95/Snake_Apple/blob/043c2714f1ddd12a00fcfc64941d56bac30540c4/X.%20NU/custom/mach_ipc/client_server_CFMessagePort/client.m#L11
[38]NSMachPort
:https://developer.apple.com/documentation/foundation/nsmachport?language=objc
server.m:https://github.com/Karmaz95/Snake_Apple/blob/b7357068919ed395160e1d8fe68b58662a19ccc9/X.%20NU/custom/mach_ipc/client_server_NSMachPort/server.m#L25
[40]client.m:https://github.com/Karmaz95/Snake_Apple/blob/b7357068919ed395160e1d8fe68b58662a19ccc9/X.%20NU/custom/mach_ipc/client_server_NSMachPort/client.m#L13
[41]NSDistributedNotificationCenter:https://developer.apple.com/documentation/foundation/nsdistributednotificationcenter
[42]NSXPCConnection:https://developer.apple.com/documentation/foundation/nsxpcconnection?language=objc
[43]XPC:https://developer.apple.com/documentation/xpc
[44]Kass - Noah Gregory 编写的安全研究工具。:https://swiftpackageindex.com/nmggithub/Kass
[45]ipc_entry
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/ipc/ipc_entry.h#L107
最初有 32 个条目:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/ipc/ipc_entry.h#L129
[47]port_inspector:https://github.com/Karmaz95/Snake_Apple/blob/fe6dcb3b7966323ab7cce3cd0496cebfe29230eb/X.%20NU/custom/mach_ipc/port_inspector.c#L22-L28
[48]service_lookup:https://github.com/Karmaz95/Snake_Apple/blob/2b125144ea325d0572136a78d459366477158325/X.%20NU/custom/mach_ipc/service_lookup.c#L23
[49]task_get_special_port
:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/task.defs#L215
用于枚举我们对这些端口的任务权限的工具:https://github.com/Karmaz95/Snake_Apple/blob/63971e56bccc5434e1ee6867873ff2c4073d2ebb/X.%20NU/custom/mach_ipc/enum_special_port_rights.c#L56
[51]enum_special_port_rights_self.c:https://github.com/Karmaz95/Snake_Apple/blob/1e0787cef8d22fe1c27f827c1ea9c98c7e06cf2f/X.%20NU/custom/mach_ipc/enum_special_port_rights_self.c#L56
[52]enum_special_port_rights_pid.c:https://github.com/Karmaz95/Snake_Apple/blob/1e0787cef8d22fe1c27f827c1ea9c98c7e06cf2f/X.%20NU/custom/mach_ipc/enum_special_port_rights_pid.c#L68
[53]osfmk/
:https://github.com/apple-oss-distributions/xnu/tree/main/osfmk
Mach API 集合:https://developer.apple.com/documentation/kernel/mach
[55]Mach 枚举。:https://developer.apple.com/documentation/system/mach
[56]客户端 - 服务器示例:https://github.com/Karmaz95/Snake_Apple/tree/main/X.%20NU/custom/mach_ipc/client_server_no_mig
[57]使用 MIG 的客户端 - 服务器示例:https://github.com/Karmaz95/Snake_Apple/tree/main/X.%20NU/custom/mach_ipc/client_server_mig
[58]mach_msg_header_t:https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57b9f54c2f6d4a15585/osfmk/mach/message.h#L596-L603
[59]Mach 特征:https://developer.apple.com/documentation/kernel/mach
[60]Snake&Apple VI — AMFI:https://karol-mazurek.medium.com/snake-apple-vi-amfi-31c48fb92d33
[61]我已经将带有注释的代码上传到了代码库:https://github.com/Karmaz95/Snake_Apple/blob/9f195f010bb1824096b17d308676b17214d59707/X.%20NU/custom/mach_ipc/task_for_pid_inject.c#L19-L49
[62]Ian Beer:https://x.com/i41nbeer
[63]Ignacio Sanmillan:https://x.com/ulexec
[64]Mach IPC 笔记:https://ulexec.github.io/post/2022-12-01-xnu_ipc/
[65]Jonathan Bar Or:https://x.com/yo_yo_yo_jbo
[66]macOS 入门 — Mach 端口:https://github.com/yo-yo-yo-jbo/macos_mach_ports
[67]Robert Sesek:https://robert.sesek.com/
[68]Mach 凭证介绍:https://robert.sesek.com/2023/6/mach_vouchers.html
[69]Noah Gregory:https://x.com/wtsdev
[70]Kass:一个安全研究工具:https://swiftpackageindex.com/nmggithub/Kass
[71]HackTricks:https://book.hacktricks.xyz/
[72]macOS IPC — 进程间通信:https://book.hacktricks.xyz/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication#mach-messaging-via-ports
[73]Ian Beer:https://x.com/i41nbeer
[74]审计和利用 Apple IPC:https://thecyberwire.com/events/docs/IanBeer_JSS_Slides.pdf
[75]Ian Beer:https://x.com/i41nbeer
[76]iOS 上的异常导向利用:https://googleprojectzero.blogspot.com/2017/04/exception-oriented-exploitation-on-ios.html
[77]Ian Beer:https://x.com/i41nbeer
[78]在 XNU 中分裂原子:https://googleprojectzero.blogspot.com/2019/04/splitting-atoms-in-xnu.html
[79]Samuel Groß:https://x.com/5aelo
[80]macOS IPC 中间人攻击:https://saelo.github.io/presentations/poc_18_macos_ipc_mitm.pdf
[81]Dillon Franke:https://x.com/dillon_franke
[82]以 Mach 速度进行模糊测试:https://troopers.de/downloads/troopers24/TR24_FuzzingAtMachSpeed_LB9PJT.pdf
[83]tihmstar:https://x.com/tihmstar
[84]XNU 堆利用:从内核漏洞到内核控制:https://archive.nullcon.net/website/archives/pdf/goa-2020/XNU%20heap%20exploitation%3A%20From%20kernel%20bug%20to%20kernel%20control%20by%20Tihmstar.pdf
[85]Mach 概述:https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/Mach/Mach.html
[86]分布式对象介绍:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DistrObjects/DistrObjects.html
[87]GNU Mach 参考手册:https://www.gnu.org/software/hurd/gnumach-doc/mach.pdf
[88]Mach 3 内核接口:http://www.shakthimaan.com/downloads/hurd/kernel_interface.pdf
[89]Mach 端口 — Darling 文档:https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
[90]Jonathan Levin:https://twitter.com/Morpheus______
[91]*OS 内部原理第二卷:https://newosxbook.com/home.html
[92]Snake&Apple VI — AMFI:https://karol-mazurek.medium.com/snake-apple-vi-amfi-31c48fb92d33
原文始发于微信公众号(securitainment):macOS 上的 Mach IPC 安全
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论