xz-utils后门的发现过程复现
继最近披露上游 xz/liblzma 中的后门之后,我们正在撰写这篇“入门”类型的博客文章。我们将解释如何使用 liblzma 的后门版本设置环境,然后运行第一个命令来验证后门是否已安装。总而言之,只需几分钟,并且没有学习曲线,一切都非常简单。
这篇博文针对的是所有随着事件的发展而关注新闻的爱好者,以及那些渴望把手放在键盘上,在终端中运行一些命令而不仅仅是阅读它的人。这确实是初学者水平,我们只会重现最初披露中报告的最简单的发现。这里没有什么开创性的,抱歉;)
设置环境
首先,我们需要一台虚拟机(或简称 VM)。最快的方法可能是从Kali Linux 下载页面下载预构建的镜像,可以根据您的喜好选择当前的 2024.1 版本或最新的每周镜像。
下载镜像后,让我们开始它。不知道怎么办?我们为每种类型的镜像提供了文档:VirtualBox、VMware、Hyper-V和QEMU。
现在我们的虚拟机已启动并运行,因此我们将下载并安装liblzma
包含后门的版本。尽管该软件包已从 Linux 发行版中撤出,但它仍然可以在 Internet 上广泛使用。对于本操作方法,我们将从Debian 快照服务获取它。由于Kali是基于Debian的,而liblzma只依赖于libc,所以在Kali中安装Debian软件包是可以的,我们不应该遇到任何不兼容的问题。
为了清楚起见,请注意: xz-utils 是上游存储库的名称,它提供了众所周知的xz
压缩和解压缩文件的命令,但它还提供了库liblzma
,这是目前每个人都在谈论的受损库。正是通过这个库,后门被添加到 SSH 守护进程中……明白了吗?
已知 xz-utils 的上游版本包含后门,因此让我们获取5.6.0
Debian软件包。5.6.15.6.1-1
在虚拟机中,让我们打开一个终端并使用以下命令获取它:
kali@kali:~$ wget https://snapshot.debian.org/archive/debian/20240328T025657Z/pool/main/x/xz-utils/liblzma5_5.6.1-1_amd64.deb
现在让我们安装这个包:
对于那些不注意的人来说,请注意:下面,我们故意安装一个包含后门的软件包!显然,您正在虚拟机中运行这些步骤,并且该虚拟机没有暴露在互联网上。
kali@kali:~$ sudo apt-get install --allow-downgrades --yes ./liblzma5_5.6.1-1_amd64.deb
下一步是启动(或重新启动)SSH 守护进程:
kali@kali:~$ sudo systemctl restart ssh
下一步是什么?让我们来看看吧!
确认 liblzma 已被存在后门
首先,借助披露中提供的 Vegard Nossum 脚本,我们可以检测 liblzma 的版本是否包含后门。
让我们创建脚本:
kali@kali:~$ cat << 'EOF' > detect.sh
#! /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
EOF
使其可执行,然后运行它:
kali@kali:~$ chmod +x detect.sh
kali@kali:~$
kali@kali:~$ ./detect.sh
probably vulnerable
上面命令的输出应该是probably vulnerable
,这意味着在库中检测到后门。
但是等等,这是如何运作的?该命令hexdump -ve '1/1 "%.2x"' <<file>>
将以十六进制形式转储文件,没有任何格式,只是一个很长的十六进制字符串。该脚本使用 liblzma 执行此操作,然后匹配属于该漏洞利用的模式(也是十六进制形式)。这就是它的全部内容,并且足以检测它。
确认 SSH 守护进程比平时慢
首先,对于此测试,我们需要确保在 SSH 守护程序的设置中禁用密码身份验证:
kali@kali:~$ sudo sed -E -i 's/^#?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config
然后重新启动守护进程:
kali@kali:~$ sudo systemctl restart ssh
现在,让我们尝试以不存在的用户身份登录,并计时:
kali@kali:~$ time ssh nonexistant@localhost
nonexistant@localhost: Permission denied (publickey).
real 0.31s
user 0.05s
sys 0.00s
cpu 17%
这里没有“正确的值”,因为它高度依赖于您的特定设置。然而,我们想要的是了解它需要多少时间,所以让我们运行该命令几次,以确保结果一致。在我的测试中,结果确实非常一致,我几乎每次都得到real 0.30s
。
现在让我们重新安装无后门版本的 liblzma:
kali@kali:~$ sudo apt update && sudo apt install --yes liblzma5
[...]
Get:1 http://http.kali.org/kali kali-rolling/main amd64 liblzma5 amd64 5.6.1+really5.4.5-1 [240 kB]
[...]
截至撰写本文时,lzma5
Kali 滚动中的包版本为5.6.1+really5.4.5-1
,如上所示。
现在,让我们再次尝试 SSH 登录,并计时:
kali@kali:~$ time ssh nonexistant@localhost
nonexistant@localhost: Permission denied (publickey).
real 0.13s
user 0.05s
sys 0.00s
cpu 41%
正如我们所看到的,时间上的差异非常明显,没有后门的话速度要快得多!
致谢
正如引言中所说,这篇博文并不是什么新鲜事,它只是逐步重现最初披露的一些发现。所有的功劳(实际上是大量的功劳)都归功于安德烈斯·弗罗因德(Andres Freund)出色的工作和详细的报告,以及维加德·诺苏姆(Vegard Nossum)的detect.sh
脚本。
https://www.kali.org/blog/xz-backdoor-getting-started/