PolicyKit(简称polkit)是Ubuntu系统中负责细粒度权限控制的核心组件,它决定了普通用户在不输入root密码的情况下能执行哪些特权操作。一旦polkit策略配置不当或存在漏洞,攻击者就能通过它实现本地权限提升,直接拿到root权限。这不是理论风险,而是真实发生过的安全事件,比如CVE-2021-4034(Pkexec漏洞)就是经典案例。本文直接讲清楚polkit权限提升的原理、常见攻击路径、如何审计现有策略、以及怎样修改策略来加固系统。
一、PolicyKit到底是什么,为什么它会成为攻击目标
PolicyKit是一个运行在系统后台的守护进程(polkitd),它的工作机制是:当普通用户尝试执行一个需要特权的操作时(比如挂载磁盘、修改网络配置、安装软件),系统会先拦截这个请求,然后交给polkitd去判断——这个用户有没有权限做这件事。判断依据就是一组策略文件,通常存放在/etc/polkit-1/目录下,以及/usr/share/polkit-1/目录下。
polkit的设计初衷是好的,它让桌面用户不用每次都输sudo密码就能完成日常管理操作。但问题在于,很多发行版的默认策略过于宽松,有些策略文件甚至允许任何本地用户执行某些高危操作。攻击者一旦获得了一个低权限的本地账户,就可以利用这些宽松策略直接提权到root。
二、Polkit权限提升的常见攻击路径
第一种路径是利用pkexec组件。pkexec是polkit提供的一个工具,允许用户以其他用户身份(通常是root)执行程序。如果pkexec本身存在漏洞或者策略允许任意用户执行它,攻击者就能通过它拿到root shell。CVE-2021-4034就是这个组件的堆溢出漏洞,攻击者构造恶意参数就能执行任意代码。
第二种路径是利用宽松的策略规则。比如某些策略文件中写了这样的规则:
<allow active="yes">
<match user="*">
<all>
</allow>这条规则的意思是:任何活跃用户都被允许执行所有操作。如果你的系统里有这样的策略文件,那基本等于把root权限白送给了所有本地用户。
第三种路径是通过D-Bus接口调用polkit。很多系统服务通过D-Bus暴露接口,而这些接口背后可能绑定了polkit策略。攻击者如果能找到一个不需要认证或者认证宽松的D-Bus方法,就能间接触发特权操作。
三、如何审计当前系统的Polkit策略
审计是加固的第一步。你需要先搞清楚当前系统里到底有哪些策略、哪些是宽松的。执行以下命令查看所有策略文件:
find /etc/polkit-1 -name "*.rules" -o -name "*.pkla" 2>/dev/null find /usr/share/polkit-1 -name "*.rules" -o -name "*.pkla" 2>/dev/null
注意,Ubuntu 18.04之后主要使用JavaScript格式的规则文件(.rules),而老版本可能还有.pkla文件。.pkla文件格式更简单但功能也更弱,建议统一迁移到.rules格式。
接下来,用pkaction命令查看系统中所有已注册的polkit动作:
pkaction --verbose
这个命令会列出所有polkit管理的操作,包括每个操作对应的默认策略是什么。重点关注那些默认策略为"unix-user:*"或者"unix-group:*"的动作,这些通常意味着任何用户或任何组都能执行。
还有一个实用工具是pkcheck,它可以测试当前用户对某个动作是否有权限:
pkcheck --action-id org.freedesktop.policykit.exec --process $$ --allow-user-interaction
把org.freedesktop.policykit.exec替换成你关心的动作ID就行。如果返回yes,说明当前用户确实有权限,那你就要评估这个权限是否合理。
四、如何修改和加固Polkit策略
修改策略的核心原则是:最小权限。只给必要的用户、必要的操作开放权限,其他全部拒绝。
首先,创建自定义规则文件。不要直接修改/usr/share/polkit-1/下的文件,因为系统更新会覆盖它们。正确做法是在/etc/polkit-1/rules.d/目录下创建新文件,文件名以数字开头来控制加载顺序(数字越小优先级越高):
sudo nano /etc/polkit-1/rules.d/50-custom-hardening.rules
然后写入规则。比如,你想禁止所有非管理员用户通过pkexec执行任意程序:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.policykit.exec" &&
subject.user != "root" &&
!subject.isInGroup("admin")) {
return polkit.Result.NO;
}
});这段代码的逻辑是:如果动作是pkexec,且用户不是root也不在admin组里,就拒绝执行。这样普通用户就没法用pkexec提权了。
再比如,你想限制某个特定的高危动作只允许admin组执行:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.udisks2.open-device" &&
!subject.isInGroup("admin")) {
return polkit.Result.AUTH_ADMIN;
}
});AUTH_ADMIN表示需要管理员认证,NO表示直接拒绝,YES表示允许。根据你的安全需求选择合适的返回值。
写完规则文件后,重启polkit服务让它生效:
sudo systemctl restart polkit
五、针对Pkexec漏洞的专项修复
如果你的Ubuntu版本受到CVE-2021-4034影响(主要是Ubuntu 20.04、21.04、21.10等),必须立即更新系统。但如果暂时无法更新,可以临时禁用pkexec的setuid位:
sudo chmod 0755 /usr/bin/pkexec
注意,这只是临时方案,会影响正常功能。正确做法还是打补丁。同时检查pkexec是否有setuid位:
ls -l /usr/bin/pkexec
如果显示-rwsr-xr-x,说明有setuid位,这是漏洞利用的前提。打完补丁后这个位会被移除或者策略会被收紧。
六、其他加固建议
第一,定期检查/etc/polkit-1/rules.d/目录下有没有来路不明的规则文件。有些恶意软件会在这里植入提权规则,让自己获得永久root权限。
第二,监控polkit的日志。polkitd会记录所有授权决策,日志通常在/var/log/auth.log或者journalctl中:
journalctl -u polkit --since "1 hour ago"
如果你看到大量来自非管理员用户的授权成功记录,就要警惕了。
第三,限制能够登录本地控制台的用户。polkit的很多策略是基于"active"(活跃会话)来判断的,如果你能控制谁能物理登录或者远程登录,就从源头减少了攻击面。
第四,使用AppArmor或者SELinux对polkitd进程做强制访问控制。即使polkit策略被绕过,MAC机制还能提供一层防护。
第五,不要随意安装来路不明的.deb包。有些恶意软件在安装脚本中会向/etc/polkit-1/rules.d/写入宽松规则,实现静默提权。安装任何软件前检查其postinst脚本。
七、总结
PolicyKit是Ubuntu权限体系的重要一环,但它的默认配置往往偏宽松,给本地提权攻击留下了可乘之机。作为运维人员或者安全从业者,你需要定期审计策略文件、收紧不必要的权限、及时修补已知漏洞、监控异常授权行为。把polkit当成一个需要持续管理的安全组件,而不是装完系统就不管的东西。做到这几点,你的Ubuntu系统在本地权限提升这个攻击面上就能挡住绝大多数威胁。
