macOS XPC Connecting Process Check
XPC 接続プロセスチェック
XPCサービスへの接続が確立されると、サーバーは接続が許可されているかどうかをチェックします。通常、以下のチェックを行います:
接続しているプロセスがAppleによって署名された証明書で署名されているかをチェックします(Appleからのみ発行されます)。
これが検証されない場合、攻撃者は他のチェックに合わせて偽の証明書を作成する可能性があります。
接続しているプロセスが組織の証明書で署名されているかをチェックします(チームIDの検証)。
これが検証されない場合、Appleの任意の開発者証明書を使用して署名し、サービスに接続することができます。
接続しているプロセスに適切なバンドルIDが含まれているかをチェックします。
これが検証されない場合、同じ組織によって署名された任意のツールを使用してXPCサービスと対話することができます。
(4または5) 接続しているプロセスに適切なソフトウェアバージョン番号があるかをチェックします。
これが検証されない場合、古い、安全でないクライアントがプロセスインジェクションに対して脆弱であり、他のチェックがあってもXPCサービスに接続するために使用される可能性があります。
(4または5) 接続しているプロセスが危険な権限(任意のライブラリをロードしたりDYLD環境変数を使用するなど)なしにハード化されたランタイムを持っているかをチェックします。
これが検証されない場合、クライアントはコードインジェクションに対して脆弱である可能性があります。
接続しているプロセスにサービスに接続することを許可する権限があるかをチェックします。これはAppleのバイナリに適用されます。
検証は接続しているクライアントの監査トークンに基づいて行われるべきであり、プロセスID(PID)ではないため、前者はPID再利用攻撃を防ぐことができます。
開発者は監査トークンのAPIコールをほとんど使用しません。なぜならそれはプライベートであり、Appleはいつでも変更する可能性があるからです。さらに、プライベートAPIの使用はMac App Storeのアプリでは許可されていません。
**
processIdentifier
**メソッドが使用されている場合、それは脆弱である可能性があります**
xpc_dictionary_get_audit_token
はxpc_connection_get_audit_token
**の代わりに使用されるべきです。後者は特定の状況で脆弱である可能性があります。
通信攻撃
PID再利用攻撃についての詳細は以下をチェックしてください:
pagemacOS PID Reuse**xpc_connection_get_audit_token
**攻撃についての詳細は以下をチェックしてください:
Trustcache - ダウングレード攻撃防止
TrustcacheはApple Siliconマシンで導入された防御方法で、AppleのバイナリのCDHSAHのデータベースを保存し、許可された変更されていないバイナリのみが実行されるようにします。これにより、ダウングレードバージョンの実行が防止されます。
コード例
サーバーは**shouldAcceptNewConnection
と呼ばれる関数でこの検証**を実装します。
オブジェクト NSXPCConnection には、プライベートプロパティ auditToken
(使用されるべきだが変更される可能性がある)と、パブリックプロパティ processIdentifier
(使用されるべきではない)があります。
接続プロセスは以下のように検証できます:
開発者がクライアントのバージョンをチェックしたくない場合、少なくともクライアントがプロセスインジェクションに対して脆弱でないことを確認することができます:
```objectivec [...] 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 } ```
Last updated