macOS Launch/Environment Constraints & Trust Cache
基本情報
macOSの起動制約は、プロセスの開始方法、誰が、どこからプロセスを開始できるかを規制することでセキュリティを強化するために導入されました。macOS Venturaで開始され、各システムバイナリを異なる制約カテゴリに分類するフレームワークを提供し、それらは信頼キャッシュ内に定義されたシステムバイナリとそれらのハッシュを含むリストを含みます。これらの制約は、システム内のすべての実行可能なバイナリに適用され、特定のバイナリを起動するための要件を明確にする一連のルールを含みます。これらのルールには、バイナリが満たす必要がある自己制約、親プロセスが満たす必要がある親制約、および他の関連エンティティが守る必要がある責任制約が含まれます。
このメカニズムは、macOS Sonomaから始まる環境制約を通じてサードパーティのアプリケーションにも拡張され、開発者が環境制約のためのキーと値のセットを指定することでアプリを保護できるようになりました。
起動環境とライブラリ制約を定義するには、launchd
プロパティリストファイルに保存するか、コードサイニングで使用する別個のプロパティリストファイルに保存します。
制約には4種類あります:
自己制約:実行中のバイナリに適用される制約。
親プロセス:プロセスの親に適用される制約(たとえば**
launchd
**がXPサービスを実行している場合)。責任制約:XPC通信でサービスを呼び出すプロセスに適用される制約。
ライブラリロード制約:ロードできるコードを選択的に記述するためにライブラリロード制約を使用します。
したがって、プロセスが別のプロセスを起動しようとする場合(execve(_:_:_:)
またはposix_spawn(_:_:_:_:_:_:)
を呼び出すことにより)、オペレーティングシステムは実行可能ファイルが自己制約を満たしているかどうかをチェックします。また、親プロセスの実行可能ファイルが実行可能ファイルの親制約を満たしているか、および責任プロセスの実行可能ファイルが実行可能ファイルの責任プロセス制約を満たしているかをチェックします。これらの起動制約のいずれかが満たされていない場合、オペレーティングシステムはプログラムを実行しません。
ライブラリをロードする際にライブラリ制約の一部が真でない場合、プロセスはライブラリをロードしません。
LCカテゴリ
LCは事実と論理演算(and、orなど)で構成され、事実を組み合わせます。
is-init-proc:実行可能ファイルがオペレーティングシステムの初期化プロセス(
launchd
)である必要があるかどうかを示すブール値。is-sip-protected:System Integrity Protection(SIP)によって保護されたファイルである必要があるかどうかを示すブール値。
on-authorized-authapfs-volume:
:オペレーティングシステムが認証されたAPFSボリュームから実行可能ファイルを読み込んだかどうかを示すブール値。on-authorized-authapfs-volume
:オペレーティングシステムが認証されたAPFSボリュームから実行可能ファイルを読み込んだかどうかを示すブール値。Cryptexesボリューム
on-system-volume:
:オペレーティングシステムが現在起動しているシステムボリュームから実行可能ファイルを読み込んだかどうかを示すブール値。/System内部...
...
Appleバイナリが署名されると、信頼キャッシュ内のLCカテゴリに割り当てられます。
iOS 16 LCカテゴリはこちらで逆アセンブルされ文書化されています。
現在のLCカテゴリ(macOS 14 - Somona)は逆アセンブルされ、こちらで説明が見つかります。
たとえば、カテゴリ1は:
(on-authorized-authapfs-volume || on-system-volume)
: システムまたはCryptexesボリューム内にある必要があります。launch-type == 1
: システムサービスである必要があります(LaunchDaemons内のplist)。validation-category == 1
: オペレーティングシステムの実行可能ファイルです。is-init-proc
: Launchd
LCカテゴリの逆変換
詳細はこちらにありますが、基本的に、これらは**AMFI(AppleMobileFileIntegrity)**で定義されているため、KEXTを取得するためにKernel Development Kitをダウンロードする必要があります。 kConstraintCategory
で始まるシンボルが興味深いものです。 これらを抽出すると、ASN.1でエンコードされたストリームが得られます。これをASN.1デコーダまたはpython-asn1ライブラリとそのdump.py
スクリプト、andrivet/python-asn1を使用してデコードする必要があります。これにより、より理解しやすい文字列が得られます。
環境制約
これらはサードパーティアプリケーションで構成されたLaunch Constraintsです。 開発者は、自分のアプリケーションへのアクセスを制限するために使用する事実と論理演算子を選択できます。
アプリケーションの環境制約を列挙することが可能です。
信頼キャッシュ
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 を使用してデータベースのペイロードを抽出できます:
(別のオプションとして、img4tool ツールを使用することもできます。このツールは、リリースが古く、x86_64 用に適切な場所にインストールされていれば、M1 でも実行されます)。
今、trustcache ツールを使用して、情報を読みやすい形式で取得できます:
信頼キャッシュは以下の構造に従いますので、LCカテゴリは4番目の列です。
次に、このスクリプトなどを使用してデータを抽出できます。
そのデータから、0
の起動制約値を持つアプリをチェックできます。これは制約されていないものです(各値についてはこちらを参照)。
攻撃緩和
起動制約は、プロセスが予期しない状況で実行されないようにすることで、いくつかの古い攻撃を緩和していました。たとえば、予期しない場所からの起動や予期しない親プロセスによる起動(launchdだけが起動すべき場合)などです。
さらに、起動制約はダウングレード攻撃を緩和します。
ただし、これらは一般的なXPCの悪用、Electronコードの挿入、ライブラリの検証なしでのdylibの挿入(ライブラリを読み込むことができるチームIDがわかっている場合を除く)を緩和しません。
XPCデーモン保護
Sonomaリリースでは、デーモンXPCサービスの責任構成が注目されます。XPCサービスは、接続するクライアントが責任を負うのではなく、自己責任を負います。これはフィードバックレポートFB13206884に記載されています。この設定は欠陥のように見えるかもしれませんが、次のようなXPCサービスとの相互作用を許可します:
XPCサービスの起動:バグと仮定される場合、この設定では攻撃者コードを介してXPCサービスを起動することは許可されません。
アクティブサービスへの接続:XPCサービスが既に実行中の場合(おそらく元のアプリケーションによってアクティブ化された場合)、接続に障壁はありません。
XPCサービスに制約を実装することで、潜在的な攻撃の余地を狭めることができますが、主要な懸念には対処できません。XPCサービスのセキュリティを確保するには、接続するクライアントを効果的に検証することが不可欠です。これがサービスのセキュリティを強化する唯一の方法です。また、言及された責任構成が現在稼働していることに留意する価値がありますが、これは意図された設計と一致しない可能性があります。
Electron保護
アプリケーションが親の制約でLaunchServiceによって開かれる必要がある場合でも、これは**open
**(環境変数を設定できる)を使用するか、Launch Services API(環境変数を指定できる)を使用して達成できます。
参考文献
Last updated