Mitigating CVE-2022-0811: Arbitrary code execution affecting CRI-O

By Stefano Chierici - MARCH 17, 2022

SHARE:

CVE-2022-0811 CRI-O

A new vulnerability CVE-2022-0811, alias cr8escape, with CVSS 8.8 (HIGH) has been found in the CRI-O container engine by Crowdstrike. This vulnerability can lead to arbitrary code execution.

The container engines affected are:

  • CRI-O version 1.19+

Any containerized infrastructure that relies on these vulnerable container engines is affected as well, including Kubernetes and OpenShift (version 4.6 to 4.10).

By exploiting the vulnerabilities, adversaries could bypass these safeguards and set arbitrary kernel parameters to compromise the host and get remote control over servers and potentially poison the container.

In this article, you’ll understand how CVE-2022-0811 works, what parts of Kubernetes are affected, and how to mitigate it.

Preliminary

Before we start talking about CVE-2022-0811 itself, we need to briefly talk about CRI-O and why this is a critical point.

CRI-O is a CNCF open source project from April 2019 and it is a community-driven container engine, which can replace the Docker service as the container engine for Kubernetes implementations, such as OpenShift Container Platform.

Architecture of CRI-O inside Kubernetes

The CRI-O container engine provides a stable and performant platform for running Open Container Initiative (OCI) compatible runtimes to launch containers and pods by engaging OCI-compliant runtimes like runc.

CRI-O’s goal is to be the reference container engine implementing the Kubernetes Container Runtime Interface (CRI) for OpenShift Container Platform and Kubernetes, replacing the Docker service.

The CVE-2022-0811 issue

The CVE-2022-0811 affects CRI-O from version v1.19+.

To check the current version you have installed in your system you can do:

run crio --version

CRI-O uses the pinns utility to set kernel options for a pod. In version 1.19 additional pinns support has been introduced and here is where the vulnerability has been found. With the new changes, pinns has a flaw that allows any kernel parameters to be set without the proper validation, allowing arbitrary code execution and can result in a compromise of the host.

In particular, the vulnerability affects the following piece of code in version 1.19 related to the functiongetSysctlForPinns. Inside that function there is a lack of validation for kernel parameters that can be exploited.

func getSysctlForPinns(sysctls map[string]string) string {
	// this assumes there's no sysctl with a `+` in it
	const pinnsSysctlDelim = "+"
	g := new(bytes.Buffer)
	for key, value := range sysctls {
		fmt.Fprintf(g, "'%s=%s'%s", key, value, pinnsSysctlDelim)
	}
	return strings.TrimSuffix(g.String(), pinnsSysctlDelim)
}

A patch has been released already from the version 1.19 and we can see here the validation introduced to stop the vulnerability.

Code enabling CVE-2022-0847

The impact of CVE-2022-0811

According to the CVSS system, CVE-2022-0811 scores 8.8 as HIGH severity.


To learn more about how a vulnerability score is calculated, Are Vulnerability Scores Tricking You? Understanding the severity of CVSS and using them effectively

The vulnerability has a low attack complexity and privileges are required to perform the attack. The impacts are very high on confidentiality and integrity and availability due to the possible total compromise of the attacked host.

It’s important to highlight that CRI-O is supported by Kubernetes and this means that Kubernetes clusters using the mentioned engines are affected as well by this vulnerability.

Mitigating CVE-2022-0811

If you’re impacted by this CVE, a fix has been released in CRI-O and you should apply the patch immediately.

If you cannot patch your systems immediately, detecting exploitation attempts and preventing attacks. Even though you might have already upgraded your system and container runtime engine affected by the vulnerability, those mechanisms are is still necessary to block any exploitation attempts and detect post-breach activities in your environment

Due to the exploitability of the CVE-2022-0811, we can act at the pod level to be sure to prevent any pods with specific settings to be deployed in our environment to block the exploitation and detect possible exploitation.

Let’s see how Falco and pod security can help us with this vulnerability.

Mitigating CVE-2022-0811 with Falco

