目录
PwnKit漏洞描述
Qualys 研究团队在 polkit 的 pkexec 中发现了一个内存损坏漏洞,该 SUID 根程序默认安装在每个主要的 Linux 发行版上。这个易于利用的漏洞允许任何非特权用户通过在其默认配置中利用此漏洞来获得易受攻击主机上的完全 root 权限。
PwnKit 漏洞原理
以下是对 PwnKit 漏洞如何工作的解释。
pkexec 的 main() 函数的开头处理命令行参数(第 534-568 行),并在 PATH 环境变量的目录中搜索要执行的程序(如果其路径不是绝对路径)(第 610-640 行) ):
435 main (int argc, char *argv[])
436 {
...
534 for (n = 1; n < (guint) argc; n++)
535 {
...
568 }
...
610 path = g_strdup (argv[n]);
...
629 if (path[0] != '/')
630 {
...
632 s = g_find_program_in_path (path);
...
639 argv[n] = path = s;
640 }
不幸的是,如果命令行参数 argc 的数量为 0——这意味着如果我们传递给 execve() 的参数列表 argv 为空,即 {NULL}——那么 argv[0] 为 NULL。这是参数列表的终止符。所以:
- 在第 534 行,整数 n 永久设置为 1;
- 在第 610 行,从 argv[1] 越界读取指针路径;
- 在第 639 行,指针 s 被越界写入 argv[1]。
但是从这个越界的 argv[1] 中读取和写入的到底是什么?
要回答这个问题,我们必须简短地离题。当我们 execve() 一个新程序时,内核将我们的参数、环境字符串和指针(argv 和 envp)复制到新程序堆栈的末尾;例如:
显然,因为 argv 和 envp 指针在内存中是连续的,如果 argc 为 0,那么越界 argv[1] 实际上是 envp[0],指向我们的第一个环境变量“value”的指针。最后:
- 在第610行,将要执行的程序的路径从argv[1](即envp[0])中越界读取,并指向“value”;
- 在第 632 行,这个路径“value”被传递给 g_find_program_in_path()(因为“value”不是以斜线开头,在第 629 行);
- 然后,g_find_program_in_path() 在我们的 PATH 环境变量的目录中搜索一个名为“value”的可执行文件;
- 如果找到这样的可执行文件,则将其完整路径返回给 pkexec 的 main() 函数(在第 632 行);
- 最后,在第 639 行,这个完整路径被越界写入 argv[1](即 envp[0]),从而覆盖了我们的第一个环境变量。
所以,更准确地说:
- 如果我们的 PATH 环境变量是“PATH=name”,并且如果目录“name”存在(在当前工作目录中)并且包含一个名为“value”的可执行文件,则写入一个指向字符串“name/value”的指针越界到 envp[0];
或者
- 如果我们的 PATH 是“PATH=name=.”,并且目录是“name=.” 存在并包含一个名为“value”的可执行文件,然后将指向字符串“name=./value”的指针越界写入 envp[0]。
换句话说,这种越界写入允许我们将一个“不安全”的环境变量(例如,LD_PRELOAD)重新引入 pkexec 的环境。这些“不安全”变量通常在调用 main() 函数之前从 SUID 程序的环境中删除(通过 ld.so)。我们将在下一节中利用这个强大的原语。
最后一分钟说明:polkit 还支持非 Linux 操作系统,例如 Solaris 和 *BSD,但我们尚未调查它们的可利用性。然而,我们注意到 OpenBSD 是不可利用的,因为如果 argc 为 0,它的内核拒绝执行程序。
PwnKit漏洞复现
poc:https://github.com/berdav/CVE-2021-4034
复现环境为
下载poc编译执行获得root权限
也有python3一键提权脚本
https://github.com/nikaiw/CVE-2021-4034
PwnKit漏洞修复
鉴于此漏洞在 Linux 和非 Linux 操作系统中的广泛攻击面,建议用户立即针对此漏洞应用补丁程序。
目前各Linux发行版官方均已给出安全补丁,建议用户尽快升级至安全版本,或参照官方说明措施进行缓解,CentOS、Ubuntu及Debian用户可参考以下链接:
https://ubuntu.com/security/CVE-2021-4034 https://access.redhat.com/security/cve/CVE-2021-4034 https://security-tracker.debian.org/tracker/CVE-2021-4034
可以通过rpm -qa polkit查看polkit是否为安全版本
安全版本
CentOS系列:
CentOS 6:polkit-0.96-11.el6_10.2
CentOS 7:polkit-0.112-26.el7_9.1
CentOS 8.0:polkit-0.115-13.el8_5.1
CentOS 8.2:polkit-0.115-11.el8_2.2
CentOS 8.4:polkit-0.115-11.el8_4.2
Ubuntu系列:
Ubuntu 20.04 LTS:policykit-1 - 0.105-26ubuntu1.2
Ubuntu 18.04 LTS:policykit-1 - 0.105-20ubuntu0.18.04.6
Ubuntu 16.04 ESM:policykit-1 - 0.105-14.1ubuntu0.5+esm1
Ubuntu 14.04 ESM:policykit-1 - 0.105-4ubuntu3.14.04.6+esm1
参考链接: