资讯详情

CVE-2021-4034 pkexec本地提权漏洞在CentOS 8.5上的完整修复指南

📅 2026/10/22 10:57:52 | 华诺云谱 👁 阅读
CVE-2021-4034 pkexec本地提权漏洞在CentOS 8.5上的完整修复指南
2022年年初安全圈最炸裂的那条通告CVE-2021-4034也就是大家常说的 pkexec 本地提权漏洞。只要是任何允许普通用户登录的 Linux 机器都存在被直接提权到 root 的风险而且不需要你输入密码。这已经不是“高危”两个字能概括的了对跑着业务的 CentOS 8.5 服务器来说修复动作慢一天风险就多一天。这篇文章把我实际处理这个漏洞的完整过程写出来从漏洞原理、修复方案选择到 CentOS 8.5 上的具体操作和踩坑记录一次性说清楚。1. 先说清楚这个漏洞到底狠在哪1.1 一句话讲明白漏洞原理要理解这个漏洞先得弄清楚 pkexec 是什么。pkexec 是 polkit 授权框架里的一个命令作用是让普通用户临时以其他用户的身份执行某个程序最常见的用法就是在图形界面里弹出授权框让你输入管理员密码完成系统设置操作。它本身是个 setuid 程序也就是说执行它的进程能够临时获得 root 权限这是它的设计功能。CVE-2021-4034 的问题出在 pkexec 处理命令行参数时的一个越界写漏洞。安全研究员发现pkexec 在解析参数时错误地处理了 argv[0] 为空的情况导致程序发生越界写入攻击者可以利用这个异常行为把精心构造的环境变量写入到进程内存中最终诱导系统加载恶意共享库从而以 root 身份执行任意命令。整个过程不需要用户密码也不需要交互一个普通用户在自己的 shell 里敲几条命令就能完成提权。1.2 影响范围比想象的大这个漏洞被称为 PwnKit重点在于“默认受影响”这四个字。polkit 是几乎所有主流 Linux 发行版的基础组件从桌面版到服务器版都会预装。服务器上即使没有图形界面也可能会因为某些管理工具、虚拟化组件或打印服务等依赖链而安装了 polkit。这意味着 CentOS 8.5、其他 Linux 发行版甚至一些容器镜像只要里面有 pkexec 且版本在受影响范围内都存在风险。更要命的是触发这个漏洞的权限门槛极低。只要有任意一个本地用户账号哪怕是那些被设置成 nologin、不能正常登录的账户都能参与攻击。因为利用的是 pkexec 本身的解析逻辑不依赖系统里的任何服务配置。所以判断一台机器是否要紧危处理标准很简单看看有没有本地用户账号有没有 pkexec 二进制文件。有就赶紧修。2. 动手前先确认环境别闭眼就敲命令2.1 确认系统版本和 polkit 包状态修复的前提是先搞清楚自己待的环境。使用以下命令确认系统版本和 polkit 安装情况cat /etc/redhat-release uname -a rpm -qa | grep -i polkit执行后通常会看到类似这样输出CentOS Linux release 8.5.2111以及polkit-0.116-11.el8、polkit-libs-0.116-11.el8、polkit-pkla-0.116-11.el8这几个关键包。0.116 这个版本就在受影响范围内需要升级到打了补丁的版本。在 CentOS 8 的修复渠道里修复版本通常以0.116-11.el8_5.4或更高版本号的形式出现最终以仓库实际推送的版本为准。2.2 检查依赖关系评估升级影响升级前最怕的是改出新的问题。先花一分钟看看谁依赖 polkit避免升级完导致别的服务起不来。用下面两条命令检查rpm -q --whatrequires polkit rpm -q --whatrequires pkexec我处理过的环境里最常见的依赖方是libvirt、gnome-settings-daemon、udisks2这类组件。一般情况升级 polkit 不会有破坏性影响但如果输出里有某些私有软件直接硬编码调用了旧版本的接口那升级后就要额外做验证。这一步不能省尤其是生产环境。2.3 准备好回滚手段无论网络环境多好都要想好失败怎么退回来。最稳妥的方式是对虚机先打快照云主机就用控制台的磁盘快照功能耗时基本可以忽略。如果是物理机或者不方便打快照至少把当前版本的 rpm 包留底mkdir -p /root/polkit-backup rpm -qa | grep -i polkit | while read pkg; do rpm -ql $pkg /root/polkit-backup/$pkg.filelist done yumdownloader polkit polkit-libs polkit-pkla --destdir/root/polkit-backup这个目录保留好万一升级后出现兼容性问题可以直接rpm -Uvh /root/polkit-backup/polkit-*.rpm --oldpackage回滚。备份不占多少空间却能在紧急时候救你一命。3. 修复方案怎么选补丁升级和临时缓解3.1 首选方案升级到修复版本的 polkit最理想的修复方法是直接安装官方修复版本。现在各个发行版都已经发布了打了补丁的 polkit 包CentOS 8.5 环境也适用。不过要特别提醒一点CentOS Linux 8 官方仓库的生命周期在 2021 年底结束而 CVE-2021-4034 的公开和修复通告在 2022 年 1 月。这导致如果你只保留了原始官方源可能刷不到这个更新。有几种应对方式如果服务器之前就配置了国内镜像源并且镜像源保留了 RHEL 8.5 对应的安全更新仓库直接dnf update polkit -y通常能拉到修复包。如果刷不到可以把 BaseOS 和 AppStream 源指向仍在维护的兼容仓库或者直接使用由社区/第三方提供的 rebuild 修复包。部分云厂商的镜像源会同步推送安全更新我记得在当时的实际操作中切换到云厂商内网源后很快就刷到了0.116-11.el8_5.4.el8版本。注意升级时把polkit-libs、polkit-pkla一起升级这几个包版本号必须匹配只升级主包会导致依赖检查失败。3.2 应急方案先去掉 pkexec 的 setuid 位如果仓库一时拿不到修复包又或者出于某种原因必须把更新窗口推到后面应急缓解措施也很简单。漏洞利用依赖 pkexec 的 setuid 特殊权限位只要把这个权限去掉pkexec 在执行时就不会切换到 root 身份攻击链就断了。执行一步命令chmod 0755 /usr/bin/pkexec操作后用ls -l /usr/bin/pkexec确认权限显示为-rwxr-xr-x而不是正常的-rwsr-xr-x就说明缓解生效了。需要清楚这个操作的代价系统里那些依赖 pkexec 的授权弹窗和提权操作会一并失效。比如桌面环境里打开管理界面输入密码授权时可能会提示认证失败或无法执行提权命令。对于纯命令行服务器影响相对小一些因为很少有普通用户日常用到 pkexec管理员都用 sudo。这个方案适合作为临时阻断手段不能作为长期状态更不要忘了后续还要升级补丁升级完成后确认权限位回到 4755。3.3 关于移除 pkexec 的补充思路有部分人问既然 pkexec 有漏洞能不能直接把整个 polkit 包卸载理论上能从系统里删除它但代价往往超出预期。polkit 是很多桌面组件、服务管理工具的基础依赖直接卸载极有可能让某些功能报错严重时连桌面都起不来。还有一个可行思路是结合 SELinux 进行加固。虽然 SELinux 不能单独拦住 CVE-2021-4034 的利用链但作为纵深防御的一部分保持 SELinux 开启Enforcing状态能在漏洞被利用后显著增加攻击者的操作难度。我习惯的做法是漏洞修复为主SELinux 策略加固为辅两层都做到位这台机器才算真的放心。4. 完整实操从验证到修复到回归4.1 如何安全地确认漏洞是否存在首先是验证本地环境的漏洞状态。这里建议不要直接在业务环境运行公开的攻击验证程序避免产生不可控的副作用。运维人员要的只是一个可靠的判断依据用版本检查就足够当前 rpm 包版本如果在受影响范围内就认为存在漏洞按未修复处理。这个判断逻辑简单且不会给生产环境带来风险。如果实在想在测试机上做行为验证可以在非 root 用户下直接执行pkexec不带任何参数观察是否出现段错误或者异常退出。但我要多提醒一句这类行为本质上已经接近触发漏洞的边界绝不要在没有隔离的测试环境里做更不能拿它去生产环境试探。确认版本在受影响范围内就已经够声明这台机器需要修复了。4.2 在线升级 polkit 的完整命令流程在能够获取修复包的环境里操作顺序如下。先刷新缓存dnf clean all dnf makecache然后直接升级dnf update polkit polkit-libs polkit-pkla -y如果命令提示没有任何可更新的包说明当前仓库源里的包版本未变或者源已经失效。这时按我上面说的把源切到仍维护兼容仓库的镜像站再执行一次。升级完成后立刻确认三件事rpm -q polkit polkit-libs polkit-pkla ls -l /usr/bin/pkexec systemctl restart polkit正常情况下版本号会显示为修复后的版本pkexec 权限位恢复为-rwsr-xr-x4755polkit 服务重启后保持在运行状态。这里的 systemctl restart 非常重要因为 polkit 的一部分工作由守护进程完成不重启的话旧进程体内可能依然保留着旧版本的缺陷逻辑。4.3 离线环境的升级思路很多服务器出于安全要求不能连外网升级得走离线流程。具体做法是在另一台能够访问软件源的主机上把需要升级的包和依赖都下载下来dnf download polkit polkit-libs polkit-pkla --resolve --alldeps --destdir/tmp/polkit-rpms然后把/tmp/polkit-rpms里的文件拷贝到离线服务器的某个目录比如/root/polkit-rpms在目标机器上执行dnf install /root/polkit-rpms/*.rpm -y使用dnf install而不是直接rpm -Uvh的好处是它会自动做依赖解析避免漏包。安装结束后同样做版本、权限位和服务状态三个检查。离线环境最怕的是下载的 rpm 包和系统的架构或版本不匹配比如用的是 8.6 的包给 8.5 装很可能出现依赖版本过高的问题。所以在下载阶段就要确认好软件源和你目标系统是同一个大版本。4.4 修复后的功能回归测试补丁装上以后验证不是说版本号对了就完事还得看功能是否正常。我最常用的回归测试是用普通用户身份执行su - testuser -c pkexec /bin/echo test正常情况下应该弹出认证提示比如要求输入密码或提示需要认证代理而不会再出现直接崩溃或者异常段错误。这个命令实际不会执行成功但它的输出能帮你判断 pkexec 是否还具备正常的提权流程。再检查一下系统日志journalctl -u polkit --since today grep pkexec /var/log/messages看到正常的服务启动日志和认证尝试记录没有重复的 crash 记录就说明修复生效且功能正常。如果这台机器上有图形桌面最好再点开一次系统设置里的管理功能确认认证弹窗能正常出现这一步能避免遗漏权限位错误引起的隐性故障。5. 实操中容易踩的坑问题排查速查表5.1 升级后 pkexec 权限位变成 0755 导致功能异常我在处理一批机器时遇到过这种情况系统里之前做了chmod 0755 /usr/bin/pkexec应急缓解升级完 polkit 包之后发现 pkexec 权限依然是 0755版本明明已经是修复后的但桌面管理的提权操作全部失败。原因很简单rpm 升级不会自动把被管理员手工修改过的权限位强制纠正回来。解决办法是手动恢复chmod 4755 /usr/bin/pkexec恢复后再确认权限应是-rwsr-xr-x。这个小细节不写在补丁公告里容易让人以为升级完成就万事大吉实际上还要补上这一脚。5.2 仓库刷不到修复版本升级计划卡住最常见的问题就是执行dnf update polkit后提示“没有软件包需要更新”。如果确定当前版本确实在受影响范围内说明现在的源仓库里没有推送修复包。运维人员尤其是 CentOS 8 这种生命周期结束的发行版必须在心里明确一个事实官方源不更新安全补丁了。处理方式有两种一种是把源切到仍在维护的兼容仓库或者直接使用 RHEL 8.5 对应的安全更新通道另一种是使用社区维护的 rebuild 包。无论用哪种都必须留意包的签名校验非官方渠道的包风险自担安装前先确认 MD5 或 GPG 签名是否正确。升级完成后记得把源配置切回原样避免后续操作误用到不确定的仓库。5.3 升级后是否需要重启机器这个问题在我处理的群里被问了不下十遍。我给出的建议是分场景看。如果系统里有桌面套件并且很多图形进程长时间运行稳妥起见安排一次重启如果是纯命令行的业务服务器只需要执行systemctl restart polkit并确认依赖 polkit 的进程没有残留异常可以暂时不重启。但要注意如果你在用容器特别是容器和宿主机共享/usr目录的部署方式宿主机和容器里的 polkit 包都要检查只更新一个层面是不够的。5.4 如何防止同类问题再次大面积漏掉经历过一轮紧急修复后最怕的就是机房里还有某台机器被漏掉下次漏洞通告出来又得手工确认一次。我们可以把巡检自动化。最简单的思路是用一个命令批量收集所有机器的 polkit 版本再和修复版本号做对比。rpm -qa polkit --qf %{NAME}-%{VERSION}-%{RELEASE}\n配合自动化配置工具下发到所有机器把执行结果集中汇总设定版本阈值告警低于修复版本的主机自动标记为需要人工介入。平时关注官方的安全通告有新的 polkit 相关 CVE 出来时第一时间更新自己的版本识别脚本。安全运维这活儿靠记忆靠不住靠自动化的版本基线才能减少漏网之鱼。5.5 别把 CVE-2021-4034 和 CVE-2021-3560 搞混复习一下知识要点CVE-2021-3560 是 polkit 的另一个本地提权漏洞利用的是认证流程中的逻辑漏洞和 4034 的越界写完全不同。有些文章会把二者写在一起导致有些同学以为修复了一个就把另一个也覆盖了。实际上两个漏洞需要各自的补丁包检查版本时最好同时确认这两个漏洞的修复版本号。我在实际巡检脚本里会把这两个 CVE 对应的修复版本都写成检查项避免出现修了 A 漏了 B 的局面。6. 最后分享几点个人经验这批漏洞处置下来我个人的最大体会是对于本地提权漏洞修复窗口真的要压缩到最短。CVE-2021-4034 从公开到出现公开利用脚本的时间间隔非常短秒级提权的演示视频传播速度远超很多运维的响应速度。与其等攻击者先扫描到你不如自己先动手把补丁打上。还有一个教训是应急缓解措施和正式补丁要分开记台账。chmod 0755 之后一定要在监控或巡检脚本里留下记录否则几天后你自己都会忘了这台机器是不是已经恢复权限。我这边的做法是每台执行过缓解操作的机器都要在备注里写清楚“待升级补丁升级后必须恢复 4755”并且把这类机器放在自动化巡检的最高优先级。最后说个小技巧如果机器数量多可以把rpm -qa polkit --qf %{NAME}-%{VERSION}-%{RELEASE}\n的结果统一收集再用脚本比对预期版本号。这一条命令的成本几乎为零却能避免你在某次安全通告后逐台登录排查的尴尬。安全这件事功夫下在平时比临时抱佛脚有用得多。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