PwnKit: Local Privilege Escalation Vulnerability Discovered in polkit’s pkexec (CVE-2021-4034)

Bharat Jogi

The Qualys Research Team has discovered a memory corruption vulnerability in polkit’s pkexec, a SUID-root program that is installed by default on every major Linux distribution. This easily exploited vulnerability allows any unprivileged user to gain full root privileges on a vulnerable host by exploiting this vulnerability in its default configuration.

Qualys VMDR

Free Trial

Fix the PwnKit Vulnerability with a Free Trial of Qualys

About Polkit pkexec for Linux

Polkit (formerly PolicyKit) is a component for controlling system-wide privileges in Unix-like operating systems. It provides an organized way for non-privileged processes to communicate with privileged processes. It is also possible to use polkit to execute commands with elevated privileges using the command pkexec followed by the command intended to be executed (with root permission).

Potential Impact of PwnKit Vulnerability

Successful exploitation of this vulnerability allows any unprivileged user to gain root privileges on the vulnerable host. Qualys security researchers have been able to independently verify the vulnerability, develop an exploit, and obtain full root privileges on default installations of Ubuntu, Debian, Fedora, and CentOS. Other Linux distributions are likely vulnerable and probably exploitable. This vulnerability has been hiding in plain sight for 12+ years and affects all versions of pkexec since its first version in May 2009 (commit c8c3d83,  “Add a pkexec(1) command”).

As soon as our Research Team confirmed the vulnerability, Qualys engaged in responsible vulnerability disclosure and has coordinated with both vendor and open-source distributions to announce the vulnerability.

Vulnerability Disclosure Timeline

  • 2021-11-18: Advisory sent to secalert@redhat.
  • 2022-01-11: Advisory and patch sent to distros@openwall.
  • 2022-01-25: Coordinated Release Date (5:00 PM UTC).

Proof of Concept Video of PwnKit Exploit

View this video of a potential exploit path.

PwnKit Scan Video

View this video on how to get visibility of the PwnKit vulnerability using Qualys VMDR.

Technical Details of PwnKit Vulnerability

What follows is an explanation of how the PwnKit vulnerability works.

The beginning of pkexec’s main() function processes the command-line arguments (lines 534-568), and searches for the program to be executed, if its path is not absolute, in the directories of the PATH environment variable (lines 610-640):

