macOS xpc_connection_get_audit_token Attack
詳細については、元の投稿を確認してください: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/。これは要約です:
Machメッセージの基本情報
Machメッセージが何かわからない場合は、このページをチェックしてください:
pagemacOS IPC - Inter Process Communication今のところ、(ここからの定義):
Machメッセージは machポート を介して送信され、これは mach カーネルに組み込まれた 単一の受信者、複数の送信者通信 チャネルです。 複数のプロセスが mach ポートにメッセージを送信できますが、いつでも 単一のプロセスがそれを読み取ることができます。 ファイルディスクリプタやソケットと同様に、machポートはカーネルによって割り当てられ管理され、プロセスは整数しか見ません。これを使用して、カーネルに使用する mach ポートを示すことができます。
XPC接続
XPC接続がどのように確立されるかわからない場合は、次を確認してください:
pagemacOS XPC脆弱性の要約
知っておくと興味深いのは、XPCの抽象化は1対1の接続であるが、複数の送信者を持つことができる技術に基づいているということです:
Machポートは単一の受信者、複数の送信者です。
XPC接続の監査トークンは、最後に受信したメッセージからコピーされた監査トークンです。
XPC接続の監査トークンを取得することは、多くの セキュリティチェック にとって重要です。
前述の状況は有望に聞こえますが、問題を引き起こさないシナリオもいくつかあります (ここから):
監査トークンは、接続を受け入れるかどうかを決定するための認可チェックによく使用されます。これはサービスポートへのメッセージを使用して行われるため、接続はまだ確立されていません。このポートへの追加のメッセージは、追加の接続要求として処理されます。したがって、接続を受け入れる前のチェックは脆弱ではありません(これは
-listener:shouldAcceptNewConnection:
内での監査トークンが安全であることを意味します)。したがって、特定のアクションを検証する XPC 接続を探しています。XPCイベントハンドラは同期的に処理されます。つまり、1つのメッセージのイベントハンドラを呼び出す前に、次のメッセージのイベントハンドラを呼び出さなければなりません。そのため、XPCイベントハンドラ内では、他の通常の(非応答)メッセージによって監査トークンを上書きすることはできません。
これが悪用される可能性がある2つの異なる方法:
Variant1:
Exploit がサービス A とサービス B に 接続 します
サービス B は、ユーザーができない 特権機能 をサービス A で呼び出すことができます
サービス A が
dispatch_async
内でxpc_connection_get_audit_token
を呼び出すとき、イベントハンドラ の内部にいませんしたがって、異なるメッセージが 監査トークンを上書き できます。なぜなら、イベントハンドラの外部で非同期にディスパッチされているからです。
悪用は サービス A に対して SEND 権限をサービス B に渡します。
したがって、svc B は実際にはサービス A に メッセージを送信します。
悪用 は 特権アクションを呼び出そうとします。RC svc A はこの アクション の認可を チェック しますが、svc B が監査トークンを上書き したため(悪用が特権アクションを呼び出す権限を与えられる)、アクセスできるようになります。
Variant 2:
サービス B は、ユーザーができない 特権機能 をサービス A で呼び出すことができます
悪用は、サービス A に接続し、特定の リプライポート で 応答を期待するメッセージ を送信します。
悪用は、そのリプライポート を渡すメッセージを サービス B に送信します。
サービス B が応答する と、悪用 は サービス A に異なるメッセージを送信 し、特権機能に到達しようとします。そして、サービス B からの返信が監査トークンを完璧なタイミングで上書きすることを期待します(競合状態)。
Variant 1: イベントハンドラの外部で xpc_connection_get_audit_token を呼び出す
シナリオ:
両方に接続できる2つの mach サービス
A
とB
(サンドボックスプロファイルと接続を受け入れる前の認可チェックに基づく)。A
は、B
が通過できる特定のアクションの 認可チェック を持っている必要があります(ただし、アプリはできません)。たとえば、Bには エンタイトルメント があるか root として実行されている場合、Aに特権アクションを実行するように要求することができます。
この認可チェックのために、
A
は非同期で監査トークンを取得します。たとえば、dispatch_async
からxpc_connection_get_audit_token
を呼び出すことによって。
この場合、攻撃者は **悪用** をトリガーし、**`A` にアクションを実行するように要求** する **悪用** を複数回実行し、**`B` が `A` にメッセージを送信** するようにします。RC が **成功する** と、**`B`** の **監査トークン** が **メモリにコピー** され、**悪用** のリクエストが **A によって処理される間** に、特権アクションにアクセスできるようになります。これは **`A`** が `smd` として、**`B`** が `diagnosticd` として発生しました。[`SMJobBless`](https://developer.apple.com/documentation/servicemanagement/1431078-smjobbless?language=objc) 関数は、新しい特権ヘルパーツール(**root** として)をインストールするために使用できます。**root** として実行されているプロセスが **smd** に連絡を取る場合、他のチェックは実行されません。
したがって、サービス B は diagnosticd
であり、root として実行されているため、プロセスを監視するために使用でき、監視が開始されると、1秒あたり複数のメッセージを送信します。
攻撃を実行するには:
標準の XPC プロトコルを使用して、
smd
という名前のサービスに 接続 を開始します。diagnosticd
に二次的な 接続 を形成します。通常の手順とは異なり、新しい mach ポートを作成して送信するのではなく、クライアントポートの送信権限はsmd
接続に関連付けられた 送信権限 の複製で置き換えられます。その結果、XPC メッセージを
diagnosticd
にディスパッチできますが、diagnosticd
からの応答はsmd
にリダイレクトされます。smd
にとっては、ユーザーとdiagnosticd
からのメッセージが同じ接続から発信されているように見えます。
次のステップは、
diagnosticd
に選択したプロセス(おそらくユーザー自身)の監視を開始するよう指示することです。同時に、smd
にルーチンの1004メッセージの洪水を送信します。ここでの目的は、特権を持つツールをインストールすることです。このアクションは、
handle_bless
関数内でレースコンディションを引き起こします。タイミングが重要です:xpc_connection_get_pid
関数呼び出しはユーザーのプロセスの PID を返さなければなりません(特権ツールはユーザーのアプリバンドルに存在します)。しかし、xpc_connection_get_audit_token
関数は、特にconnection_is_authorized
サブルーチン内で、diagnosticd
に属する監査トークンを参照しなければなりません。
バリアント 2: リプライ転送
XPC(クロスプロセス通信)環境では、イベントハンドラは同時に実行されませんが、リプライメッセージの処理にはユニークな動作があります。具体的には、リプライを期待するメッセージを送信するための 2 つの異なるメソッドが存在します:
xpc_connection_send_message_with_reply
: ここでは、XPC メッセージは指定されたキューで受信および処理されます。xpc_connection_send_message_with_reply_sync
: これに対して、このメソッドでは、XPC メッセージは現在のディスパッチキューで受信および処理されます。
この違いは重要です。なぜなら、リプライパケットが XPC イベントハンドラの実行と同時に解析される可能性があるからです。特に、_xpc_connection_set_creds
は監査トークンの部分的な上書きを防ぐためにロックを実装していますが、この保護を接続オブジェクト全体には拡張していません。その結果、パケットの解析とそのイベントハンドラの実行の間に監査トークンが置換される脆弱性が生じます。
この脆弱性を悪用するには、次のセットアップが必要です:
A
とB
という名前の 2 つの mach サービスが必要で、どちらも接続を確立できます。サービス
A
は、B
のみが実行できる特定のアクションの認証チェックを含める必要があります(ユーザーのアプリケーションはできません)。サービス
A
は、リプライを期待するメッセージを送信する必要があります。ユーザーは、
B
に応答するメッセージを送信できます。
悪用プロセスは以下の手順を含みます:
サービス
A
がリプライを期待するメッセージを送信するのを待ちます。A
に直接返信する代わりに、リプライポートがハイジャックされ、サービスB
にメッセージを送信するために使用されます。その後、禁止されたアクションを含むメッセージがディスパッチされ、
B
からの返信と同時に処理されることが期待されます。
以下は、説明された攻撃シナリオの視覚的表現です:
![https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/variant2.png](../../../../../../.gitbook/assets/image (1) (1) (1) (1) (1) (1) (1).png)
発見の問題
インスタンスの特定の難しさ:
xpc_connection_get_audit_token
の使用例を静的および動的に検索することは困難でした。方法論:
xpc_connection_get_audit_token
関数をフックするために Frida を使用し、イベントハンドラから発信されない呼び出しをフィルタリングしました。ただし、この方法はフックされたプロセスに限定され、アクティブな使用が必要でした。分析ツール: IDA/Ghidra のようなツールを使用して到達可能な mach サービスを調査しましたが、dyld 共有キャッシュを含む呼び出しによって時間がかかり、複雑になりました。
スクリプトの制限:
dispatch_async
ブロックからxpc_connection_get_audit_token
への呼び出しを解析するためのスクリプト化の試みは、ブロックの解析と dyld 共有キャッシュとの相互作用の複雑さによって妨げられました。
修正
報告された問題:
smd
内で見つかった一般的および特定の問題について、Apple に報告が提出されました。Apple の対応: Apple は
smd
内の問題をxpc_connection_get_audit_token
をxpc_dictionary_get_audit_token
で置き換えることで対処しました。修正の性質:
xpc_dictionary_get_audit_token
関数は、受信した XPC メッセージに関連付けられた mach メッセージから監査トークンを直接取得するため、安全であると見なされます。ただし、これはxpc_connection_get_audit_token
と同様に公開APIの一部ではありません。より包括的な修正の不在: Apple が接続の保存された監査トークンと一致しないメッセージを破棄するなど、より包括的な修正を実装しなかった理由は明確ではありません。特定のシナリオ(たとえば、
setuid
の使用)で正当な監査トークンの変更が可能である可能性があることが要因かもしれません。現在の状況: 問題は iOS 17 および macOS 14 で依然として存在し、それを特定し理解しようとする人々にとって課題となっています。
Last updated