title |
---|
TOKEN_STEAL |
Source | Destination | MITRE |
---|---|---|
Volume | Identity | Unsecured Credentials, T1552 |
This attack represents the ability to steal a K8s API token from an accessible volume.
An attacker with access to a pod with an automounted serviceaccount token (the default behaviour) can steal the serviceaccount access token to perform actions in the K8s API. More significantly if an attacker is able to access all or part of the K8s node filesystem e.g via a hostPath
mount, an attacker could retrieve the service account tokens for ALL pods running on the node. This attack is possible from access to a container or node and each case is discussed separately throughout.
- A service account token mounted into the container via a projected volume (default behaviour).
- Access to a K8s node filesystem (
/var/lib/kubelet/pods
or any parent directory)
Check whether a serviceaccount token is automounted:
ls -la /var/run/secrets/kubernetes.io/
ls -la /run/secrets/kubernetes.io/
Check whether a host volume mount provides access to other pods' tokens:
ls -la /<HOST MOUNT>/var/lib/kubelet/pods/
KDigger can also help with this.
Confirm access to the location of pod tokens:
ls -la /var/lib/kubelet/pods/
See IDENTITY_ASSUME for how to use a captured token.
From within a container read the service account token mounted in the default location:
cat /run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/token
Steal access tokens for ALL pods running on the node:
find /var/lib/kubelet/pods/ -name token -type l 2>/dev/null
# /var/lib/kubelet/pods/5a9fc508-8410-444a-bf63-9f11e5979bee/volumes/kubernetes.io~projected/kube-api-access-225d6/token
# /var/lib/kubelet/pods/a1176593-34a2-43e6-8bdd-ed10fa148fe7/volumes/kubernetes.io~projected/kube-api-access-ng6px/token
# /var/lib/kubelet/pods/10b90d62-6b16-4aa7-9e72-75f18dcca5a8/volumes/kubernetes.io~projected/kube-api-access-j7dsp/token
# /var/lib/kubelet/pods/dfbf38ad-2e92-44e0-b05
- Monitor for access to well-known K8s secrets paths from unusual processes.
When a pod is being created, it automatically mounts a service account (the default is default service account in the same namespace). Not every pod needs the ability to access the API from within itself.
From version 1.6+ it is possible to prevent automounting of serviceaccount tokens on pods using:
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa1
automountServiceAccountToken: false