macOS xpc_connection_get_audit_token Attack

HackTricksをサポートする

詳細情報は元の投稿を確認してください: https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/。これは要約です:

Machメッセージの基本情報

Machメッセージが何か知らない場合は、このページを確認してください:

macOS IPC - Inter Process Communication

現時点では、(こちらからの定義): Machメッセージは_machポート_を介して送信され、これは単一受信者、複数送信者通信チャネルで、machカーネルに組み込まれています。複数のプロセスがメッセージをmachポートに送信できますが、任意の時点で単一のプロセスのみがそれを読み取ることができます。ファイルディスクリプタやソケットと同様に、machポートはカーネルによって割り当てられ、管理され、プロセスは整数を見て、それを使用してカーネルにどのmachポートを使用したいかを示します。

XPC接続

XPC接続がどのように確立されるか知らない場合は、次を確認してください:

macOS XPC

脆弱性の概要

知っておくべき興味深い点は、**XPCの抽象化は一対一の接続ですが、**複数の送信者を持つ技術の上に構築されているため、以下のようになります:

  • Machポートは単一受信者、複数送信者です。

  • XPC接続の監査トークンは、最近受信したメッセージからコピーされた監査トークンです。

  • XPC接続の監査トークンを取得することは、多くのセキュリティチェックにとって重要です。

前述の状況は有望に聞こえますが、これが問題を引き起こさないシナリオもいくつかあります(こちらから):

  • 監査トークンは、接続を受け入れるかどうかを決定するための認証チェックにしばしば使用されます。これはサービスポートへのメッセージを使用して行われるため、接続はまだ確立されていません。このポートへの追加のメッセージは、追加の接続要求として処理されます。したがって、接続を受け入れる前のチェックは脆弱ではありません(これは、-listener:shouldAcceptNewConnection:内で監査トークンが安全であることも意味します)。したがって、私たちは特定のアクションを検証するXPC接続を探しています

  • XPCイベントハンドラは同期的に処理されます。これは、1つのメッセージのイベントハンドラが次のメッセージのために呼び出される前に完了する必要があることを意味し、同時にディスパッチキュー上でも同様です。したがって、XPCイベントハンドラ内では、監査トークンは他の通常の(非応答!)メッセージによって上書きされることはありません

この脆弱性が悪用される可能性のある2つの異なる方法:

  1. バリアント1:

  • 攻撃はサービスAおよびサービスB接続します。

  • サービスBは、ユーザーができないサービスAの特権機能を呼び出すことができます。

  • サービスAは、**xpc_connection_get_audit_tokenを呼び出しますが、接続のイベントハンドラ内ではなく、dispatch_async**内で行います。

  • したがって、異なるメッセージが監査トークンを上書きする可能性があります。なぜなら、それはイベントハンドラの外で非同期にディスパッチされているからです。

  • 攻撃はサービスBにサービスAへのSEND権を渡します

  • したがって、svc Bは実際にサービスAメッセージを送信します。

  • 攻撃特権アクションを呼び出そうとします。RC svc Aはこのアクションの認証をチェックしますが、svc Bは監査トークンを上書きしました(攻撃に特権アクションを呼び出すアクセスを与えます)。

  1. バリアント2:

  • サービスBは、ユーザーができないサービスAの特権機能を呼び出すことができます。

  • 攻撃はサービスAに接続し、サービスは攻撃に特定の応答を期待するメッセージを送信します。

  • 攻撃はサービスBにその応答ポートを渡すメッセージを送信します。

  • サービスBが応答すると、サービスAにメッセージを送信し攻撃はサービスAに異なるメッセージを送信し、特権機能に到達しようとし、サービスBからの応答が監査トークンを完璧なタイミングで上書きすることを期待します(レースコンディション)。

バリアント1:イベントハンドラの外でxpc_connection_get_audit_tokenを呼び出す

シナリオ:

  • 接続できる2つのmachサービス**AB**(サンドボックスプロファイルと接続を受け入れる前の認証チェックに基づく)。

  • _A_は、Bが通過できる特定のアクションの認証チェックを持っている必要があります(しかし、私たちのアプリはできません)。

  • たとえば、Bがいくつかの権利を持っているか、rootとして実行されている場合、Aに特権アクションを実行するように要求できるかもしれません。

  • この認証チェックのために、**Aは非同期的に監査トークンを取得します。たとえば、dispatch_async**からxpc_connection_get_audit_tokenを呼び出すことによって。

この場合、攻撃者はレースコンディションを引き起こし、Aにアクションを実行するように要求する攻撃を何度も行いながら、BがAにメッセージを送信させることができます。RCが成功するとB監査トークンがメモリにコピーされ、私たちの攻撃のリクエストがAによって処理されている間、特権アクションに対するアクセスを与えます

これは、Asmdで、Bdiagnosticdで発生しました。関数SMJobBlessは、特権ヘルパーツールを新たにインストールするために使用できます(rootとして)。もしrootとして実行されているプロセスがsmdに接触すると、他のチェックは行われません。

