CVE-2021-4034:pkexec本地提权漏洞分析

CVE-2021-4034:pkexec本地提权漏洞分析

时间:2022-02-17 作者:安帝科技

Part1 漏洞状态

Part2 漏洞描述

2022年1月26日,安帝科技VulEye监测到Polkit的Pkexec中的一个权限提升漏洞(CVE-2021-4034) 应急事件病毒样本中发现。
Linux Polkit的Pkexec程序中发现了一个本地权限提升漏洞。Pkexec应用程序是一个Setuid工具,旨在允许非特权用户根据预定义的策略以特权用户身份运行命令。由于当前版本的Pkexec无法正确处理调用参数计数,并最终会尝试将环境变量作为命令执行。攻击者可以通过控制环境变量,从而诱导Pkexec执行任意代码。利用成功后,可导致非特权用户获得管理员权限。

Part3 受影响版本

Polkit由于为系统预装工具,目前主流Linux版本均受影响。

Part4 漏洞复现

测试Ubuntu、Debian、CentOS的默认安装环境上均测试通过。漏洞利用难度不高,最早引入问题的commit来自2009年,影响版本范围远超2020年的sudo漏洞。
Ubuntu系统:

Debian:

Part5 漏洞分析

以下内容整理自网络上的公开信息,仅供技术研究目的。本文不包含任何具体的漏洞利用代码。
漏洞细节:部分poc代码

Github上已经有Poc流出
https://github.com/arthepsy/CVE-2021-4034
漏洞细节:函数流程
漏洞出在pkexec命令上。
在main函数里,如果传入的命令不是绝对路径,就会在PATH环境变量的目录里搜索。

在534行的for循环从下标1开始遍历argv[]。但Linux里argv允许只包含一个元素,就是使用execve并给argv传入{0},此时argc就是0。
这个for循环结束之后,变量n为1。第610行产生了第一个越界读,而第639行产生了一个越界写,把g_find_program_in_path返回的指针尝试写回argv[1]。
调用execve之后,新进程的栈如下:

巧合的是 argv 之后正好马上接的是envp的第一个元素,完全可控。只要不是 / 开头的字符串就会进入越界写的分支。如果能控制g_find_program_in_path返回的字符串,就可以注入任意的环境变量。

这个内存安全(memory safety)问题瞬间变成了一个逻辑漏洞。

作者传入 PATH=folder,然后在folder目录里放置一个可执行文件value,那么字符串 folder/value 就会写回 envp[0]。再进一步,让这个组合的文件名里包含等号 “=”。传入 PATH=name=.,创建一个name=. 目录,并在其中放一个可执行文件value,最终 envp[0] 就会被篡改为name=./value,也就是注入了一个新的环境变量进去。

回到这个命令本身,pkexec 具有suid,在执行入口程序之前不安全的环境变量都会被过滤一遍;由于这个漏洞的存在,这个过滤措施可以直接绕过。

这个漏洞将一个内存安全的off-by-one问题转化成了参数注入,关键出错的代码不长,颇有ctf的味道。

值得一提的是GitHub Security Labs在2021年发过一篇Polkit的本地提权漏洞CVE-2021-3560,只是利用条件有一定限制。Qualys很有可能是看了这篇分析然后开始审计代码。

Part6 修复建议

目前各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
—————————————————————-

获取更多情报

联系我们,获取更多漏洞情报详情及处置建议,让企业远离漏洞威胁。
电话:18511745601
邮箱:shiliangang@andisec.com