This bug is a combination of a race condition and bad error handling. Basically:
- Manually request an action that requires superuser access via DBus.
- Kill dbus-daemon after Polkit has received the message but before it responds (there’s the race).
- Polkit requests the user ID associated with the message, but since DBus has restarted it can’t reference the original message ID and responds with an error.
- Polkit mishandles the error, substituting 0 for the ID of the requesting user (there’s the botched error handling).
- Because the requesting user ID now appears to be root, Polkit just goes ahead and takes the action without issuing a challenge.
Ubuntu fixed with with version 0.105-26ubuntu1.1 of the policykit-1 package (the last vulnerable version was 0.105-26ubuntu1).
-
Construct a message similar to the following:
The three parameters are:
string:attacker
— the name of the user to create.string:"Pentester Account"
— the user “description” (GECOS field).int32:1
— grant sudo access to the user.
-
Begin by determining how long the message takes to execute on the target. This can be done with the
time
command. -
DBus needs to be killed approximately halfway through this execution period. We cannot wait for the application to return, so instead we background it.
Here
$TIME
is approximately half the time measured in the previous step. -
ID the created user.
-
Create a new password hash for the user.
-
Pull the same trick as in step 3, but with setting the created user’s password.
Here
$UID
is the user ID retrieved in step 4 (note that there’s no space betweenUser
and the ID, so you’ll be hitting an endpoint that looks something like /org/freedesktop/Accounts/User1003),$PASSWORD_HASH
is the hash returned in step 5, and$TIME
is the same timing determined from step 3. The secondstring
being passed in the user password hint. -
Log in as the new user (probably via su).