FlawOpen

flawopen.com/Incidents/xz-utils-backdoor-march-2024

● Xz · CVE-2024-3094 · March 2024 · CVSS 10.0 · 緊急
セキュリティ研究 · FlawOpen

XZ Utils サプライチェーン侵害(CVE-2024-3094)

CVE-2024-3094 は XZ Utils 5.6.0/5.6.1 に影響。影響はディストリビューションのビルド条件に依存するため、該当パッケージを特定して置き換えてください。[1], [3], [4], [5], [6]

CVSS ベクトルCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H[9]
💡 わかりやすい解説 (ELI5)

ソースリポジトリを公開されたレシピ、リリースアーカイブを封をした食材箱だと考えてください。レシピが正しく見えても、厨房は箱の封印と納品書を確認します。同じ料理名が書かれているだけで、箱をそのまま調理台に載せてはいけません。別の信頼できる経路で認証したマニフェストは箱のすり替えを検出できますが、有効な提供元の署名でも、正規に承認された箱が安全だとは証明できません。侵害された XZ の箱も公式リリースでした。対象パッケージはディストリビューションの案内に従って置き換え、マニフェスト検証はすり替え対策としてのみ別に使ってください。[5], [6]

主要な概念と専門用語

リリースアーカイブ
インストールまたはパッケージ化のために配布されるソースコードのアーカイブです。リポジトリから取得したファイルと異なる場合があるため、別個の成果物として検証します。[3], [4], [6]
ビルド来歴(build provenance)
成果物が、どのレビュー済みソース、ビルド手順、公開者から来たかを示す記録です。ダウンロードしたものを信頼してよいか判断できます。[5], [6]
成果物検証(artifact verification)
成果物をビルドや公開に使う前に、ハッシュまたは署名を、独立した信頼経路で入手した期待値と照合することです。

フレームワーク対応

  • このガイドで説明する弱点の CWE 参照: CWE-506

インシデントのタイムライン

2024年2月24日

XZ 5.6.0 がリリースされました。プロジェクトの後の説明では、そのリリースアーカイブにバックドアが含まれていたとされています。[3], [6]

2024年3月9日

XZ 5.6.1 がリリースされました。同じ説明では、そのリリースアーカイブにバックドアが含まれていたとされています。[4], [6]

2024年3月29日より前

異常な SSH CPU 使用率と Valgrind エラーが調査を促した後、Freund は配布アーカイブにあり対応する上流ソースファイルにはない注入済みビルドスクリプトを報告しました。[5], [6]

2024年3月29日

Andres Freund が問題を公開報告しました。[5]

ステップ・バイ・ステップの攻撃フロー

ステップ 1

リポジトリと配布物は同一ではない

公開された分析は、配布アーカイブに上流リポジトリの対応ファイルとは異なるビルドスクリプトが含まれていたと説明しています。リポジトリのコミットだけを確認しても、アーカイブの安全性は証明できません。[5], [6]

ステップ 2

影響はビルド経路に依存する

この問題は特定のパッケージ化とビルドの条件で生じました。公式の報告は Git からのビルドでは該当コードが注入されないと説明しており、全ての XZ または Linux インストールへ一般化してはいけません。[5], [6]

ステップ 3

異常が調査の端緒になった

Andres Freund は SSH プロセスの異常な CPU 使用率と Valgrind のエラーを報告しました。観測可能な異常が、調査と公開につながりました。[5]

ステップ 4

対応は置換と検証から始める

この事案は、影響を受けたパッケージとビルド来歴の問題として扱ってください。ディストリビューションの案内に従って対象パッケージを置き換えます。今後の成果物では来歴と署名を検証してください。これはすり替えの検出には役立ちますが、正規に承認されたリリースが無害だとは証明できません。[1], [6]

ソースコード比較:脆弱 vs 堅牢化

脆弱な実装
# ダウンロードしたビルド入力を、その身元を証明せずに受け入れる。
from pathlib import Path

def stage_release(artifact: Path, build_inputs: Path) -> None:
    build_inputs.joinpath(artifact.name).write_bytes(artifact.read_bytes())

# コピーが成功しても、そのアーカイブがレビュー済みの
# リリースまたは信頼できるマニフェストに対応するとは証明できない。
堅牢化されたセキュアパッチ
# 教育用のゲート: 信頼できるマニフェストの期待 SHA-256 を検証する。
import hashlib
import hmac
from pathlib import Path

def verify_release(artifact: Path, expected_sha256: str) -> None:
    digest = hashlib.sha256(artifact.read_bytes()).hexdigest()
    if not hmac.compare_digest(digest, expected_sha256.lower()):
        raise ValueError("リリース成果物が信頼できるマニフェストと一致しません")

# expected_sha256 は別途認証された公開経路から入手し、
# アーカイブをビルド入力にする前に verify_release を呼び出す。

# これはすり替えを検出しますが、正規に承認された悪意あるリリースは検出できません。対象パッケージは提供元の案内に従ってください。

エンジニアリング&システム堅牢化チェックリスト

参考資料