macOS XPC Connecting Process Check

HackTricksをサポートする

XPC 接続プロセスチェック

XPCサービスへの接続が確立されると、サーバーは接続が許可されているかどうかを確認します。通常、以下のチェックが行われます:

  1. 接続しているプロセスがApple署名の証明書で署名されているか確認します(Appleからのみ発行されます)。

  • これが確認されない場合、攻撃者は偽の証明書を作成して他のチェックに合致させることができます。

  1. 接続しているプロセスが組織の証明書で署名されているか確認します(チームIDの確認)。

  • これが確認されない場合、Appleの任意の開発者証明書が署名に使用され、サービスに接続できます。

  1. 接続しているプロセスが適切なバンドルIDを含んでいるか確認します。

  • これが確認されない場合、同じ組織によって署名された任意のツールがXPCサービスと対話するために使用される可能性があります。

  1. (4または5) 接続しているプロセスが適切なソフトウェアバージョン番号を持っているか確認します。

  • これが確認されない場合、古い、脆弱なクライアントがプロセスインジェクションに対して脆弱であり、他のチェックが行われていてもXPCサービスに接続される可能性があります。

  1. (4または5) 接続しているプロセスが危険な権限のないハードンされたランタイムを持っているか確認します(任意のライブラリを読み込むことを許可するものやDYLD環境変数を使用するものなど)。

  • これが確認されない場合、クライアントはコードインジェクションに対して脆弱である可能性があります。

  1. 接続しているプロセスがサービスに接続することを許可する権限を持っているか確認します。これはAppleのバイナリに適用されます。

  2. 検証は接続しているクライアントの監査トークン基づくべきであり、そのプロセスID(PID)ではなく、前者はPID再利用攻撃を防ぎます。

  • 開発者は監査トークンAPI呼び出しをほとんど使用しないため、これはプライベートであり、Appleはいつでも変更できる可能性があります。さらに、プライベートAPIの使用はMac App Storeアプリでは許可されていません。

  • **processIdentifier**メソッドが使用される場合、脆弱である可能性があります。

  • **xpc_dictionary_get_audit_tokenxpc_connection_get_audit_token**の代わりに使用されるべきであり、後者は特定の状況で脆弱である可能性があります

コミュニケーション攻撃

PID再利用攻撃についての詳細は以下を確認してください:

macOS PID Reuse

**xpc_connection_get_audit_token**攻撃についての詳細は以下を確認してください:

macOS xpc_connection_get_audit_token Attack

Trustcache - ダウングレード攻撃防止

TrustcacheはApple Siliconマシンで導入された防御方法で、AppleバイナリのCDHSAHのデータベースを保存し、許可された非修正バイナリのみが実行されるようにします。これにより、ダウングレードバージョンの実行が防止されます。

コード例

サーバーはこの検証を**shouldAcceptNewConnection**という関数で実装します。

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

オブジェクト NSXPCConnection には プライベート プロパティ auditToken (使用すべきものだが変更される可能性がある)と パブリック プロパティ processIdentifier (使用すべきでないもの)がある。

接続プロセスは次のように検証できる:

[...]
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 with the PID (vulnerable)
SecRequirementCreateWithString(requirementString, kSecCSDefaultFlags, &requirementRef);
SecCodeCheckValidity(code, kSecCSDefaultFlags, requirementRef);

// Check the requirements wuing the auditToken (secure)
SecTaskRef taskRef = SecTaskCreateWithAuditToken(NULL, ((ExtendedNSXPCConnection*)newConnection).auditToken);
SecTaskValidateForRequirement(taskRef, (__bridge CFStringRef)(requirementString))

もし開発者がクライアントのバージョンを確認したくない場合、少なくともクライアントがプロセスインジェクションに対して脆弱でないことを確認することができます:

[...]
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
}
HackTricksをサポートする

Last updated