[レポート]音の壁を破る:Machメッセージ・ファジングによるCoreAudioのエクスプロイト - CODE BLUE 2025 #codeblue_jp #codeblue2025

[レポート]音の壁を破る:Machメッセージ・ファジングによるCoreAudioのエクスプロイト - CODE BLUE 2025 #codeblue_jp #codeblue2025

CODE BLUE 2025で行われた「音の壁を破る:Machメッセージ・ファジングによるCoreAudioのエクスプロイト」というセッションのレポートです。
2025.11.18

こんにちは、臼田です。

みなさん、セキュリティ対策してますか?(挨拶

今回はCODE BLUE 2025で行われた以下のセッションのレポートです。

音の壁を破る:Machメッセージ・ファジングによるCoreAudioのエクスプロイト

本研究では、macOSのIPC(プロセス間通信)セキュリティ、特にシステムデーモンにおけるMachメッセージハンドラに焦点を当てて探求します。これらのハンドラは特権機能を公開しており、サンドボックスエスケープやローカルな権限昇格のための重要な攻撃面となります。

私は、構造化ファジングとAPIコールチェイニングという手法を用いて、macOSのcoreaudiodシステムデーモンにおける脆弱性を発見した方法を実演します。私のカスタムファジングハーネス、動的計測、および静的分析とランタイム分析の組み合わせにより、2つの主要なメモリ破損バグを含むいくつかのセキュリティ上の欠陥が見つかりました。これらのうち1つを悪用して、現代のmacOSでサンドボックスエスケープを行うための完全なエクスプロイトチェーンを詳細に説明します。

また、CoreAudioの初期化、コンポーネントのモック、ファジングのためのターゲット文法の構築など、直面した課題についても議論します。最後に、本研究中に開発されたオープンソースのファジングハーネスとツールを共有し、セキュリティコミュニティにとってmacOS IPCファジングのアクセシビリティを向上させることを目指します。

Speakers
Dillon Franke ディロン・フランケ

レポート

  • GoogleのISE所属
  • Project Zeroに20%
  • 以前はMandiantに所属していた
  • 概要
    • Fuzzingについて紹介
    • MachIPCについて
    • 具体的なアタックサイクルについて
    • 脆弱性の活用
    • 最後にメッセージ
  • Fuzzingとは
    • 基本的な内容から
    • 予期されないインプットをシステムに送って想定外のことが起こることを期待する
    • 例えばクラッシュとか
    • Fuzzingで好んでいるアプローチは自動化
    • 色々やってみて反応を見る
    • 物を壊して試してみる
    • しかしそれだけではなくマニュアル分析もする
    • Fuzzがどこで起きてなぜそうなるのか?コードベースを理解する必要がある
    • 自動化といっしょにやる
  • アタックサイクル
    • 興味深いAttack Vectorを特定してターゲットを選ぶ
    • Fuzzingを繰り返して改善していく
    • コードベースに深く入っていく
    • セキュリティに関連するクラッシュを見つけて悪用する
    • Attack Vectorの特定から
      • 現在のブラウザでは追加のサンドボックスエスケープも必要
      • よく使うのはIPC
      • natural bridge
      • mach messageは悪用されている歴史がある
      • task_t considered harmful
    • Mach Ports
      • IPCメッセージキュー
      • ポートのsendとrecirveの権限があるとそれぞれできる
      • Bootstrapに対するsendがデフォルトである
      • com.apple.codeblueというサービスを登録して受け取る
    • System Daemons Register Mach Services
      • 特別なもの
      • 最初から登録されている
      • AddressBookサービスとか
    • Sandboxを探す
      • MachサービスでSandboxからアクセスできるものを探す
      • .sbファイルを確認する
      • TinySchemeで書かれている
      • mach-lookupを許可しているものを探す
      • またはダイナミックにsbtoolを使う
    • coreaudiodを使う
      • バイナリ
      • complex serviceに入っている
      • Machが許可されている
      • 数多くのmessage handlerからアクセスできる
  • Fuzzing Harness
    • 望ましい関数を呼び出す
    • エントリポイントがFuzzingでは重要
      • コマンドライン引数を見て実行するだけではない
      • どのコードエリアをターゲットとするのかが重要
      • 条件が適切にパスしたのかどうか
      • エネルギーが正しい場所に注がれているか
      • 現実的にするのか?パフォーマンスを高めたいかなどで変わる
    • 今回どこに絞ったか?
      • まず自然にmach_msg()を実行
      • Mach IPCからKernel-Managed Message Queueを経由してMach Message Handlerへ
        • シンプルだが時間がかかる
        • どこに到達しているのか確認するのが難しい
        • どのメッセージが原因になったか特定しづらい
      • もう一つはDirect Harnessを書く
        • 直接接続で早くなる
        • どのインプットでクラッシュするかわかりやすく反復もできる
        • しかし初期化のルーティンを行う必要がある
        • 今回はこれを選択
    • アプローチ
      • coreaudiodを使う
      • フレームワークCoreAudio
      • Dyld shared cache
        • パフォーマンスのためにdisk上にあるわけではないが抽出されているものがある
      • CoreAudioライブラリを見てみる
      • Mach Interface Generator(MIG)を使用している
      • HALB_MIGServer_server
        • サブシステムでmessage idに基づいて求められる
        • RCPのハンドラはわかりやすい
    • どうやって直接callするか
      • このシンボルはexportできない
      • TinyInstを使う
      • シンボル情報を抽出し関数を特定する
    • Fuzzing Harnessでコンディションを調整できるようにした
    • 有効なMockメッセージを送らないといけない
      • 簡単なlldbスクリプトを作った
      • 色々なオーディオデバイスとしてセットアップできるようになった
  • Fuzzしてクラッシュする
    • Jackalope fuzzerを使う
      • シームレスにできる
      • 軽くて良い
    • fuzzしてクラッシュする
      • 最初のクラッシュはセキュリティの脆弱性ではない
    • できるものをどうやって作っていくか
      • 初期設定
        • 質の低いメッセージをハンドラに送っているので問題がおきる
        • これで受信プロセスが良くなる
        • コードのカバレッジも重要
        • Fuzzerがカバーしていないもの(ビジュアライズ上で白いもの)をカバーしていく
      • API Call Chaining
        • プロパティを設定するにはクライアントが必要
        • 構造化されたFuzzingが必要
        • 通常のFuzzerはlow byte
        • 複数のMachメッセージを送る
        • メッセージを取り出して処理できるように
        • データが無くなるまで処理するように
        • Fuzzerがどのインプットが面白いのか見つけるのを得意としているのでそれに任せる
      • Mocking Out Functionality
        • 関係ないところで止まってしまう
        • C Function Interposing
          • カスタムしてロード
        • セキュリティに重要ではないものを対処する
          • TinyInst Hook APIでfireするものを選ぶ
  • 脆弱性の特定とエクスプロイト
    • Hardware Abstration Layer(HAL)
      • 新しいオーディオをプラグ・インする時
      • HALS_Objectsリンク
      • どのようにオブジェクトがヒープ上でアレンジされるかわかった
      • CoreAudioではCoppyObjectByObject利用
    • XIO_Context_Fetcg_Workgroup_Portでクラッシュが起きた
      • IDAで見る
      • CVE-2024-54529: Type Confusion
      • 特定の種類が期待されている
      • 全く違うオブジェクトがあるのでポイント先が異なりクラッシュする
      • これでハイジャックができそう
    • Intelのみで試している
    • エクスプロイト戦略
      • チェーンを作ってエクスプロイトできる
      • uidを使いたいが間違っている
      • CFStringはコントロールできないハンドラ
      • ポイントしたい
      • 別のアイデアでcoreaudiodのPreScribble
        • ngneオブジェクト
        • 6つのhighbyteが使える
        • 再利用できる
      • 新しいアプローチ
        • ngneをアロケートされているのを見つける
        • たくさんアロケート
      • IDAを通じてngenオブジェクトを咲く壊死する
      • malloc size zoneがある
      • allocation前になんとかしないといけない
      • 別のngneオブジェクトの作り方がある
        • こちらは1152 bytes
      • XMLバイナリをシリアライズして格納
      • plistにも格納
      • CFArrayRefが大事
    • 戦略
      • RCEでサンドボックス
      • plist contain
      • ヒープスプレー
      • ROPチェーンを作る
      • CoreAudioユーザーはできる
      • 何回かやらないと成功しない
    • もう一つCVE-2025-31235
      • Double free
  • 詳細はブログがあるので見てね

感想

Fuzzingも単純にランダムにやるわけではなく管理してアプローチしていくんですね。勉強になりました。

この記事をシェアする

FacebookHatena blogX

関連記事