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]

核心概念与专有名词

发布归档(release tarball)
项目为安装或打包而发布的源代码归档。它可能与从版本库检出的文件不同,因此应作为独立工件核验。[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]

源代码对比:漏洞与安全实现

存在漏洞的实现
# 接收下载的构建输入,却不证明其身份。
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。

# 这能发现制品被调包,却发现不了获授权但含恶意内容的发布包;受影响软件包应按指导处理。

工程与系统安全加固清单

参考来源