If this vulnerability is successfully exploited, the pinns binary will be tricked into applying the attacker-supplied kernel settings. Settings which allow for a user-controlled script to be specified, such as kernel.core_pattern, are very useful in this situation.

The core_pattern usually contains a string used to name any future core dumps that our application can generate. When the parameter is preceded by a “|”, it redirects the output of the core into a program that would process it. However, the program waiting to do that job will actually be the malicious crafted script, allowing the attacker to run a program or script whenever a program crashes and drops a core dump.

This can be leveraged to run an attacker’s payload as causing a core dump is trivial.

This attack can be detected at runtime by the below Falco rule:

- rule: CVE-2022-0811 (CRI-O container escape)
  desc: Detects execution of pinns binary with container escape sysctl parameters (kernel.core_pattern)
  condition: spawned_process and proc.name = pinns and proc.cmdline contains "+" and proc.cmdline contains "=" and proc.cmdline contains "kernel.core_pattern"
  output: Possible CVE-2022-0811 exploit attempt using pinns %proc.cmdline
  priority: CRITICAL
  tags: [syscall,MITRE_T1068]

Be advised that there are likely other sysctls that could be applied in order to escape from a container (the list of “safe” sysctls, according to the official Kubernetes documentation, is only 5 long).

Pod Security

As we know a pod is the most fine-grained unit. However, securing Kubernetes pods is a huge topic and it could be done during the entire DevOps flow: build, deployment, and runtime.

To secure Kubernetes pods in the build stage, we will talk about how to harden a container image and configure the security attributes of pods (or pod templates) to reduce the attack surface. Although some of the security attributes of workloads, such as AppArmor and SELinux labels, take effect in the runtime stage, security control has already been defined for the workload.

Different tools can be used to secure Kubernetes pods and enforce those settings in our environment. PodSecurityPolicy might be the most famous but it is deprecated as of Kubernetes v1.21, and will be removed in v1.25.

Mitigating CVE-2022-0811 with OPA

Instead of PodSecurityPolicy, we could use OPA which works with a customized Kubernetes admission controller. OPA allows us to define the policies we need and prevent pods which use the CVE-2022-0811 from being deployed in our environment.

Architecture of OPA inside Kubernetes

In this specific scenario the vulnerability CVE-2022-0811 can be exploited by deploying a Pod as following:

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-set
spec:
  securityContext:
   sysctls:
   - name: kernel.shm_rmid_forced
     value: "1+kernel.core_pattern=|/var/lib/containers/storage/overlay/3ef1281bce79865599f673b476957be73f994d17c15109d2b6a426711cf753e6/diff/malicious.sh #"
  containers:
  - name: alpine
    image: alpine:latest

The important setting highlighted is the one that permits exploiting the vulnerability. Using OPA we can block any pod which uses special chars like “+” or “=” in the securityContent sysctl section.

package kubernetes.admission
valueSysctls(sysctls) {
        contains(sysctls.value, "+")
        contains(sysctls.value, "=")
}
deny[message] {
        assign(workload, input.request.object);
        assign(setSysctls, input.request.object.spec.securityContext.sysctls[_]);
        valueSysctls(setSysctls);
        assign(message, sprintf("Workflow or pod not compliant with the security policy.", [workload.metadata.name]))
}

Here is the error message from OPA when the suggested policy is in place and try to deploy the malicious pod

Error from server (Workflow or pod not compliant with the security policy.%!(EXTRA string=sysctl-set)): error when creating "test-sysctl.yaml": admission webhook "validating-webhook.openpolicyagent.org" denied the request: Workflow or pod not compliant with the security policy.%!(EXTRA string=sysctl-set)

Conclusion

We’ve seen the impact of this new HIGH Severity CVE-2022-0811 affecting CRI-O, which allows setting arbitrary kernel parameters to compromise the host and the above infrastructure, like Kubernetes clusters and so on.

Luckily, upgrading the CRI-O version will help you avoid this and similar attacks. In addition, applying the proper Pods security limitation could help in preventing possible attacks to your infrastructure.

Subscribe and get the latest updates