原视频中,漏洞发现人[@Kevin Backhouse]简单介绍漏洞原理后对漏洞进行手动复现;而我们需注意的是:
*Tips:详细视频可点击原视频链接观看,或者:
BiliBili - CVE-2021-3560 Linux提权漏洞复现2
尽管用作者的话来说是The vulnerability enables an unprivileged local user to get a root shell on the system. It’s easy to exploit with a few standard command line tools
而对于漏洞复现本身而言,我们似乎并不能百分百触发漏洞如果我们没有找到窍门,正如作者说的:
I like to think that it’s theoretically possible to trigger by smashing Ctrl+C at just the right moment, but I’ve never succeeded, so I do it with a small amount of bash scripting instead.
You might need to run that a few times, and you might need to experiment with the number of milliseconds in the delay
所以有了本文。
该漏洞存在于系统服务Polkit中,因为Polkit被Systemd所调用,因此默认安装了Systemd的发行版都会使用Polkit;
该漏洞成因是执行dbus-send命令后在认证完成前强制终止引发错误,而Polkit未正确处理错误导致允许无特权的用户添加一个sudo用户。
dbus & polkit 交互流程图
虚线上方的两个进程——dbus-send 和Auth Agent是非特权用户进程。线下的那些是特权系统进程。中间是 dbus-daemon,它处理所有的通信:其他四个进程通过发送 D-Bus 消息来相互通信。
dbus-daemon 在 polkit 的安全性中扮演着非常重要的角色,因为它使四个进程能够安全地通信并检查彼此的凭据。
例如,当Auth Agent向 polkit 发送身份验证 cookie 时,它会通过将其发送到 org.freedesktop.PolicyKit1
D-Bus 地址来实现。由于该地址仅允许由根进程注册,因此不存在非特权进程拦截消息的风险。
我们从左边箭头指向方向到右边一个凹字形来看流程:4
dbus-daemon
守护程序然后转发告诉 account-daemon
dbus-send程序请求polkit
(我们的主角)
polkit
返回dbus-daemon守护程序确认请求,最终到达Auth Agent
认证端
显而易见:问题流程在最后一段,我们通过漏洞发现者博客已知关键在于Kill掉dbus-send 命令导致了身份验证绕过,为什么?换而言之,漏洞出现在第三步骤的第二小步,挖掘思路是什么?
在此之前我们简单了解一下polkit,我认为可以把它想像成sudo认证机制的可视化界面,当我们的当前操作需要更多权限时那么就会触发polkit的认证机制:pkexec
$ pkexec id
==== AUTHENTICATING FOR org.freedesktop.policykit.exec ===
Authentication is needed to run `/usr/bin/id' as the super user
Authenticating as: bin4xin,,, (ingeek)
Password:
polkit-agent-abouter-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie
==== AUTHENTICATION FAILED ===
Error executing command as another user: Not authorized
This incident has been reported.
# pkexec whoami
root
作者提到:在第三步骤的第一小步中询问dbus-daemon的函数 中代码存疑:
static gboolean
polkit_system_bus_name_get_creds_sync (
PolkitSystemBusName *system_bus_name,
guint32 *out_uid,
guint32 *out_pid,
GCancellable *cancellable,
GError **error)
具体的代码分析可以参考原博客,我们这里就不做不过多的搬运和翻译。
所以如上我们可以得到的是polkit在询问dbus-daemon过程中未进行错误检查,导致在运行质询的过程中可以通过一些可控手段绕过认证机制:
The bug is in this snippet of code in check_authorization_sync: Notice that the value of
error
is not checked.
Poc代码需解决的如下:
ingeek@ubuntu:~$ /etc/init.d/dbus status
● dbus.service - D-Bus System Message Bus
Loaded: loaded (/lib/systemd/system/dbus.service; static; vendor preset: enabled)
Active: active (running) since Tue 2021-06-15 23:00:47 PDT; 1h 26min ago
TriggeredBy: ● dbus.socket
Docs: man:dbus-daemon(1)
Main PID: 875 (dbus-daemon)
Tasks: 1 (limit: 4618)
Memory: 5.4M
CGroup: /system.slice/dbus.service
└─875 /usr/bin/dbus-daemon --system --address=systemd: --nofork --
以上。