Local privilege escalation using polkit
Exploit CVE-2021-3560 is used for privilege escalation on linux systems. It’s related to polkit and D-bus requests. ”polkit is an application-level toolkit for defining and handling the policy that allows unprivileged processes to speak to privileged processes” . This exploit was made public in June 2021  and has a CVSS score of 7.8. The main goal for the exploit is to create a new local root user. To use the exploit only a few commands are required like bash, kill and dbus-send. But it also requires some luck and timing.
Step 1 – Reconnaissance of current system. All linux distributions are not vulnerable against this exploit so first step is to find out the current distribution. If the distribution is for instance Ubuntu 20.04 or Fedora 21 then it might be vulnerable. Any system that has polkit version 0.113 or later is vulnerable.
Step 2 – Find correct timing. In the exploit script you need to specify how long the execution time should be before it’s terminated. In order to find out how long execution time a dbus command has on the system you can execute:
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:aba string:"aba" int32:1
The output will be something like: ”Error .. PermissionDenied .. real: 0m0.012s. Which means that the dbus request in the exploit command will need to terminate before 12 ms has elapsed.
Step 3 – Prepare the exploit command and execute. Here is the dbus-send command:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:aba string:"aba" int32:1 & sleep 0.008s ; kill $!
This command tries to create a new user “aba” but after 8 ms the command is terminated (sleep 0.008s ; kill $!). The command may be executed a couple of times before correct timing is reached. If succeeded then: “id aba”.
Timing is crucial and can be difficult to achieve. The command can of course be put into a bash script and executed iteratively. Then you can also add a random timing interval to test with.
In short terms. If a control center receives a request from another party but this party disappears after the request has been completed. Then I take it for granted that the party is authorized and has the authority to carry out their request.
When a request from dbus-send is sent, several processes are involved. Dbus-send is sent to dbus-daemon which communicates with polkit and accounts-daemon.
The dbus-send sends a request to the accounts-daemon to create a new user. Accounts-deamon is responsible to check if the user that sent the dbus command is authorized. The deamon is performing the check against polkit. Polkit then wants the user id of the connection that sent the request. But the connection has now been terminated and user id becomes “0”. Polkit authorize the request despite user id is “0” by returning TRUE rather than FALSE and replies back to the account-deamon. Once this has been approved, the request can be approved and the new user created.