------------------------------------------------------------------------
435 main (int argc, char *argv[])
436 {
...
534   for (n = 1; n < (guint) argc; n++)
535     {
...
568     }
...
610   path = g_strdup (argv[n]);
...
629   if (path[0] != '/')
630     {
...
632       s = g_find_program_in_path (path);
...
639       argv[n] = path = s;
640     }
------------------------------------------------------------------------

Unfortunately, if the number of command-line arguments argc is 0 – which means if the argument list argv that we pass to execve() is empty, i.e. {NULL} – then argv[0] is NULL. This is the argument list’s terminator. Therefore:

  •  at line 534, the integer n is permanently set to 1;
  •  at line 610, the pointer path is read out-of-bounds from argv[1];
  •  at line 639, the pointer s is written out-of-bounds to argv[1].

But what exactly is read from and written to this out-of-bounds argv[1]?

To answer this question, we must digress briefly. When we execve() a new program, the kernel copies our argument, environment strings, and pointers (argv and envp) to the end of the new program’s stack; for example:

|---------+---------+-----+------------|---------+---------+-----+------------| 

| argv[0] | argv[1] | ... | argv[argc] | envp[0] | envp[1] | ... | envp[envc] | 

|----|----+----|----+-----+-----|------|----|----+----|----+-----+-----|------| 

     V         V                V           V         V                V 

"program" "-option"           NULL      "value" "PATH=name"          NULL 

Clearly, because the argv and envp pointers are contiguous in memory, if argc is 0, then the out-of-bounds argv[1] is actually envp[0], the pointer to our first environment variable, “value”. Consequently:

  •  At line 610, the path of the program to be executed is read out-of-bounds from argv[1] (i.e. envp[0]), and points to “value”;
  •  At line 632, this path “value” is passed to g_find_program_in_path()  (because “value” does not start with a slash, at line 629);
  •  Then, g_find_program_in_path() searches for an executable file named “value” in the directories of our PATH environment variable;
  •  If such an executable file is found, its full path is returned to pkexec’s main() function (at line 632);
  •  Finally, at line 639, this full path is written out-of-bounds to argv[1] (i.e. envp[0]), thus overwriting our first environment variable.

So, stated more precisely:

  •  If our PATH environment variable is “PATH=name”, and if the directory “name” exists (in the current working directory) and contains an  executable file named “value”, then a pointer to the string  “name/value” is written out-of-bounds to envp[0];

OR

  •  If our PATH is “PATH=name=.”, and if the directory “name=.” exists and contains an executable file named “value”, then a pointer to the  string “name=./value” is written out-of-bounds to envp[0].

In other words, this out-of-bounds write allows us to re-introduce an “unsecure” environment variable (for example, LD_PRELOAD) into pkexec’s environment. These “unsecure” variables are normally removed (by ld.so) from the environment of SUID programs before the main() function is called. We will exploit this powerful primitive in the following section.

Last-minute note: polkit also supports non-Linux operating systems such as Solaris and *BSD, but we have not investigated their exploitability. However, we note that OpenBSD is not exploitable, because its kernel refuses to execve() a program if argc is 0.

Solution: How to Patch the PwnKit Vulnerability

Given the breadth of the attack surface for this vulnerability across both Linux and non-Linux OS, Qualys recommends that users apply patches for this vulnerability immediately.

Current Qualys customers can search the vulnerability knowledgebase for CVE-2021-4034 to identify all the QIDs and assets vulnerable for this vulnerability.

Other interested parties can start a free Qualys VMDR trial to get full access to the QIDs (detections) for CVE-2021-4034, where all vulnerable assets can be identified.

The Qualys Research Team has discovered a memory corruption vulnerability in polkit’s pkexec, a SUID-root program that is installed by default on every major Linux distribution. This easily exploited vulnerability allows any unprivileged user to gain full root privileges on a vulnerable host by exploiting this vulnerability in its default configuration.


Fix the PwnKit Vulnerability with a Free Trial of Qualys


About Polkit pkexec for Linux

Qualys QID Coverage

Qualys is releasing the QIDs in the table below as they become available starting with vulnsigs version VULNSIGS-2.5.387-2 and in Linux Cloud Agent manifest version lx_manifest-2.5.387.2-1.

QIDTitleVulnSigs Version
376287Polkit pkexec Local Privilege Escalation Vulnerability (PwnKit)VULNSIGS-2.5.387-2  / lx_manifest- VULNSIGS-2.5.387.2-1  

Discover Vulnerable Linux Servers Using Qualys VMDR

Identify Assets Running Linux Kernel

The following instructs current Qualys customers on how to detect PwnKit in their environment.

The first step in managing this critical vulnerability and reducing risk is the identification of all assets running Linux OS. Qualys VMDR makes it easy to identify such assets.

Query: operatingSystem.category1:`Linux`

Once the hosts are identified, they can be grouped together with a ‘dynamic tag’, let’s say: “Linux Servers”. This helps by automatically grouping existing hosts with the above vulnerabilities as well as any new Linux assets that spin up in your environment. Tagging makes these grouped assets available for querying, reporting, and management throughout the Qualys Cloud Platform.

Prioritize Based on RTIs

Using Qualys VMDR, the PwnKit vulnerability can be prioritized using the following real-time threat indicators (RTIs):

  • Predicted_High_Risk
  • Privilege_Escalation
  • Easy_Exploit
  • High_Lateral_Movement

Patch With Qualys VMDR

We expect vendors to release patches for this vulnerability in the short term. Qualys Patch Management can be used to deploy those patches to vulnerable assets, when available.

Using the same prioritization based on the RTI method as described above, customers can use the “patch now” button found to the right of the vulnerability to add PwnKit to a patch job. Once patches are released, Qualys will find the relevant patches for this vulnerability and automatically add those patches to a patch job. This will allow customers to deploy those patches to vulnerable devices, all from Qualys Cloud Platform.

Detect Impacted Assets with Threat Protection

VMDR also enables you to automatically map assets vulnerable to PwnKit vulnerabilities using Threat Protect.

Track Vulnerability with VMDR Dashboard

With VMDR Unified Dashboard, you can track this vulnerability, impacted hosts, status, and overall management in real time. With trending enabled for dashboard widgets, you can keep track of these vulnerability trends in your environment using the “PwnKit” Dashboard.

Leverage Qualys XDR Identifying Exploit Attempts

Qualys XDR customers can use the rule name titled – “T1068 – Linux: Polkit pkexec Local Privilege Escalation Vulnerability Detected (CVE-2021-4034)” to detect post-exploitation activity on affected systems. Post enablement, customers can also search for vulnerable systems using the following QQL query:

eventName:” The value for the SHELL variable was not found the /etc/shells file“ or “contains suspicious content“

Customers will be able to see output similar to the following screenshot:

Interested customers can contact Qualys Support for a copy of the XDR rule until it is available in the rule library.

Vendor References

Read the PwnKit security advisory

Frequently Asked Questions (FAQs)

What versions are vulnerable?

All Polkit versions from 2009 onwards are vulnerable.

Will the Qualys Research Team publish exploit code for this vulnerability?

No. But given how easy it is to exploit the vulnerability, we anticipate public exploits to become available within a few days of this blog’s post date.

Are there any mitigations for this vulnerability?

If no patches are available for your operating system, you can remove the SUID-bit from pkexec as a temporary mitigation; for example:

# chmod 0755 /usr/bin/pkexec

Is this vulnerability remotely exploitable?

No. But if an attacker can log in as any unprivileged user, the vulnerability can be quickly exploited to gain root privileges.

Is it possible to check for evidence of exploitation?

Yes, this exploitation technique leaves traces in the logs (either “The value for the SHELL variable was not found the /etc/shells file” or “The value for environment variable […] contains suspicious content”). However, please note that this vulnerability is also exploitable without leaving any traces in the logs.

Why is the vulnerability named “PwnKit”?

This is a pun intended on the name of the vulnerable application Polkit.

Qualys VMDR

Free Trial

Fix the PwnKit Vulnerability with a Free Trial of Qualys

Show Comments (8)

Leave a Reply to Info security Cancel reply

Your email address will not be published.

  1. This is similar to a typical sudo exploit. On my personal systems, I always remove sudo and remove all users from the sudo group. In that case, the exploit does not seem to work.

    I understand that this is not a solution for a non-personal system with multiple admins, but it still valuable information for many

  2. Hello Bharat,
    On your vulnerability disclosure timeline was the opensource community not notified till 7weeks or so after contacting RedHat? Any reason for this delay ?

    2021-11-18: Advisory sent to secalert@redhat.
    2022-01-11: Advisory and patch sent to distros@openwall.
    2022-01-25: Coordinated Release Date (5:00 PM UTC).

  3. I am still not fully convinced this is a critical and urgent problem: to let pkexec run your program as root, you need to know the root password and enter it first, then when you know the root password, if you want you can do anything, why need to do the exploit?