安全でないMarshal.loadをコマンド実行に変える新たなRuby RCEガジェットチェーン

新たに公開されたユニバーサルデシリアライゼーションガジェットチェーンは、たった一つの安全でないMarshal.load操作が、Ruby 4.0.6においてリモートコマンド実行につながることを示しています。

このチェーンは、報告によればRuby 3.3までさかのぼるバージョンでも変更なしに動作するとされており、信頼できないデータにさらされた場合、Rubyのネイティブなシリアライゼーション機構が依然として高リスクな攻撃対象領域であるという懸念を改めて浮き彫りにしています。

この研究は、Ruby on Railsを標的とした過去のチェーンを含むYAML.load、RubyGems、標準ライブラリに対する10年以上にわたるRubyデシリアライゼーション攻撃の研究の積み重ねの上に成り立っています。

Ruby 3.4での変更によって動作しなくなった従来の概念実証(PoC)とは異なり、今回のチェーンはRubyGemsとコア言語機能の新たな組み合わせを利用しており、アプリケーション固有の依存関係やターゲットホスト上に事前に存在するファイルを必要とせずにコードを実行できます。

大まかに言えば、この攻撃はRubyのオブジェクト再構築プロセスを悪用するものです。Marshal.loadはシリアライズされたオブジェクトを復元する際、デシリアライゼーション中にクラスの読み込み、メソッド呼び出し、オブジェクト状態の復元をトリガーすることがあります。

報告によると、新しいチェーンはまずGem::SpecFetcherを参照することから始まり、これによりRubyGemsのオートロード機能が働いて、本来は最小限のRubyプロセスにおいても追加のクラスが利用可能になります。この攻撃は、攻撃者が制御するコンテンツを取得することと、それをRubyコードとして評価することという二つの機能を組み合わせています。

生き残っているRubyGemsのガジェットは、攻撃者が管理するHTTPSサーバーから圧縮されたコンテンツを取得し、解凍した結果を/tmpのような予測可能な書き込み可能な場所に書き込むことができます。

別のGem::StubSpecificationオブジェクトが、書き込まれたそのファイルに対してRubyGemsにGem::Specification.loadを呼び出させます。Gem::Specification.loadは対象ファイルを読み込み、Rubyのeval機能を使ってその内容を評価します。

その結果、攻撃者がダウンロードされるファイルとその書き込み先パスの両方を制御できる場合、デシリアライゼーションの流れの中で、影響を受けるアプリケーションの権限で任意のRuby文が実行される可能性があります。

このチェーンには特に注目すべき性質が二つあります。一つ目は、期待される例外を抑え込みながらTimeのデシリアライゼーションを利用してダウンロード動作をトリガーする点です。

報告によれば、このプロセスは細工された値を変換パスに通し、最終的に攻撃者が制御するオブジェクトのメソッドを呼び出すとされています。二つ目は、標準的なハッシュの挙動を実行トリガーとして利用する点です。

RubyがMarshal.load中にHashを再構築する際、復元されたキーのハッシュ値を計算します。そのため、キーとして使われる細工済みのGem::StubSpecificationは自身のhashメソッドを呼び出させることができ、最終的にファイルの読み込みと評価のパスに到達します。

こうしたトリガーは、対象を絞り込んだ従来のRubyGemsガジェットに比べて排除が難しいものです。これまでのRubyGemsの修正では、型チェックの追加や攻撃者が制御可能な実行パスの除去によって既知のチェーンを塞いできました。

しかし、Luke Jahnke氏は、ハッシュキー処理や許容度の高いTime復元といったコアの挙動は、期待される言語仕様を壊すことなく取り除くことはできないと述べています。実際の影響は、攻撃者がRubyのMarshalデータを提供または操作できる場所であればどこでも深刻なものとなります。

脆弱なサービスは、到達可能な攻撃者管理下のHTTPSホストと書き込み可能なディレクトリへのアクセスさえあれば悪用され得るものであり、必ずしもサードパーティ製のgem、事前に存在するファイル、アプリケーション固有のガジェットクラスを必要としません。

組織は、信頼できない入力に対するMarshal.loadの使用を、直接的なコード実行と同等のリスクとして扱うべきです。

シリアライズされたデータが必要な場合、チームは厳格なスキーマと明示的な型検証を伴う、JSONのようなデータのみを扱う形式へ移行すべきです。

既存のRubyアプリケーションについては、Marshal.loadMarshal.restoreYAML.load、および関連する安全でないデシリアライゼーションのパスがないか監査を行うべきです。また、インシデント対応担当者は、通常とは異なる外向きのHTTPSリクエスト、一時ディレクトリ配下への予期しない書き込み、コマンドを生成するRubyプロセスに注意を払う必要があります。

ANY.RUNのブラウザ内データ検査で、検知・調査・対応をより迅速に。フィッシングの可視性を完全に確保し、SOCを強化してMTTRを削減しましょう

翻訳元: https://cyberpress.org/new-ruby-rce-gadget-chain-marshal-load-command-execution/

ソース: cyberpress.org