xz后门黑客潜伏时间线,开源软件供应链安全分水岭 |笔记
“开源软件供应链投毒案”
“几乎撬开了保险金库的大门”
“2024安全界第一大瓜”
“核弹级漏洞”
说的是发生在软件开源社区潜伏的故事。
过去近两年半的时间里,有位名叫“Jia Tan”的成为xz压缩库的贡献者,工作勤奋、责任心强,最终获得了提交访问权限和维护者身份。
xz是非常基础的压缩组件,开源操作系统Linux的软件基本上都会默认安装。
利用这些权限,Jia Tan在xz的核心组件liblzma中精心安装了一个非常隐蔽的后门,而基于systemd的Linux系统上OpenSSH sshd都要依赖liblzma。sshd是应用最广泛的远程控制服务。
该后门为攻击者监控在SSH发送的隐藏命令,使攻击者能够在不登录的情况下在目标系统上执行任意命令:未经身份验证的、有针对性的远程代码执行,可以导致完全控制目标系统。该漏洞的危险性评为10分,意味着它具有极高的风险等级。
这个漏洞差一点点就流入Linux各个发行版中,如果成功被植入,将会造成非常可怕的后果,相当于有人拿了一把万能钥匙,可以随时进出金库的大门,可能给全球各个行业带来难以估量的损失,因为大部分行业后端服务器用的操作系统都是Linux的各个发行版,像Redhat、Ubuntu、Fedora等。
更令人担忧的是,这个漏洞是被偶然发现的。一个名叫Andres Freund的微软安全研究员观察到在 Debian sid 安装使用 liblzma时出现了一些异常状况,通过 SSH 登录时 CPU 使用率异常高,他对 sshd 进行分析,显示 liblzma 占用了很多 CPU 时间,但无法将其归因于任何符号。最终Freund发现上游 xz 仓库和发布的 xz 压缩包被植入了后门。至此,潜伏两年半的攻击于2024年3月29日败露。
这是针对开源软件供应链的首次严重攻击,可能标志着开源软件供应链安全的一个转折点。
一些流行的开源软件,维护是建立在志愿开发者的基础之上,而全球的一些大公司和重要机构都使用这些软件。知名开发者Tim Bray尖锐地指出:如此重要的软件维护者都是志愿者,而那些恶意的黑客都通过攻击赚了大钱。开源软件基础设施,面对有组织的攻击是脆弱的。他主张建立一个“开源质量学院”,提升重要开源软件的品质和安全。“开源软件已经成为我们文明的基座平台”。
xz 后门事件也标志着开源软件中基于自愿信任的分享基础遭到侵蚀。以往的漏洞几乎是贡献者没有考虑周到,也就是说是无心造成的,但这次有人处心积虑自己植入后门,令整个开源界感到震惊和后怕。
整个开源界都在思考应该吸取什么教训,如何堵住漏洞。开源项目及其贡献者可能会面临更加严格的审查,以确保代码的安全性和可靠性。未来开源社区可能会寻求更好的方法来监控和审计代码变更,例如通过AI工具和更全面的代码审查流程。
Jia Tan是谁?他在过去的两年半中是如何潜伏,一步一步地获取权限,并植下后门的?
Research.swtch.com网站梳理了这次攻击的详细时间线,从社会工程方面来看,Jia Tan使命似乎可以追溯到2021年底。如下:
序幕
2005–2008年:Lasse Collin在其他人的帮助下,使用LZMA压缩算法设计了.xz文件格式,该格式将文件压缩到gzip的约70%大小。随着时间的推移,这种格式广泛用于压缩tar文件、Linux内核镜像以及其他许多用途。
Jia Tan登场,还有神秘的助攻者
2021年10月29日:Jia Tan向xz-devel邮件列表发送了第一个无害的补丁,添加了“.editorconfig”文件。
2021年11月29日:Jia Tan向xz-devel邮件列表发送了第二个无害的补丁,修复了一个明显的可重现构建问题。随后(即使回顾起来)也发送了更多看似无害的补丁。
2022年4月19日:Jia Tan向xz-devel邮件列表发送了又一个无害的补丁。
2022年4月22日:“Jigar Kumar”发送了第一封电子邮件,抱怨Jia Tan的补丁没有被合并。(“补丁在这份邮件列表上待了多年。没有理由认为近期会有任何进展。”)此时,Lasse Collin已经合并了Jia Tan的四个补丁,还在提交信息中标记了“感谢Jia Tan”。
2022年5月19日:“Dennis Ens”向xz-devel发送邮件询问XZ for Java是否得到维护。
2022年5月19日:Lasse Collin回复道歉,并表示“Jia Tan已经在名单外帮助我处理XZ Utils,他未来至少在XZ Utils方面可能会发挥更大作用。很明显,我的资源太有限了(因此有很多邮件等待回复),所以长期来看必须有所改变。”
2022年5月27日:Jigar Kumar向补丁线程发邮件施压。“超过一个月了,合并的进展并不顺利。这一点都不令人意外。”
2022年6月7日:Jigar Kumar把压力邮件发到了Java线程。“除非有新的维护者,否则不会有进展。XZ for C的提交日志也很稀疏。Dennis,你最好等到新的维护者出现,或者自己分叉。现在提交补丁没有意义。当前的维护者已经失去了兴趣,或者不再关心维护了。对于这样的仓库来说,这是令人悲哀的。”
2022年6月8日:Lasse Collin反驳道:“我没有失去兴趣,但我的关心能力受到了相当大的限制,主要是因为长期的精神健康问题,也因为其他一些事情。最近我与Jia Tan在名单外稍微合作了一下XZ Utils,也许他将来会发挥更大作用,我们会看到的。也要提醒一下,这毕竟是个无偿的业余项目。”
2022年6月10日:Lasse Collin在git元数据中合并了Jia Tan作为作者的第一个提交(“测试:为硬件功能创建测试”)。
2022年6月14日:Jugar Kumar发送压力邮件。“按照你目前的速度,我非常怀疑今年会看到5.4.0版本。自四月以来唯一的进展就是对测试代码的小幅修改。你忽略了邮件列表上许多正在腐烂的补丁。现在你正在限制你的仓库。为什么要等到5.4.0才更换维护者?为什么要拖延你的仓库需要的东西?”
2022年6月21日:Dennis Ens发送压力邮件。“对于你的精神健康问题,我表示遗憾,但了解自己的极限很重要。我知道这对于所有贡献者来说都是一个业余项目,但社区希望得到更多。为什么不把XZ for C的维护权交出去,这样你就可以给XZ for Java更多的关注?或者把XZ for Java的维护权传给别人,专注于XZ for C?试图同时维护两者,两者都维护不好。”
2022年6月22日:Jigar Kumar向C补丁线程发送压力邮件。“这方面有任何进展吗?Jia,我看到你最近又有提交。为什么你自己不能提交这个?”
2022年6月29日:Lasse Collin回复:“正如我之前在邮件中暗示的,Jia Tan未来可能会在项目中扮演更重要的角色。他已经在名单外出力很多,实际上已经是共同维护者了。:-) 我知道git仓库里还没有太多变化,但事情会一步步来。无论如何,至少对于XZ Utils,维护权的某种变化已经在进行中。”
Jia Tan成为维护者
此时,Lasse似乎开始与Jia Tan更紧密地合作。Evan Boehs观察到,Jigar Kumar和Dennis Ens都有nameNNN@mailhost的电子邮件地址,这些地址从未在互联网上的其他地方或xz-devel中再次出现过。他俩很可能是虚构出来的假身份,用来推动Lasse给予Jia更多的控制权。这一招很奏效。在接下来的几个月里,Jia开始在xz-devel上权威地回复关于即将发布的5.4.0版本的讨论。
2022年9月27日:Jia Tan为5.4.0版本提供了发布摘要。(“计划在12月发布的5.4.0版本将包含多线程解码器。我正在跟踪的与5.4.0相关的开放问题列表是...”)
2022年11月30日:Lasse Collin将bug报告电子邮件从他的个人地址更改为一个转给他和Jia Tan的别名,并在README中注明“项目维护者Lasse Collin和Jia Tan可以通过xz@tukaani.org联系”。
2022年12月30日:Jia Tan直接把第一个提交并入xz仓库(“CMake: 更新.gitignore,以包含CMake构建中的CMake工件”)。
至此,我们知道Jia Tan有提交权限了。
2023年1月11日:Lasse Collin标记并构建了他的最终版本,v5.4.1。
2023年3月18日:Jia Tan标记并构建了他们的第一个版本,v5.4.2。
2023年3月20日:Jia Tan更新了Google oss-fuzz配置,将漏洞发送给他们。
2023年6月22日:Hans Jansen发送了一对补丁,由Lasse Collin合并,这些补丁使用了“GNU间接函数”功能在启动时选择一个快速的CRC函数。最终的提交由Lasse Collin重新加工,并由Jia Tan合并。这个变化很重要,因为它安插了一个接口,后门代码可以通过它在全局函数表被映射为只读之前修改它们。虽然这个变化本身可能是一个无害的性能优化,但Hans Jansen在2024年返回来推广带有后门的xz,并且在互联网上不存在其他信息。
2023年7月7日:Jia Tan在oss-fuzz构建期间禁用了ifunc支持,声称ifunc与地址 sanitizer不兼容。这本身可能是无害的,尽管它也是为以后使用ifunc做更多的准备工作。
2024年1月19日:Jia Tan将网站移至GitHub pages,从而控制了XZ Utils网页。Lasse Collin可能为指向GitHub pages的xz.tukaani.org子域创建了DNS记录。在攻击被发现后,Lasse Collin删除了这个DNS记录,回到了他控制的tukaani.org。
攻击开始
2024年2月23日:Jia Tan合并了隐藏的后门二进制代码,这些代码很好地隐藏在一些二进制测试输入文件中。README已经说明了(远在Jia Tan出现之前)“这个目录包含了一堆文件,用于测试解码器实现中.xz、.lzma(LZMA_Alone)和.lz(lzip)文件的处理。许多文件是手工用十六进制编辑器创建的,因此没有比这些文件本身更好的‘源代码’了。”拥有这种测试文件对于这种类型的库来说司空见惯。Jia Tan利用这一点添加了一些不会被仔细审查的文件。
2024年2月24日:Jia Tan标记并构建了v5.6.0,并发布了xz-5.6.0.tar.gz软件分发包,带有额外的、恶意的构建至目标主机的(build-to-host).m4,该m4文件在构建deb/rpm包时添加了后门。这个m4文件不在源代码仓库中,但许多其他合法的文件也会在包中添加,所以它本身并不可疑。但是脚本已经从通常的副本中修改以添加后门。
2024年2月24日:Gentoo开始在5.6.0中看到崩溃。这似乎是一个实际的ifunc bug,而不是隐藏后门中的bug,因为这是第一个带有Hans Jansen的ifunc变化的xz。
2024年2月26日:Debian将xz-utils 5.6.0-0.1添加到不稳定版本中。
2024年2月28日:Debian将xz-utils 5.6.0-0.2添加到不稳定版本中。
2024年2月29日:在GitHub上,@teknoraver发送了一个拉取请求,要求停止将liblzma链接到libsystemd。看起来这将挫败攻击。Kevin Beaumont推测,知道这一点可能会加速攻击者的计划。目前尚不清楚是否存在任何早期讨论,可能会给他们提供线索。
2024年2月28日:Jia Tan在配置脚本中破坏了landlock(一种安全机制)检测,Jia Tan在用于检查landlock支持的C程序中添加了一个微妙的打字错误。配置脚本尝试构建并运行C程序以检查landlock支持,但由于C程序有一个语法错误,它永远不会构建和运行,脚本将始终决定没有landlock支持。Lasse Collin被列为提交者;他可能忽略了这个微妙的打字错误,或者作者可能是伪造的。可能是前者,因为Jia Tan没有费心在他的许多其他变化中伪造提交者。这个补丁似乎是为了除sshd变化之外的其他事情做准备,因为landlock支持是xz命令的一部分,而不是liblzma的一部分。确切的是什么还不清楚。
2024年3月4日:RedHat发行版开始在liblzma的_get_cpuid(后门入口)中看到Valgrind错误。竞赛开始了,要赶在Linux发行版深入挖掘之前修复这个问题。
2024年3月5日:libsystemd PR合并以移除liblzma。另一场竞赛正在进行,要在发行版完全破坏该方法之前得到liblzma的后门。
2024年3月5日:Debian将xz-utils 5.6.0-0.2添加到测试版本中。
2024年3月5日:Jia Tan提交了两个ifunc bug修复。这些似乎是针对实际的ifunc bug的真实修复。一个提交链接到了Gentoo的错误,并且还打错了一个上游的GCC错误。
2024年3月8日:Jia Tan提交了所谓的Valgrind修复。这是一种误导,但很有效。
2024年3月9日:Jia Tan提交了更新的后门文件。这是实际的Valgrind修复,更改了包含攻击代码的两个测试文件。“原始文件是用本地随机生成的。为了在未来更好地重现这些文件,使用了一个常数种子来重新创建这些文件。”
2024年3月9日:Jia Tan标记并构建了v5.6.1,并发布了包含新后门的xz 5.6.1分发包。到目前为止,还没有看到任何分析旧的和新的后门有何不同。
2024年3月20日:Lasse Collin向LKML发送了一个补丁集,用他本人和Jia Tan替换其个人电子邮件,他们都是内核中xz压缩代码的维护者。没有迹象表明Lasse Collin在这里有恶意行为,只是在清理他自己作为唯一维护者的资料。当然,Jia Tan可能已经促成了这一点,并且能够向Linux内核发送xz补丁将是Jia Tan未来工作的一个很好的支点。我们还没有达到信任级别,但这将是更近的一步。
2024年3月25日:Hans Jansen回来了(!),提交了一个Debian错误,将xz-utils更新到5.6.1。就像在2022年的压力运动中一样,更多name###@mailhost地址出现了,它们在互联网上根本就不存在,现在都冒出来为其主张。
2024年3月28日:Jia Tan提交了一个Ubuntu错误,从Debian更新xz-utils到5.6.1。
攻击偶然败露
2024年3月28日:Andres Freund发现了错误,私下通知了Debian和distros@openwall。RedHat分配了CVE-2024-3094。
2024年3月28日:Debian回滚了5.6.1,引入了5.6.1+really5.4.5-1。
2024年3月29日:Andres Freund在公共oss-security@openwall列表中发布了后门警告,称他在“过去几周”发现了它。
2024年3月29日:RedHat宣布被安装后门的xz在Fedora Rawhide和Fedora Linux 40 beta中被分发。
2024年3月30日:Debian关闭了构建,使用Debian稳定版重建了他们的构建机器(以防恶意软件xz逃离了他们的沙箱?)
时间线原文及更多分析文章:https://research.swtch.com/xz-timeline