hacktricks/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/macos-xpc-connecting-process-check.md
2023-07-07 23:42:27 +00:00

8.2 KiB
Raw Blame History

macOS XPC接続プロセスのチェック

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

XPC接続プロセスのチェック

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

  1. 接続するプロセスがAppleによって署名された証明書を持っているかどうかをチェックしますAppleのみが提供
  • これが検証されていない場合、攻撃者は他のチェックに合わせるために偽の証明書を作成することができます。
  1. 接続するプロセスが組織の証明書チームIDの検証で署名されているかどうかをチェックします。
  • これが検証されていない場合、Appleの任意の開発者証明書を使用して署名し、サービスに接続することができます。
  1. 接続するプロセスが適切なバンドルIDを持っているかどうかをチェックします。
  2. 接続するプロセスが適切なソフトウェアバージョン番号を持っているかどうかをチェックします。
  • これが検証されていない場合、他のチェックが行われていても、古い、セキュリティの脆弱なクライアントがプロセスインジェクションに対して脆弱であるため、XPCサービスに接続することができます。
  1. 接続するプロセスがサービスに接続するためのエンタイトルメントを持っているかどうかをチェックします。これはAppleのバイナリに適用されます。
  2. 検証は、接続するクライアントの監査トークンに基づいて行われる必要があります。プロセスIDPIDではなく。
  • 開発者は監査トークン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);

{% endcode %}

開発者がクライアントのバージョンをチェックしたくない場合、少なくともクライアントがプロセスインジェクションの脆弱性を持っていないことをチェックすることができます。

{% 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 🎥