Qualys 在发行版中使用的 Polkit(以前称为 PolicyKit)系统组件中发现了一个漏洞 (CVE-2021-4034),该漏洞允许非特权用户执行需要提升访问权限的操作。 该漏洞允许非特权本地用户将其权限升级为 root 并获得对系统的完全控制。 该问题的代号为 PwnKit,值得注意的是,它产生了一个在大多数 Linux 发行版的默认配置下运行的有效漏洞。
该问题存在于 PolKit 的 pkexec 实用程序中,该实用程序带有 SUID root 标志,旨在根据指定的 PolKit 规则以另一个用户的权限运行命令。 由于对传递给 pkexec 的命令行参数的处理不正确,非特权用户可能会绕过身份验证并导致其代码以 root 身份运行,而不管访问规则设置如何。 对于攻击来说,在 PolKit 中指定什么设置和限制并不重要,只要使用 pkexec 实用程序为可执行文件设置 SUID 根属性就足够了。
Pkexec 不检查启动进程时传递的命令行参数计数 (argc) 的有效性。 pkexec 的开发人员假设 argv 数组中的第一个条目始终包含进程的名称 (pkexec),第二个条目要么是 NULL 值,要么是通过 pkexec 启动的命令的名称。 由于参数计数没有根据数组的实际内容进行检查,并且被假定为始终大于 1,因此如果向进程传递空 argv 数组(如 Linux execve 函数允许的那样),pkexec 会将 NULL 视为第一个参数(进程名称)和下一个在缓冲存储器之外,就像数组的后续内容一样。 |———+———+——+————|———+———+——+————| | argv[0] | argv[1] | argv[0] ... | argv[argc] | argv[argc] | 环境[1] | 环境[XNUMX] | ... | 环境变量[环境变量] | |—-|—-+—-|—-+——+——|——|—-|—-+—-|—-+——+——|——| VVVVVV“程序”“-选项”NULL“值”“PATH=名称”NULL
问题是,在 argv 数组之后,内存中有一个包含环境变量的 envp 数组。 因此,如果 argv 数组为空,pkexec 从带有环境变量的数组的第一个元素中提取有关以提升的权限运行的命令的数据(argv[1] 与 envp[0] 相同),其中的内容可以控制由攻击者。
收到 argv[1] 的值后,pkexec 尝试考虑 PATH 中的文件路径来确定可执行文件的完整路径,并将一个指向带有完整路径的字符串的指针写回 argv[1],这导致覆盖第一个环境变量的值,因为 argv[1] 与 envp[0] 相同。 通过操纵第一个环境变量的名称,攻击者可以在pkexec中替换另一个环境变量,例如替换suid程序中不允许的“LD_PRELOAD”环境变量,并安排其共享库加载到过程。
有效利用涉及替换 GCONV_PATH 变量,该变量用于确定符号转码库的路径,在调用 g_printerr() 函数时动态加载,该函数的代码使用 iconv_open()。 通过重新定义 GCONV_PATH 中的路径,攻击者可以确保加载的不是标准 iconv 库,而是它自己的库,当 pkexec 仍在运行时显示错误消息时,将从该库执行处理程序root 权限和启动前权限都会被检查。
值得注意的是,尽管该问题是由内存损坏引起的,但无论使用何种硬件架构,都可以可靠且可重复地利用该问题。 准备好的漏洞已在 Ubuntu、Debian、Fedora 和 CentOS 上成功测试,但也可以在其他发行版上使用。 原始漏洞尚未公开,这表明它很简单,并且其他研究人员可以轻松地重新创建,因此在多用户系统上尽快安装补丁更新非常重要。 Polkit 也可用于 BSD 系统和 Solaris,但尚未研究在它们上的使用。 已知的是,该攻击无法在 OpenBSD 上进行,因为 OpenBSD 内核不允许在调用 execve() 时传递 null argc 值。
该问题自 2009 年 6 月添加 pkexec 命令以来一直存在。 PolKit 漏洞的修复目前以补丁形式提供(尚未发布补丁版本),但由于发行版开发人员提前收到了该问题的通知,因此大多数发行版在披露漏洞信息的同时发布了更新。 该问题已在 RHEL 7/8/0755、Debian、Ubuntu、openSUSE、SUSE、Fedora、ALT Linux、ROSA、Gentoo、Void Linux、Arch Linux 和 Manjaro 中修复。 作为阻止该漏洞的临时措施,您可以从 /usr/bin/pkexec 程序中删除 SUID root 标志(“chmod XNUMX /usr/bin/pkexec”)。
来源: opennet.ru