事件概览
3+
年潜伏期
CVSS 10
最高评分
SSH
攻击目标
glibc
依赖系统
这不是一次普通的漏洞,而是一场「完美犯罪」
攻击者(化名 Jia Tan)从 2021 年起就开始向 xz 项目贡献代码,逐步获得维护者信任,最终在 2024 年 2 月成为项目共同维护者。随后,ta 向发布的 tarball 和 Git 仓库中植入了极其隐蔽的后门代码。后门仅在特定构建条件下激活,并通过
libsystemd 的依赖链感染 sshd,从而可能实现未经授权的远程访问或代码执行。
事件时间线
2021 - 2023
长期潜伏,建立信任
攻击者以 Jia Tan 的身份向 xz 项目提交无害的补丁,参与邮件列表讨论,逐步赢得原维护者 Lasse Collin 的信任。期间还使用多个马甲账号在社区中施压,要求加快项目更新节奏。
2024年1月 - 2月
获得维护权限
Jia Tan 成为 xz 项目的共同维护者(co-maintainer),获得了直接向仓库推送代码和发布版本的权限。这是供应链攻击中最关键的一步。
2024年2月 - 3月
后门植入与发布
发布了 xz 5.6.0 和 5.6.1,其中包含了经过高度混淆的后门代码。后门存在于发布的 tarball 中,以及 Git 仓库的测试文件
bad-3-corrupt_lzma2.xz 和 good-large_compressed.lzma 里。
2024年3月29日
惊天发现
PostgreSQL 开发者 Andres Freund 在调试 Debian sid 上 SSH 登录变慢的问题时,通过
perf 和 valgrind 追踪到了 liblzma 中的异常行为,最终确认了这是一个上游后门。他在 oss-security 邮件列表上公布了这一发现。
2024年3月29日后
全球应急响应
Red Hat 分配了 CVE-2024-3094。各大发行版紧急回滚 xz 版本。GitHub 封禁了相关账号和仓库。这一事件引发了开源社区对软件供应链安全的深刻反思。
技术原理
1. 双重植入:Tarball + 仓库
后门分两部分存在:发布 tarball 中的
m4/build-to-host.m4 会在 configure 阶段注入恶意脚本;而 Git 仓库中的测试文件(.xz 和 .lzma)则包含了真正的二进制载荷。这些测试文件在 5.6.0 中甚至根本没有被任何测试调用。
2. 构建时激活条件
后门脚本在 configure 结束时运行,只有满足以下全部条件才会注入恶意代码:
- 目标架构为 x86_64
- 目标系统为 Linux (linux-gnu)
- 使用 GCC 编译器和 GNU ld 链接器
- 构建环境是 Debian 或 RPM 包构建(通过检测
debian/rules或RPM_ARCH)
这些限制使得普通开发者很难在本地复现问题,从而大大延缓了被发现的时间。
3. 运行时劫持机制
后门利用 GNU IFUNC(Indirect Function Call)机制,在动态链接器解析符号时劫持控制流:
- 替换
crc32_resolve()和crc64_resolve()的 IFUNC resolver - 在
crc64_resolve()的第二次调用时执行环境检查(TERM、argv[0]、LD_DEBUG 等) - 向动态链接器注册一个 audit hook
- 当
RSA_public_decrypt@....plt被解析时,将其 GOT/PLT 条目重定向到后门代码 - 随后卸载 audit hook,抹除痕迹
# 后门修改后的 GOT/PLT 调用链示例(perf trace)
ssh_rsa_verify+0x49c => RSA_public_decrypt@plt
# 此时 RSA_public_decrypt 已被重定向到后门代码
[liblzma.so] => RSA_get0_key+0x0 [libcrypto.so]
# 后门调用回 libcrypto,表面上完成正常认证
4. SSH 攻击路径
OpenSSH 本身并不依赖 liblzma,但 Debian 等多个发行版为了支持 systemd notification,对 OpenSSH 进行了补丁修改。而
libsystemd 依赖 liblzma,这就形成了完整的攻击链路:
sshd
→ libsystemd.so
→ liblzma.so.5.6.0 (被植入后门)
→ 劫持 RSA_public_decrypt@plt
→ 在预认证阶段执行恶意代码
→ 可能实现未授权远程访问 / RCE
关键威胁:后门在 SSH 的预认证(pre-authentication)阶段运行。这意味着攻击者甚至不需要有效的凭据,就可能通过特定的认证请求触发后门,获取系统访问权限。
发现过程:一个开发者的直觉
"After observing a few odd symptoms around liblzma on Debian sid installations over the last weeks (logins with ssh taking a lot of CPU, valgrind errors) I figured out the answer: The upstream xz repository and the xz tarballs have been backdoored."
异常现象:SSH 登录变慢
在受影响的系统上,一次失败的 SSH 登录从正常的 ~0.3 秒延长到了 ~0.8 秒。这个细微的性能回退引起了 Andres Freund 的注意。
Valgrind 报错
使用 Valgrind 运行 sshd 时出现了不寻常的错误,这表明 liblzma 的内存布局或执行流存在问题——而这些问题在 5.6.1 的"修复"提交中反而被进一步掩盖。
perf + Intel PT 追踪
Andres 使用
perf record -e intel_pt//ub 对比了有/无后门时的执行路径差异,精准定位到了 IFUNC resolver 和 audit hook 的异常行为。
反混淆与提取
通过分析 build-to-host.m4 注入的脚本,剥离了多层混淆(sed、tr、xz 解压、bash 执行),最终提取出了完整的后门载荷。
影响与反思
幸运中的不幸
幸运的是,xz 5.6.0/5.6.1 尚未被大多数稳定版 Linux 发行版广泛采用,主要出现在 Fedora Rawhide、Debian sid/testing、openSUSE Tumbleweed 等滚动/测试版本中。如果这次攻击再晚几个月被发现,后果将不堪设想——全球数以百万计的服务器可能都会暴露在未授权访问的风险之下。
开源社区的警钟
这次事件暴露了开源软件供应链中的多个脆弱环节:
- 维护者倦怠:长期由单人维护的关键基础库极易被渗透
- 社会工程学:攻击者通过"帮忙分担工作"的方式逐步获取权限
- 构建系统盲区:tarball 与 Git 源码不一致,很少有人检查
- 测试文件滥用:二进制测试文件成了藏匿恶意代码的「特洛伊木马」
- 签名验证缺失:很多发行版和开发者没有严格校验发布物的签名
如何检测与防护
检测命令示例
Andres Freund 和 Vegard Nossum 提供的检测脚本核心逻辑:
# 检查 sshd 是否链接了受感染的 liblzma
ldd $(which sshd) | grep lzma
# 快速检测:查看 liblzma 中是否包含可疑字符串/函数
strings /usr/lib/x86_64-linux-gnu/liblzma.so.5.6.0 | \
grep -E 'RSA_public_decrypt|get_cpuid|crc64_resolve'
更可靠的检测方式是直接降级 xz 到 5.4.x 版本,并监控 SSH 登录延迟是否恢复正常。