macOS xpc_connection_get_audit_token Attack

从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert)

支持HackTricks的其他方式:

有关更多信息,请查看原始帖子: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/。这是一个摘要:

Mach消息基本信息

如果您不知道什么是Mach消息,请查看此页面:

macOS IPC - Inter Process Communication

目前要记住的是(定义来自此处): Mach消息通过一个_mach端口_发送,这是内置在mach内核中的单接收器,多发送器通信通道。多个进程可以向mach端口发送消息,但在任何时候只有一个进程可以从中读取。就像文件描述符和套接字一样,mach端口由内核分配和管理,进程只看到一个整数,它们可以用来指示内核它们想要使用哪个mach端口。

XPC连接

如果您不知道如何建立XPC连接,请查看:

macOS XPC

漏洞摘要

您需要知道的有趣信息是XPC的抽象是一对一连接,但它是基于一个技术构建的,该技术可以有多个发送器,因此:

  • Mach端口是单接收器,多发送器

  • XPC连接的审计令牌是从最近接收的消息中复制的审计令牌。

  • 获取XPC连接的审计令牌对许多安全检查至关重要。

尽管前述情况听起来很有前途,但在某些情况下,这不会造成问题(来自此处):

  • 审计令牌通常用于授权检查,以决定是否接受连接。由于这是使用消息发送到服务端口进行的,尚未建立连接。在此端口上的更多消息将只被处理为附加连接请求。因此,在接受连接之前的任何检查都不会有漏洞(这也意味着在-listener:shouldAcceptNewConnection:中审计令牌是安全的)。因此,我们正在寻找验证特定操作的XPC连接

  • XPC事件处理程序是同步处理的。这意味着一个消息的事件处理程序必须在调用下一个消息的事件处理程序之前完成,即使在并发调度队列上也是如此。因此,在XPC事件处理程序内部,审计令牌不能被其他正常(非回复!)消息覆盖

这可能会利用的两种不同方法:

  1. 变体1:

  • 利用连接到服务A和服务B

  • 服务B可以调用服务A中用户无法执行的特权功能

  • 服务A不在****事件处理程序中调用**xpc_connection_get_audit_token**。

  • 因此,不同的消息可能会覆盖审计令牌,因为它是在事件处理程序之外异步调度的。

  • 攻击将向服务A传递SEND权限

  • 因此,svc B实际上将发送消息到服务A

  • 利用尝试调用****特权操作。在RC svc A 检查操作的授权,而svc B覆盖了审计令牌(使攻击获得调用特权操作的权限)。

  1. 变体2:

  • 服务B可以调用服务A中用户无法执行的特权功能

  • 利用与服务A建立连接,发送期望响应的消息到特定回复端口

  • 利用向服务B发送消息,传递该回复端口

  • 当服务B回复时,它将发送消息到服务A同时利用发送不同的消息到服务A,尝试达到特权功能并期望服务B的回复在完美时机覆盖审计令牌(竞争条件)。

变体1:在事件处理程序之外调用xpc_connection_get_audit_token

场景:

  • 两个我们都可以连接的mach服务**AB**(基于沙箱配置文件和接受连接前的授权检查)。

  • _A_必须对**B可以通过的特定操作进行授权检查**(但我们的应用程序不能)。

  • 例如,如果B具有某些授权或以root身份运行,则可能允许其要求A执行特权操作。

  • 对于此授权检查,**A通过异步方式获取审计令牌,例如通过从dispatch_async**调用xpc_connection_get_audit_token

这发生在**A作为smdB作为diagnosticd的情况下。函数SMJobBless从smb中可以用作安装新的特权助手工具(作为root**)。如果以root身份运行的进程联系smd,将不会执行其他检查。

因此,服务B是**diagnosticd,因为它以root身份运行,可用于监视进程,因此一旦监视开始,它将每秒发送多个消息。**

执行攻击的步骤:

  1. 使用标准XPC协议建立到名为smd的服务的连接

  2. 形成到diagnosticd的次要连接。与正常程序相反,不是创建并发送两个新的mach端口,而是用与smd连接关联的发送权限的副本替换客户端端口发送权限。

  3. 结果,XPC消息可以被分派到diagnosticd,但diagnosticd的响应被重新路由到smd。对于smd,似乎来自用户和diagnosticd的消息都是来自同一连接。

4. 下一步涉及指示diagnosticd启动对所选进程(可能是用户自己的进程)的监视。同时,向smd发送一连串的常规1004消息。这里的意图是安装一个具有提升权限的工具。 5. 这个操作触发了handle_bless函数内的竞争条件。时机至关重要:xpc_connection_get_pid函数调用必须返回用户进程的PID(因为特权工具位于用户的应用程序包中)。然而,xpc_connection_get_audit_token函数,特别是在connection_is_authorized子例程内,必须引用属于diagnosticd的审计令牌。

变种2:回复转发

在XPC(跨进程通信)环境中,虽然事件处理程序不会并发执行,但回复消息的处理具有独特的行为。具体而言,存在两种不同的方法用于发送期望回复的消息:

  1. xpc_connection_send_message_with_reply:在这里,XPC消息在指定队列上接收并处理。

  2. xpc_connection_send_message_with_reply_sync:相反,在这种方法中,XPC消息在当前调度队列上接收并处理。

这种区别至关重要,因为它允许在执行XPC事件处理程序的同时并发解析回复数据包的可能性。值得注意的是,虽然_xpc_connection_set_creds实现了锁定以防止审计令牌的部分覆盖,但它没有将此保护扩展到整个连接对象。因此,这会产生一个漏洞,使得在解析数据包和执行其事件处理程序之间的时间间隔内,审计令牌可以被替换。

要利用这个漏洞,需要以下设置:

  • 两个名为**AB**的mach服务,两者都可以建立连接。

  • 服务**A应包含一个授权检查,用于执行只有B**可以执行的特定操作(用户的应用程序无法执行)。

  • 服务**A**应发送一条期望回复的消息。

  • 用户可以向**B**发送一条它将会回复的消息。

利用过程包括以下步骤:

  1. 等待服务**A**发送一条期望回复的消息。

  2. 不直接回复**A,而是劫持回复端口并用于向服务B**发送一条消息。

  3. 随后,发送涉及被禁止操作的消息,期望它将与**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)

https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/variant2.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提交了一份报告,详细说明了在smd中发现的一般和具体问题。

  • 苹果的回应:苹果通过将xpc_connection_get_audit_token替换为xpc_dictionary_get_audit_token来解决了smd中的问题。

  • 修复的性质xpc_dictionary_get_audit_token函数被认为是安全的,因为它直接从与接收到的XPC消息相关联的mach消息中检索审计令牌。然而,它不是公共API的一部分,类似于xpc_connection_get_audit_token

  • 缺乏更广泛的修复:目前尚不清楚为什么苹果没有实施更全面的修复,比如丢弃与连接的保存的审计令牌不符的消息。在某些情况下(例如setuid使用),合法审计令牌更改的可能性可能是一个因素。

  • 当前状态:这个问题在iOS 17和macOS 14中仍然存在,对于那些试图识别和理解它的人来说是一个挑战。

最后更新于