macOS xpc_connection_get_audit_token Attack
詳細情報は元の投稿を確認してください: 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:
攻撃はサービスAおよびサービスBに接続します。
サービスBは、ユーザーができないサービスAの特権機能を呼び出すことができます。
サービスAは、**
xpc_connection_get_audit_token
を呼び出しますが、接続のイベントハンドラ内ではなく、dispatch_async
**内で行います。したがって、異なるメッセージが監査トークンを上書きする可能性があります。なぜなら、それはイベントハンドラの外で非同期にディスパッチされているからです。
攻撃はサービスBにサービスAへのSEND権を渡します。
したがって、svc Bは実際にサービスAにメッセージを送信します。
攻撃は特権アクションを呼び出そうとします。RC svc Aはこのアクションの認証をチェックしますが、svc Bは監査トークンを上書きしました(攻撃に特権アクションを呼び出すアクセスを与えます)。
バリアント2:
サービスBは、ユーザーができないサービスAの特権機能を呼び出すことができます。
攻撃はサービスAに接続し、サービスは攻撃に特定の応答を期待するメッセージを送信します。
攻撃はサービスBにその応答ポートを渡すメッセージを送信します。
サービスBが応答すると、サービスAにメッセージを送信し、攻撃はサービスAに異なるメッセージを送信し、特権機能に到達しようとし、サービスBからの応答が監査トークンを完璧なタイミングで上書きすることを期待します(レースコンディション)。
バリアント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
は、特権ヘルパーツールを新たにインストールするために使用できます(rootとして)。もしrootとして実行されているプロセスがsmd
に接触すると、他のチェックは行われません。
したがって、サービスBは**diagnosticd
であり、rootとして実行され、プロセスを監視**するために使用できます。監視が開始されると、毎秒複数のメッセージを送信します。
攻撃を実行するには:
標準XPCプロトコルを使用して、
smd
という名前のサービスに接続を開始します。diagnosticd
に二次的な接続を形成します。通常の手順とは異なり、2つの新しいmachポートを作成して送信するのではなく、クライアントポートの送信権がsmd
接続に関連付けられた送信権の複製に置き換えられます。結果として、XPCメッセージは
diagnosticd
にディスパッチできますが、diagnosticd
からの応答はsmd
に再ルーティングされます。smd
にとっては、ユーザーとdiagnosticd
の両方からのメッセージが同じ接続から発信されているように見えます。
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fsector7.computest.nl%2Fpost%2F2023-10-xpc-audit-token-spoofing%2Fexploit.png&width=768&dpr=4&quality=100&sign=3f6bbe07&sv=1)
次のステップは、
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
の使用例を静的および動的に検索するのは困難でした。方法論: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_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