kali linux 官方博客 --- xz-utils 后门:如何入门
最近上游 xz/liblzma (https://www.openwall.com/lists/oss-security/2024/03/29/4)中的后门被披露后,我们撰写了这篇 "入门 "类博文。我们将介绍如何设置带有后门版本 liblzma 的环境,以及运行哪些命令来验证后门是否已安装。总之,这只需要几分钟时间,没有学习曲线,一切都非常简单。
这篇博文的目标读者是所有关注新闻事件发展的爱好者,他们渴望亲手敲打键盘,在终端中运行几条命令,而不仅仅是阅读相关信息。这确实是初级水平,我们只是重现最初披露的报告中最简单的发现。这里没有什么突破性的东西,抱歉;)
设置环境
首先:我们需要一个虚拟机(简称 VM)。最快的方法可能是从 Kali Linux 下载页面下载一个预置镜像,可以是当前的 2024.1 版本,也可以是最新的每周镜像,随你喜欢。
镜像下载完成后,我们就可以启动它了。不知道怎么启动?我们为每种映像类型都准备了文档: VirtualBox、VMware、Hyper-V 和 QEMU。
现在我们的虚拟机已经启动并开始运行,因此我们要下载并安装包含后门的 liblzma 版本。尽管该软件包已从 Linux 发行版中撤下,但它仍可在互联网上广泛获取。在本教程中,我们将从 Debian 快照服务中获取它(https://snapshot.debian.org/)。由于 Kali 是基于 Debian 的,而 liblzma 只依赖于 libc,所以在 Kali 中安装 Debian 软件包是没问题的,我们应该不会遇到任何不兼容问题。
需要说明的是:xz-utils 是上游资源库的名称,它提供了众所周知的 xz 命令来压缩和解压文件,但它也提供了 liblzma 库,也就是目前大家都在谈论的被泄露的库。正是通过这个库,SSH 守护进程才被添加了后门......明白了吗?
已知 xz-utils 的上游版本 5.6.0 和 5.6.1 包含后门,所以我们抓取 Debian 软件包 5.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 已损坏
首先,我们可以检测 liblzma 版本是否包含后门,这要归功于 Vegard 提供的脚本(https://www.openwall.com/lists/oss-security/2024/03/29/4)
让我们创建脚本:
kali@kali:~$ cat << 'EOF' > detect.sh #! /bin/bash #提示使用bash处理下面脚本 set -eu #-e:如果任何命令的退出状态不是0(即执行失败),则立即退出脚本。 #-u:如果尝试使用未定义的变量,则产生错误并退出脚本。 path="$(ldd $(which sshd) | grep liblzma | grep -o '/[^ ]*')" #which sshd 查sshd文件路径 #ldd 查ssd的依赖库 #grep 过滤出我们想要的liblzma # grep -o '/[^ ]*' 过滤以/开始不包含空格的数据,因为 ldd 的输出通常会包含类似于 /lib/x86_64-linux-gnu/liblzma.so.5 => /usr/lib/x86_64-linux-gnu/liblzma.so.5 这样的行,其中包含了动态链接库的路径信息。 #如果路径不存在 if [ "$path" == "" ] then echo probably not vulnerable exit fi # 检查函数签名if hexdump -ve '1/1 "%.2x"' "$path" | grep -q f30f1efa554889f54c89ce5389fb81e7000000804883ec28488954241848894c2410 #-v 不省略重复项,-e '1/1 "%.2x"' 输入一个字节就输出一个字节,字节的格式是两位hex值
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
上述命令的输出结果应该是 "可能有漏洞",这意味着在库中检测到了后门。
但等等,这是怎么做到的?命令 hexdump -ve '1/1 "%.2x"' <<file>> 将转储文件。<<file>> 将以十六进制形式转储文件,没有任何格式化,只是一个很长的十六进制字符串。脚本使用 liblzma 进行转存,然后匹配属于漏洞的函数(也是十六进制形式)。仅此而已,足以检测到漏洞。
确认 SSH 守护进程比平时慢
首先,我们需要确保在 SSH 守护进程的设置中禁用密码验证:
kali@kali:~$ sudo sed -E -i 's/^#?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo: 以超级用户权限运行命令,因为编辑 /etc/ssh/sshd_config 文件需要超级用户权限。 sed: 流编辑器,用于对文本进行流式编辑。 -E: 启用扩展正则表达式模式,以便我们可以使用更丰富的正则表达式语法。 -i: 在原始文件中直接进行编辑,而不是将输出发送到终端或另一个文件。 's/^#?PasswordAuthentication .*/PasswordAuthentication no/': 这是 sed 的替换命令。它将文件中匹配模式 ^#?PasswordAuthentication .* 的行替换为 PasswordAuthentication no。 ^#?: 匹配行首可能有一个 # 的字符。 PasswordAuthentication .*: 匹配包含 PasswordAuthentication 开头的行,后面可以跟着任意内容。 /etc/ssh/sshd_config: 要编辑的目标文件路径,即 SSH 服务器的配置文件。
重启服务
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%
这里没有 "正确值",因为这与你的特定设置有很大关系。不过,我们只想知道需要多少时间,所以让我们多运行几次命令,确保结果一致。在我的测试中,结果确实非常一致,几乎每次都是 0.30 秒。
现在,让我们重新安装无后门版本的 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]
[...]
写这篇文章时,Kali 滚动中的 lzma5 软件包版本是 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.openwall.com/lists/oss-security/2024/03/29/4)