~ 5 min read
Part 4 - Mapping the MITRE ATT&CK framework to your Kubernetes cluster: Escalation
(This is Part 4 of a 9 part blog series that explains the Kubernetes MITRE ATT&CK like Threat Matrix created by Microsoft from an attacker perspective and attempts to provide how real world attackers use the techniques covered in the framework to gain access, execute, persist and explore Kubernetes cluster environments.)
Use this index to navigate to and read the rest of the posts in this series
- Part 1 - Initial access
- Part 2 - Execution
- Part 3 - Persistence
- Part 5 - Defense evasion
- Part 6 - Credential access
- Part 7 - Discovery
- Part 8 - Lateral movement
- Part 9 - Impact
(This blog post discusses the fourth tactic described in the MITRE ATT&CK framework for Kubernetes - Privilege Escalation)
In the last post, we saw the techniques in the Persistence tactic of the MITRE ATT&CK framework for Kubernetes. Let’s look at the next tactic, Privilege Escalation and the techniques that attackers use within this tactic. For reference, here’s the framework that Microsoft created as a visual cue to the overall tactics and techniques that attackers use when attacking a Kubernetes cluster.
Attackers seldom gain privileged access to targets upon exploitation. Services and applications are supposed to run as a lower privilege user to avoid any unnecessary violations of security boundaries. Privilege escalation is a very common tactic that attackers employ to gain additional access either to a system that is connected to the exploited endpoint or vertically to a different user level to gain access to restricted data or features.
A privileged container allows a process to access the underlying host with all of the root capabilities of the host machine. This gives the container the ability to view, interact and modify processes, network operations, IPC calls, file system access, mount points, SELinux configurations etc. as the root user on the host.
The following yaml will start a privileged container and allow the attacker to jump to the host.
apiVersion: v1 kind: Pod metadata: name: privileged-ubuntu labels: app: privileged-ubuntu spec: containers: - image: ubuntu command: - "sleep" - "3600" imagePullPolicy: IfNotPresent name: ubuntu securityContext: capabilities: add: ["NET_RAW", "NET_ADMIN", "SYS_ADMIN"] runAsUser: 0 restartPolicy: Never hostNetwork: true hostPID: true
In the container created using the above yaml, install capsh using apt-get install libcap2-bin and run the capsh —print command to see the container’s capabilities.
An attacker may have the ability to launch a privileged container or may have found themselves inside an already running privileged container, in either case a privilege escalation would mean a container to host escape.
The cluster-admin role is an RBAC, default role created alongside Kubernetes and is a super-user user facing ClusterRole. It essentially allows for access to all Kubernetes APIs resources and verbs.
You can describe the role using the command kubectl get clusterrole cluster-admin -o yaml
An attacker who has the RBAC permissions to create role bindings can create a binding to the cluster-admin role thus elevating their privilege from a Kubernetes user to a Cluster administrator.
Apart from providing persistence within the cluster, the hostPath volume can be used to read/write to configuration files or access the container daemon (Docker for example on the host) on the host allowing the user to escape the container and perform additional host based attacks.
For example, consider the following yaml and the ability of a user to start a new pod in a specific namespace. An attacker could launch a container using the mount point as mentioned below and then chroot their way to the host.
apiVersion: v1 kind: Pod metadata: labels: run: attacker-pod name: attacker-pod spec: hostPID: true hostIPC: true hostNetwork: true volumes: - name: host-fs hostPath: path: / containers: - image: ubuntu name: attacker-pod command: ["/bin/sh", "-c", "sleep infinity"] securityContext: privileged: true allowPrivilegeEscalation: true volumeMounts: - name: host-fs mountPath: /host restartPolicy: Never
You can read about this in more detail at https://blog.appsecco.com/kubernetes-namespace-breakout-using-insecure-host-path-volume-part-1-b382f2a6e216
Access cloud resources
Managed clusters running on cloud providers are setup in a way so that the user can manage the cluster using the cloud IAM access. For example, Azure uses a “service principal” token that is stored in AKS which is used to perform CRUD operations on the cluster. However, the way this token is created, it also has Azure contributor rights, allowing an attacker who manages to get hold of the token to interact with other Azure cloud resources.
You can also see similar behavior with Google GKE where the default cluster setup provides access to extra OAuth scopes that can be used to gain read access to GCP storage. This role, devstorage.read_only provides read access to buckets and files within them using a token that can be generated using the metadata endpoint.
Ideally in most cases of offensive tactics, persistence and privilege escalation are often attempted side by side as the chances of having a far more robust persistence technique would potentially be through a privileged account. Multiple features within Kubernetes allow for users to escalate privileges and escape the container environment to access the hosts resources.
In the next post we will see how attackers evade defenses and hide their tracks within the compromised environment using the framework as our guide.
This article is brought to you by Kloudle Academy, a free e-resource compilation, created and curated by Kloudle. Kloudle is a cloud security management platform that uses the power of automation and simplifies human requirements in cloud security. If you wish to give your feedback on this article, you can write to us here.