macOS xpc_connection_get_audit_token Attack
有关更多信息,请查看原始帖子: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/。这是一个摘要:
Mach 消息基本信息
如果您不知道 Mach 消息是什么,请查看此页面:
pagemacOS IPC - Inter Process Communication目前记住(定义来自此处): Mach 消息通过 mach 端口 发送,这是内置在 mach 内核中的单接收器,多发送器通信通道。多个进程可以向 mach 端口发送消息,但在任何时候只有一个进程可以从中读取。就像文件描述符和套接字一样,mach 端口由内核分配和管理,进程只看到一个整数,它们可以用来指示内核它们想要使用哪个 mach 端口。
XPC 连接
如果您不知道如何建立 XPC 连接,请查看:
pagemacOS XPC漏洞摘要
您需要知道的有趣信息是XPC 的抽象是一对一连接,但它是基于一个可以有多个发送器的技术,因此:
Mach 端口是单接收器,多发送器。
XPC 连接的审计令牌是从最近接收的消息中复制的审计令牌。
获取 XPC 连接的审计令牌对许多安全检查至关重要。
尽管前述情况听起来很有前途,但在某些情况下,这不会引起问题(来自此处):
审计令牌通常用于授权检查,以决定是否接受连接。由于这是使用消息发送到服务端口进行的,尚未建立连接。在此端口上的更多消息将只被处理为附加的连接请求。因此,在接受连接之前的任何检查都不会有漏洞(这也意味着在
-listener:shouldAcceptNewConnection:
中审计令牌是安全的)。因此,我们正在寻找验证特定操作的 XPC 连接。XPC 事件处理程序是同步处理的。这意味着一个消息的事件处理程序必须在调用下一个消息的事件处理程序之前完成,即使在并发调度队列上也是如此。因此,在XPC 事件处理程序内部,审计令牌不能被其他正常(非回复!)消息覆盖。
这可能会利用两种不同的方法:
变体1:
利用连接到服务 A 和服务 B
服务 B 可以调用服务 A 中用户无法执行的特权功能
服务 A 在不在
dispatch_async
的事件处理程序中调用xpc_connection_get_audit_token
。因此,不同的消息可能会覆盖审计令牌,因为它是在事件处理程序之外异步调度的。
攻击将服务 A 的 SEND 权限传递给服务 B。
因此,svc B 实际上将消息发送到服务 A。
利用尝试调用 特权操作。在 RC svc A 检查此操作的授权,而svc B 覆盖了审计令牌(使攻击可以调用特权操作)。
变体 2:
服务 B 可以调用服务 A 中用户无法执行的特权功能
利用与服务 A建立连接,发送期望响应的消息到特定回复端口。
利用向服务 B发送消息,传递该回复端口。
当服务 B 回复时,它将消息发送到服务 A,同时利用发送不同的消息到服务 A,尝试访问特权功能并期望服务 B 的回复将在完美时机覆盖审计令牌(竞争条件)。
变体 1:在事件处理程序之外调用 xpc_connection_get_audit_token
场景:
两个 mach 服务
A
和B
,我们都可以连接到(基于沙箱配置文件和接受连接前的授权检查)。A 必须对**
B
可以通过的特定操作进行授权检查**(但我们的应用程序不能)。例如,如果 B 有一些授权或以root身份运行,它可能允许他要求 A 执行特权操作。
对于此授权检查,**
A
通过异步方式获取审计令牌,例如通过从dispatch_async
**调用xpc_connection_get_audit_token
。
在这种情况下,攻击者可以触发竞争条件,制作一个请求 A 执行操作的利用,同时让B 发送消息到 A
。当 RC 成功时,B 的审计令牌将在处理我们的利用请求时复制到内存中,使其可以访问只有 B 可以请求的特权操作。
这发生在**A
作为smd
,B
作为diagnosticd
的情况下。从 smb 的SMJobBless
函数可以用于安装新的特权助手工具(作为root**)。如果以root身份运行的进程联系smd,将不会执行其他检查。
因此,服务 B 是 diagnosticd
,因为它以root身份运行,并可用于监视进程,因此一旦监视开始,它将每秒发送多个消息。
执行攻击的步骤:
使用标准 XPC 协议建立到名为
smd
的服务的连接。与正常程序相反,形成到
diagnosticd
的辅助连接。而不是创建并发送两个新的 mach 端口,客户端端口发送权限被替换为与smd
连接相关联的发送权限的副本。结果,XPC 消息可以被分派到
diagnosticd
,但来自diagnosticd
的响应被重新路由到smd
。对于smd
,似乎来自用户和diagnosticd
的消息都是来自同一连接。
下一步涉及指示
diagnosticd
启动对所选进程(可能是用户自己的进程)的监视。同时,向smd
发送一连串的常规 1004 消息。这里的目的是安装具有提升权限的工具。这个操作触发了
handle_bless
函数内的竞争条件。时间非常关键:xpc_connection_get_pid
函数调用必须返回用户进程的PID(因为特权工具驻留在用户的应用程序包中)。然而,xpc_connection_get_audit_token
函数,特别是在connection_is_authorized
子例程内,必须引用属于diagnosticd
的审计令牌。
变种2:回复转发
在XPC(跨进程通信)环境中,虽然事件处理程序不会并发执行,但回复消息的处理具有独特的行为。具体而言,存在两种不同的方法用于发送期望回复的消息:
xpc_connection_send_message_with_reply
:在这里,XPC消息在指定队列上接收和处理。xpc_connection_send_message_with_reply_sync
:相反,在这种方法中,XPC消息在当前调度队列上接收和处理。
这种区别至关重要,因为它允许回复数据包在执行XPC事件处理程序的同时被并发解析的可能性。值得注意的是,虽然_xpc_connection_set_creds
实现了锁定以防止审计令牌的部分覆盖,但它没有将此保护扩展到整个连接对象。因此,这会产生一个漏洞,其中在解析数据包和执行其事件处理程序之间的时间间隔内,审计令牌可以被替换。
要利用这个漏洞,需要以下设置:
两个名为**
A
和B
**的mach服务,两者都可以建立连接。服务**
A
应包含一个仅B
**可以执行的特定操作的授权检查(用户的应用程序无法执行)。服务**
A
**应发送一条期望回复的消息。用户可以向**
B
**发送一条它将回复的消息。
利用过程包括以下步骤:
等待服务**
A
**发送一条期望回复的消息。不直接回复给**
A
,而是劫持回复端口并用于向服务B
**发送消息。随后,发送涉及被禁止操作的消息,期望它将与**
B
**的回复同时处理。
下面是所描述的攻击场景的可视化表示:
![https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/variant2.png](../../../../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png)
发现问题
定位实例的困难性:静态和动态地搜索
xpc_connection_get_audit_token
使用实例都具有挑战性。方法论:使用Frida来挂钩
xpc_connection_get_audit_token
函数,过滤不是源自事件处理程序的调用。然而,这种方法仅限于被挂钩的进程,并且需要主动使用。分析工具:使用IDA/Ghidra来检查可达的mach服务,但这个过程耗时,复杂度增加了与dyld共享缓存相关的调用。
脚本限制:尝试为从
dispatch_async
块调用xpc_connection_get_audit_token
的调用编写脚本时,由于解析块和与dyld共享缓存的交互复杂性而受到阻碍。
修复
报告的问题:向Apple提交了一份报告,详细说明了
sm
中发现的一般和具体问题。苹果的回应:苹果通过用
xpc_dictionary_get_audit_token
替换xpc_connection_get_audit_token
来解决了sm
中的问题。修复的性质:
xpc_dictionary_get_audit_token
函数被认为是安全的,因为它直接从与接收的XPC消息相关联的mach消息中检索审计令牌。然而,它不是公共API的一部分,类似于xpc_connection_get_audit_token
。缺乏更广泛的修复:目前尚不清楚为什么苹果没有实施更全面的修复,比如丢弃与连接的保存的审计令牌不符的消息。在某些情况下(例如
setuid
使用)合法审计令牌更改的可能性可能是一个因素。当前状态:该问题在iOS 17和macOS 14中仍然存在,对于那些试图识别和理解它的人来说构成了一个挑战。
最后更新于