macOS Launch/Environment Constraints & Trust Cache

Support HackTricks

基本情報

macOSの起動制約は、プロセスがどのように、誰が、どこから開始できるかを規制することによってセキュリティを強化するために導入されました。macOS Venturaで開始され、各システムバイナリを異なる制約カテゴリに分類するフレームワークを提供します。これらは信頼キャッシュ内で定義されており、システムバイナリとそのハッシュのリストを含んでいます。これらの制約は、システム内のすべての実行可能バイナリに拡張され、特定のバイナリを起動するための要件を定義する一連のルールを含みます。ルールには、バイナリが満たすべき自己制約、親プロセスが満たすべき親制約、関連する他のエンティティが遵守すべき責任制約が含まれます。

このメカニズムは、macOS Sonoma以降、環境制約を通じてサードパーティアプリにも拡張され、開発者が環境制約のためのキーと値のセットを指定することによってアプリを保護できるようにします。

起動環境およびライブラリ制約は、launchdプロパティリストファイルに保存するか、コード署名で使用する別のプロパティリストファイルに保存する制約辞書で定義します。

制約には4つのタイプがあります:

  • 自己制約実行中のバイナリに適用される制約。

  • 親プロセスプロセスの親に適用される制約(例えば、**launchd**がXPサービスを実行している場合)。

  • 責任制約:XPC通信でサービスを呼び出すプロセスに適用される制約。

  • ライブラリロード制約:ロードできるコードを選択的に記述するためにライブラリロード制約を使用します。

したがって、プロセスが別のプロセスを起動しようとするとき — execve(_:_:_:)またはposix_spawn(_:_:_:_:_:_:)を呼び出すことによって — オペレーティングシステムは、実行可能ファイルが自身の自己制約を満たしているかどうかを確認します。また、プロセスの実行可能ファイルが実行可能ファイルの親制約を満たしているかどうか、および責任プロセスの実行可能ファイルが実行可能ファイルの責任プロセス制約を満たしているかどうかも確認します。これらの起動制約のいずれかが満たされない場合、オペレーティングシステムはプログラムを実行しません。

ライブラリをロードする際にライブラリ制約の一部が真でない場合、プロセスはライブラリをロードしません

LCカテゴリ

LCは、事実論理演算(and、or..)で構成され、事実を組み合わせます。

LCが使用できる事実は文書化されています。例えば:

  • is-init-proc:実行可能ファイルがオペレーティングシステムの初期化プロセス(launchd)である必要があるかどうかを示すブール値。

  • is-sip-protected:実行可能ファイルがシステム整合性保護(SIP)によって保護されているファイルである必要があるかどうかを示すブール値。

  • on-authorized-authapfs-volume: オペレーティングシステムが認可された、認証されたAPFSボリュームから実行可能ファイルをロードしたかどうかを示すブール値。

  • on-authorized-authapfs-volume:オペレーティングシステムが認可された、認証されたAPFSボリュームから実行可能ファイルをロードしたかどうかを示すブール値。

  • Cryptexesボリューム

  • on-system-volume: オペレーティングシステムが現在起動しているシステムボリュームから実行可能ファイルをロードしたかどうかを示すブール値。

  • /System内...

  • ...

Appleのバイナリが署名されると、それは信頼キャッシュ内のLCカテゴリに割り当てられます

例えば、カテゴリ1は:

Category 1:
Self Constraint: (on-authorized-authapfs-volume || on-system-volume) && launch-type == 1 && validation-category == 1
Parent Constraint: is-init-proc
  • (on-authorized-authapfs-volume || on-system-volume): システムまたはCryptexesボリューム内である必要があります。

  • launch-type == 1: システムサービスである必要があります(LaunchDaemons内のplist)。

  • validation-category == 1: オペレーティングシステムの実行可能ファイル。

  • is-init-proc: Launchd

LCカテゴリの逆アセンブル

詳細についてはこちらにありますが、基本的には、これらはAMFI (AppleMobileFileIntegrity)で定義されているため、KEXTを取得するにはカーネル開発キットをダウンロードする必要があります。kConstraintCategoryで始まるシンボルが興味深いものです。それらを抽出すると、DER (ASN.1) エンコードされたストリームが得られ、ASN.1 Decoderまたはpython-asn1ライブラリとそのdump.pyスクリプト、andrivet/python-asn1を使用してデコードする必要があります。これにより、より理解しやすい文字列が得られます。

環境制約

これらはサードパーティアプリケーションで設定されたLaunch Constraintsです。開発者は、アプリケーション内で自分自身へのアクセスを制限するために使用する事実論理演算子を選択できます。

アプリケーションの環境制約を列挙することが可能です:

codesign -d -vvvv app.app

信頼キャッシュ

macOS にはいくつかの信頼キャッシュがあります:

  • /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4

  • /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4

  • /System/Library/Security/OSLaunchPolicyData

iOS では /usr/standalone/firmware/FUD/StaticTrustCache.img4 にあるようです。

Apple Silicon デバイス上の macOS では、Apple 署名のバイナリが信頼キャッシュにない場合、AMFI はそれをロードすることを拒否します。