したがって、サービスBは**diagnosticdであり、rootとして実行され、プロセスを監視**するために使用できます。監視が開始されると、毎秒複数のメッセージを送信します。

攻撃を実行するには:

  1. 標準XPCプロトコルを使用して、smdという名前のサービスに接続を開始します。

  2. diagnosticdに二次的な接続を形成します。通常の手順とは異なり、2つの新しいmachポートを作成して送信するのではなく、クライアントポートの送信権がsmd接続に関連付けられた送信権の複製に置き換えられます。

  3. 結果として、XPCメッセージはdiagnosticdにディスパッチできますが、diagnosticdからの応答はsmdに再ルーティングされます。smdにとっては、ユーザーとdiagnosticdの両方からのメッセージが同じ接続から発信されているように見えます。

攻撃プロセスを示す画像
  1. 次のステップは、diagnosticdに選択したプロセス(おそらくユーザー自身のプロセス)の監視を開始するように指示することです。同時に、smdに対して通常の1004メッセージの洪水が送信されます。ここでの意図は、特権のあるツールをインストールすることです。

  2. このアクションは、handle_bless関数内でレースコンディションを引き起こします。タイミングが重要です:xpc_connection_get_pid関数呼び出しは、ユーザーのプロセスのPIDを返さなければなりません(特権ツールはユーザーのアプリバンドル内に存在します)。しかし、xpc_connection_get_audit_token関数は、特にconnection_is_authorizedサブルーチン内で、diagnosticdに属する監査トークンを参照しなければなりません。

バリアント2:応答の転送

XPC(プロセス間通信)環境では、イベントハンドラは同時に実行されませんが、応答メッセージの処理には独自の動作があります。具体的には、応答を期待するメッセージを送信するための2つの異なる方法があります:

  1. xpc_connection_send_message_with_reply:ここでは、XPCメッセージが指定されたキューで受信され、処理されます。

  2. xpc_connection_send_message_with_reply_sync:対照的に、この方法では、XPCメッセージが現在のディスパッチキューで受信され、処理されます。

この区別は重要です。なぜなら、応答パケットがXPCイベントハンドラの実行と同時に解析される可能性があるからです。特に、_xpc_connection_set_credsは監査トークンの部分的な上書きを防ぐためにロックを実装していますが、接続オブジェクト全体に対してこの保護を拡張していません。したがって、パケットの解析とそのイベントハンドラの実行の間の間隔で監査トークンが置き換えられる脆弱性が生じます。

この脆弱性を悪用するには、次のセットアップが必要です:

  • **AおよびB**と呼ばれる2つのmachサービスで、どちらも接続を確立できます。

  • サービス**Aは、B**のみが実行できる特定のアクションのための認証チェックを含む必要があります(ユーザーのアプリケーションはできません)。

  • サービス**A**は、応答を期待するメッセージを送信する必要があります。

  • ユーザーは、**B**に応答するメッセージを送信できます。

悪用プロセスは次のステップを含みます:

  1. サービス**A**が応答を期待するメッセージを送信するのを待ちます。

  2. **Aに直接応答するのではなく、応答ポートをハイジャックしてサービスB**にメッセージを送信します。

  3. 次に、禁止されたアクションに関するメッセージをディスパッチし、**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の使用例を静的および動的に検索するのは困難でした。

  • 方法論:Fridaを使用してxpc_connection_get_audit_token関数をフックし、イベントハンドラから発信されない呼び出しをフィルタリングしました。しかし、この方法はフックされたプロセスに限定され、アクティブな使用が必要でした。

  • 分析ツール:IDA/Ghidraのようなツールを使用して到達可能なmachサービスを調査しましたが、プロセスは時間がかかり、dyld共有キャッシュに関与する呼び出しによって複雑化しました。

  • スクリプトの制限dispatch_asyncブロックからのxpc_connection_get_audit_tokenへの呼び出しの分析をスクリプト化しようとしましたが、ブロックの解析とdyld共有キャッシュとの相互作用の複雑さによって妨げられました。

修正

  • 報告された問題:Appleに、smd内で見つかった一般的および特定の問題を詳細に報告しました。

  • Appleの対応:Appleは、smd内の問題に対処し、xpc_connection_get_audit_tokenxpc_dictionary_get_audit_tokenに置き換えました。

  • 修正の性質xpc_dictionary_get_audit_token関数は、受信したXPCメッセージに関連付けられたmachメッセージから直接監査トークンを取得するため、安全と見なされています。ただし、xpc_connection_get_audit_tokenと同様に、公開APIの一部ではありません。

  • より広範な修正の不在:Appleが接続の保存された監査トークンに一致しないメッセージを破棄するなど、より包括的な修正を実装しなかった理由は不明です。特定のシナリオ(例:setuidの使用)での正当な監査トークンの変更の可能性が要因かもしれません。

  • 現在の状況:この問題はiOS 17およびmacOS 14に残っており、これを特定し理解しようとする人々にとって課題となっています。

HackTricksをサポートする

Last updated