hacktricks/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/macos-xpc-connecting-process-check.md
2023-08-03 19:12:22 +00:00

6.6 KiB
Raw Blame History

macOS XPC连接进程检查

☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 YouTube 🎥

XPC连接进程检查

当与XPC服务建立连接时服务器将检查连接是否被允许。通常会执行以下检查

  1. 检查连接的进程是否使用Apple签名的证书仅由Apple提供
  • 如果未经验证,攻击者可以创建一个伪造的证书以匹配其他任何检查。
  1. 检查连接的进程是否使用组织的证书进行签名团队ID验证
  • 如果未经验证可以使用Apple的任何开发者证书进行签名并连接到服务。
  1. 检查连接的进程是否包含正确的Bundle ID
  2. 检查连接的进程是否具有正确的软件版本号
  • 如果未经验证即使其他检查已经通过仍然可以使用旧的、存在进程注入漏洞的客户端连接到XPC服务。
  1. 检查连接的进程是否具有允许其连接到服务的授权。这适用于Apple二进制文件。
  2. 验证必须基于连接的客户端的审计令牌而不是其进程IDPID因为前者可以防止PID重用攻击。
  • 开发人员很少使用审计令牌API调用因为它是私有的所以Apple可以随时更改。此外Mac App Store应用程序不允许使用私有API。

有关PID重用攻击检查的更多信息请参见

{% content-ref url="macos-pid-reuse.md" %} macos-pid-reuse.md {% endcontent-ref %}

Trustcache - 防止降级攻击

Trustcache是一种在Apple Silicon机器上引入的防御方法它存储了Apple二进制文件的CDHSAH数据库因此只有允许的非修改二进制文件才能执行。这可以防止执行降级版本。

代码示例

服务器将在一个名为**shouldAcceptNewConnection的函数中实现此验证**。

{% code overflow="wrap" %}

- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
//Check connection
return YES;
}

{% endcode %}

对象NSXPCConnection有一个私有属性**auditToken(应该使用但可能会更改)和一个公共属性processIdentifier**(不应该使用)。

可以使用以下方式验证连接的进程:

{% code overflow="wrap" %}

[...]
SecRequirementRef requirementRef = NULL;
NSString requirementString = @"anchor apple generic and identifier \"xyz.hacktricks.service\" and certificate leaf [subject.CN] = \"TEAMID\" and info [CFBundleShortVersionString] >= \"1.0\"";
/* Check:
- Signed by a cert signed by Apple
- Check the bundle ID
- Check the TEAMID of the signing cert
- Check the version used
*/

// Check the requirements
SecRequirementCreateWithString(requirementString, kSecCSDefaultFlags, &requirementRef);
SecCodeCheckValidity(code, kSecCSDefaultFlags, requirementRef);

如果开发人员不想检查客户端的版本,他至少可以检查客户端是否容易受到进程注入的攻击:

{% code overflow="wrap" %}

[...]
CFDictionaryRef csInfo = NULL;
SecCodeCopySigningInformation(code, kSecCSDynamicInformation, &csInfo);
uint32_t csFlags = [((__bridge NSDictionary *)csInfo)[(__bridge NSString *)kSecCodeInfoStatus] intValue];
const uint32_t cs_hard = 0x100;        // don't load invalid page.
const uint32_t cs_kill = 0x200;        // Kill process if page is invalid
const uint32_t cs_restrict = 0x800;    // Prevent debugging
const uint32_t cs_require_lv = 0x2000; // Library Validation
const uint32_t cs_runtime = 0x10000;   // hardened runtime
if ((csFlags & (cs_hard | cs_require_lv)) {
return Yes; // Accept connection
}

{% endcode %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