✨ 要約🔬 技術概要
あなたは、巨大で複雑な工場の隠れた罠を見つけようとしているセキュリティ検査員だと想像してください。この工場は、Go プログラミング言語 で書かれたソフトウェアです。
長らく、セキュリティ検査員は「TinyGo」バイナリと呼ばれる小さく単純な工場を検査するのに優れた、Zorya という特別なツールを持っていました。しかし、Kubernetes や Ethereum といった大企業が使用する現実の工場は、巨大で混沌としており、同時に多くの作業者(スレッド)が稼働しています。古い Zorya ツールはこの巨大な工場には対応できませんでした。ノイズと複雑さに混乱してしまうのです。
この論文は、Zorya をアップグレードして、ついにこれらの現実の多作業者 Go 工場を検査できるようにしたものです。その方法を簡単に説明します。
1. 問題:「忙しい工場」
標準的な Go コンパイラ(gc )は、作業を管理するために、見えない作業者(OS スレッド)のチーム全体を立ち上げるソフトウェアを構築します。また、いつでも誰かを優先させるために任意の作業者を停止できる「交通整理係」(ランタイム)も備えています。
古いツール: Zorya は、静かで単一作業者の工場を検査するために使われていました。それが忙しく多作業者の工場を調べようとしたとき、誰が何をしているのか、あるいは作業者がどこに立っているのかを把握できませんでした。
目標: Zorya を賢くして、混沌を一時停止し、すべての作業者のスナップショットを撮影し、迷わずに作業を慎重に検査できるようにすることです。
2. 解決策:3 つの新しいスーパーパワー
著者たちは、この巨大な工場に対処するために Zorya に 3 つの新しい技を与えました。
「タイムトラベル・スナップショット」(スレッド状態の復元): 工場がフルスピードで稼働していると想像してください。作業者の動きをリアルタイムで追おうとするのではなく(それは速すぎて混乱を招きます)、新しい Zorya は「一時停止」ボタンを押し、すべての作業者の両手、道具、位置を高精細で撮影して保存します。検査を開始する際、これらの写真を読み込んで、開始前のすべての人の位置を正確に把握します。これにより、「交通整理係」の混沌を無視し、実際のコードに集中することが可能になります。
「もしも」の鏡(オーバーレイ経路分析): 通常、作業者が道の分岐点に到達すると、一方の道を選んで歩き、もう一方の道は無視されます。
古い方法: Zorya は、作業者が実際に通った道しかチェックしませんでした。
新しい方法: Zorya は工場の「ゴーストの鏡」を作成します。作業者が左の道を選んだとき、Zorya は「ゴースト作業者」を右の道に数歩だけ送り込みます。実際に歩かずに、その道に罠(床の穴や壊れた道具など)があるかを確認します。ゴーストが罠を見つけると、Zorya は警報を鳴らします。これはコピー・オン・ライト と呼ばれ、ゴーストが触れる部分のみをコピーするため、膨大なエネルギーを節約します。
「静かな罠」検出器: 一部の罠は、クラッシュやパニックのような大きな音を立てません。例えば、数値が大きくなりすぎて「ラップアラウンド」し、再び小さくなることで、静かに数学を破綻させるような場合です。他のツールは、大きなクラッシュのみを検索するため、これらを見逃してしまいます。Zorya は、頭の中で数学を行う超スマートな数学脳(SMT ソルバ )を使用します。プログラムがクラッシュしなくても、「もしこの数値が大きくなれば、数学が静かに破綻する」と判断できます。
3. 検証:現実のバグの発見
チームは、Kubernetes、Go-Ethereum、CoreDNS などの有名なソフトウェアで見つかった11 の現実のセキュリティホール に対して、このアップグレードされた Zorya をテストしました。彼らは、Zorya を、コードを文法チェックのように読む静的チェッカー、ソフトウェアにランダムなデータを投げつけるファズャー、および他のセキュリティスキャナなどの他のツールと比較しました。
結果:
Zorya は 11 個のバグのうち 7 個を発見しました。
「静かな」勝利: Zorya が見つけたバグの一つは、「静かな整数オーバーフロー」でした。これはプログラムをクラッシュさせず、警報も発しない数学的なエラーでした。他のツールは、誰かが具体的に何を探すべきかをマニュアルで指示しない限り、このバグを見つけることができませんでした。 Zorya は自動的にこれを発見しました。
トレードオフ: Zorya は「ランダムなデータを投げる」ツール(ファズャー)よりも遅いです。ファズャーが数秒でクラッシュを見つける可能性があるのに対し、Zorya がバグを見つけるには約 16 分かかります。ただし、Zorya は各関数ごとに人間が特定のテストスクリプトを書く必要はなく、バイナリファイルを直接分析するだけです。
4. 結論
この論文は、高度な「ゴースト作業者」による検査を用いることで、複雑なマルチスレッド Go ソフトウェアの奥深くに隠れたセキュリティホールを発見できるようになったことを示しています。他の方法よりも少し時間がかかりますが、他のツールが完全に見逃す「静かな」バグを見つけることができ、デジタルインフラをより安全にします。
要約すると: 彼らはセキュリティロボットに、混沌とした工場を一時停止し、作業者のスナップショットを撮影し、誰も歩いていない経路をチェックする方法を教えました。これにより、以前は見えなかった隠れた罠を成功裏に見つけ出すことに成功しました。
技術的サマリー:TinyGo から gc コンパイラへ:Zorya のコンコリックフレームワークを実世界の Go バイナリへ拡張
問題定義
標準の gc コンパイラでコンパイルされた Go バイナリのセキュリティ分析は、依然として重大な課題です。TinyGo でコンパイルされたバイナリ(単一スレッドの実行可能ファイルで最小限のランタイムを生成するもの)とは異なり、gc コンパイルバイナリは、複数の OS スレッドにわたる goroutine、ガベージコレクション、およびプリエンプティブなスケジューリングを管理する複雑なランタイムを利用します。既存のシンボリック実行ツール(KLEE、angr、Radius2 など)は主に C/C++ 向けに設計されており、Go が完全にコンパイルされない LLVM 中間表現(IR)に依存しています。さらに、これらのツールは、協調的/非同期プリエンプション、goroutine スケジューリング、メモリマップド VDSO 関数などの Go 固有のランタイム機構をモデル化できず、本番環境の Go バイナリに対して効果的ではありません。Zorya フレームワークの以前のバージョンは TinyGo バイナリに限定されており、実世界のマルチスレッド Go アプリケーションの分析におけるギャップが残されていました。
手法
本論文は、コンパイルされたバイナリを Ghidra の P-Code 中間表現にリフトするコンコリック実行フレームワークであるZorya の拡張を提示します。この拡張は、以下の 3 つの主要な技術的メカニズムを通じて、マルチスレッドの gc コンパイルバイナリの分析を可能にします。
マルチスレッド状態の復元とスケジューリング:
Zorya は初期化時に gdb ダンプからすべての OS スレッドの状態を復元し、レジスタ状態、スレッドローカルストレージ(TLS)ベース、およびバックトレースを捕捉します。
スレッドは(メインスレッド、システムモニター、待機中など)分類され、スケジューリングを容易にします。
フレームワークはランタイムプリエンプションを無効化し、関数モード分析に対して「メイン専用」のスケジューリングポリシーを採用します。これにより、ガベージコレクションやシステムモニターからの中断を避けて、メインスレッドに限定したコンコリック実行が可能となり、ユーザーレベルの関数の継続的な探索を可能にします。
コピーオンライト(CoW)セマンティクスを備えたオーバーレイパス分析:
パス爆発に対処し、状態全体をフォークすることなく(gc バイナリでは 1 GiB を超える可能性があります)未実行の分岐を推論するために、Zorya はオーバーレイ機構を実装しています。
条件分岐が追跡されたシンボリック変数を含む場合、未実行パスに対して軽量なオーバーレイが作成されます。読み取りはまずオーバーレイを参照し、ヒットしない場合は基本状態にフォールバックします。書き込みはオーバーレイにのみ行われます。
このオーバーレイは、既定で N = 15 N=15 N = 15 の命令数を制限して実行された後破棄され、コンクリートなトレースによって実行されなかったパス上の脆弱性を検出することを可能にします。
アナライザルーチンによる脆弱性検出:
フレームワークは、gdb ダンプからの具体的な値と Z3 SMT ソルバーによって管理されるシンボリック表現の両方を使用して命令を実行します。
「アナライザルーチン」は、各命令において、ヌルポインタの逆参照、整数オーバーフロー、ゼロ除算などの脆弱性パターンをチェックします。
gc バイナリの場合、システムは明示的なパニック呼び出しの位置特定のための AST 探索と、ランタイムパニックをトリガーしないサイレントな脆弱性の検出のためのオーバーレイ実行の両方を活用します。
主な貢献
gc バイナリへの拡張: フレームワークは、標準 Go コンパイラによって生成されたマルチスレッドバイナリの分析に拡張され、研究ツールと本番環境の Go ソフトウェア間のギャップを埋めました。
実世界の脆弱性データセット: 著者は、Kubernetes、Go-Ethereum、CoreDNS などを含む本番プロジェクトからの 11 の実世界の脆弱性のコーパスを編纂し、再現ワークフローとトリガー入力を含めました。
比較評価: Zorya は、7 つの最先端ツール(3 つの静的アナライザ、2 つのファズャ、2 つのバイナリレベルのシンボリック実行エンジン)に対して評価されました。
サイレント脆弱性の検出: フレームワークは、手書きのオラクルを必要とすることなく、ランタイムパニックをトリガーしない脆弱性、具体的にはサイレントな整数オーバーフローを正常に検出しました。
結果
評価は、ヌルポインタ逆参照、整数オーバーフロー、インデックス範囲外という 3 つのクラスにわたる 11 の実世界の脆弱性に対して行われました。
検出率: Zorya は 11 の脆弱性のうち7 つ を検出しました。
4 つ は、コンクリート(実行された)パス上でアナライザルーチンによって捕捉されました。
3 つ は、未実行分岐上での AST パンクリーチアビリティによって特定されました。
2 つ の副次的な発見は、未実行パス上でのオーバーレイ実行(15 命令の深さ制限内で検出)によって表面化しました。
独自の検出: Zorya は、Go-Ethereum (v1.6.0) の memoryGasCost 関数におけるサイレントな整数オーバーフローを検出した唯一のツールでした。このバグは、Go の符号なし演算で静かにラップする乗算を含み、攻撃者がほぼゼロのガスで莫大なメモリを割り当てられるようにします。手書きのオラクルなしでこのバグを検出した評価されたツールはありませんでした。
ツール比較:
静的アナライザ(staticcheck, gosec, nilaway): 11 のバグのうち 0 個を検出しました。gosec は同種演算オーバーフローを見落とし、nilaway は依存関係解決の問題により Kubernetes パッケージで失敗しました。
ファズャ(go test -fuzz, GoLibAFL): 11 のバグのうち 5 個(Zorya が runtime.memmove のシンボリック実行におけるリソース枯渇により見落とした kube-sm-2025 を含む)を検出しました。ファズャは高速(平均約 0.18 秒から 7 秒)でしたが、手書きのハーネスを必要とし、クラッシュしないサイレントな脆弱性を見逃しました。
他のシンボリック実行エンジン(BINSEC, SymQEMU): Go ランタイムプリミティブのサポート不足を主な理由として、11 のバグのうち 0 個を検出しました。
パフォーマンス: Zorya の検出あたりの平均時間は 16.5 分であり、ファズャに比べて著しく遅いですが、完全な命令レベルの実行トレースを提供し、ハーネスなしで完全に自動的に動作します。
意義と主張
本論文は、Zorya が Go のセキュリティ分野における重要なギャップに対処していると主張しています。静的アナライザはプログラム固有の算術とエイリアシングを推論できず、ファズャは手書きのハーネスを必要とし、クラッシュしないバグを見逃すのに対し、Zorya はサイレントな脆弱性を検出可能な完全自動のバイナリレベル分析を提供します。
著者は、Zorya を、Go バイナリに特化した微細なオーバーレイ探索、マルチスレッド初期状態の復元、およびサイレントオーバーフロー検出を組み合わせたツールとして位置付けています。この研究は、コンコリック実行が標準 Go コンパイラの複雑なマルチスレッドランタイムに適応可能であることを実証し、他の評価ツールには見えない脆弱性(サイレントな整数オーバーフローなど)の検出を可能にしました。論文は、Zorya はファズングよりも遅いものの、正確な命令レベルのトレースを提供し、クラッシュしないバグを検出する能力により、ソフトウェアセキュリティエンジニアリングのツールキットに貴重な追加をもたらすと結論付けています。
毎週最高の computer science 論文をお届け。
スタンフォード、ケンブリッジ、フランス科学アカデミーの研究者に信頼されています。
受信トレイを確認して登録を完了してください。
問題が発生しました。もう一度お試しください。
スパムなし、いつでも解除可能。
週刊ダイジェスト — 最新の研究をわかりやすく。 登録 ×