信頼キャッシュの列挙

前述の信頼キャッシュファイルは IMG4 および IM4P 形式であり、IM4P は IMG4 形式のペイロードセクションです。

データベースのペイロードを抽出するには pyimg4 を使用できます:

# Installation
python3 -m pip install pyimg4

# Extract payloads data
cp /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/BaseSystemTrustCache.img4 /tmp
pyimg4 img4 extract -i /tmp/BaseSystemTrustCache.img4 -p /tmp/BaseSystemTrustCache.im4p
pyimg4 im4p extract -i /tmp/BaseSystemTrustCache.im4p -o /tmp/BaseSystemTrustCache.data

cp /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4 /tmp
pyimg4 img4 extract -i /tmp/StaticTrustCache.img4 -p /tmp/StaticTrustCache.im4p
pyimg4 im4p extract -i /tmp/StaticTrustCache.im4p -o /tmp/StaticTrustCache.data

pyimg4 im4p extract -i /System/Library/Security/OSLaunchPolicyData -o /tmp/OSLaunchPolicyData.data

(別のオプションは、ツール img4tool を使用することで、リリースが古くてもM1で実行でき、適切な場所にインストールすればx86_64でも実行できます)。

今、ツール trustcache を使用して、情報を読みやすい形式で取得できます:

# Install
wget https://github.com/CRKatri/trustcache/releases/download/v2.0/trustcache_macos_arm64
sudo mv ./trustcache_macos_arm64 /usr/local/bin/trustcache
xattr -rc /usr/local/bin/trustcache
chmod +x /usr/local/bin/trustcache

# Run
trustcache info /tmp/OSLaunchPolicyData.data | head
trustcache info /tmp/StaticTrustCache.data | head
trustcache info /tmp/BaseSystemTrustCache.data | head

version = 2
uuid = 35EB5284-FD1E-4A5A-9EFB-4F79402BA6C0
entry count = 969
0065fc3204c9f0765049b82022e4aa5b44f3a9c8 [none] [2] [1]
00aab02b28f99a5da9b267910177c09a9bf488a2 [none] [2] [1]
0186a480beeee93050c6c4699520706729b63eff [none] [2] [2]
0191be4c08426793ff3658ee59138e70441fc98a [none] [2] [3]
01b57a71112235fc6241194058cea5c2c7be3eb1 [none] [2] [2]
01e6934cb8833314ea29640c3f633d740fc187f2 [none] [2] [2]
020bf8c388deaef2740d98223f3d2238b08bab56 [none] [2] [3]

信頼キャッシュは以下の構造に従いますので、LCカテゴリは4番目の列です

struct trust_cache_entry2 {
uint8_t cdhash[CS_CDHASH_LEN];
uint8_t hash_type;
uint8_t flags;
uint8_t constraintCategory;
uint8_t reserved0;
} __attribute__((__packed__));

その後、このスクリプトを使用してデータを抽出できます。

そのデータから、**launch constraintsの値が0**のアプリを確認できます。これらは制約がないアプリです(各値が何であるかはこちらを確認してください)。

攻撃の緩和策

Launch Constraintsは、プロセスが予期しない条件で実行されないようにすることで、いくつかの古い攻撃を緩和します。 例えば、予期しない場所からの実行や、予期しない親プロセスによって呼び出されること(launchdのみが起動するべき場合)を防ぎます。

さらに、Launch Constraintsはダウングレード攻撃も緩和します。

しかし、一般的なXPCの悪用Electronコードの注入やdylibの注入(ライブラリの検証なしで)には対処できません(ライブラリを読み込むことができるチームIDが知られていない限り)。

XPCデーモン保護

Sonomaリリースでは、デーモンXPCサービスの責任構成が注目されます。XPCサービスは自分自身に対して責任を持ち、接続クライアントが責任を持つのではありません。これはフィードバックレポートFB13206884に文書化されています。この設定は欠陥があるように見えるかもしれませんが、XPCサービスとの特定の相互作用を許可します:

  • XPCサービスの起動:バグと見なされる場合、この設定は攻撃者のコードを通じてXPCサービスを起動することを許可しません。

  • アクティブサービスへの接続:XPCサービスがすでに実行中(元のアプリケーションによって起動された可能性がある)であれば、接続するための障壁はありません。

XPCサービスに制約を実装することは、潜在的な攻撃のウィンドウを狭めることで有益かもしれませんが、主要な懸念には対処していません。XPCサービスのセキュリティを確保するためには、接続クライアントを効果的に検証することが根本的に必要です。 これがサービスのセキュリティを強化する唯一の方法です。また、前述の責任構成は現在機能していることに注意する価値がありますが、意図された設計とは一致しない可能性があります。

Electron保護

アプリケーションがLaunchServiceによって開かれる必要がある場合(親の制約内)。これは、openを使用することで達成できます(環境変数を設定できます)またはLaunch Services APIを使用することで達成できます(環境変数を指定できます)。

参考文献

Support HackTricks

Last updated