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

Exposed sensitive interfaces

Exposing a sensitive interface to the internet poses a security risk. Some popular frameworks were not intended to be exposed to the internet, and therefore don’t require authentication by default. Thus, exposing them to the internet allows unauthenticated access to a sensitive interface which might enable running code or deploying containers in the cluster by a malicious actor. Examples of such interfaces that were seen exploited in the past include Apache NiFi, Kubeflow, Argo Workflows, Weave Scope, and the Kubernetes dashboard.

Example

You can as an example follow the official Kubernetes documentation on except for the following minor but very relevant changes which will disable authentication completely and mess with permissions drastically.

In the official YAML file provided by the Kubernetes project we add a single line after the following part (please note that the version/tag might have changed once you’re reading this).

...
containers:
  - name: kubernetes-dashboard
    image: kubernetesui/dashboard:v2.6.1
    imagePullPolicy: Always
    ports:
      - containerPort: 8443
        protocol: TCP
    args:
      - --auto-generate-certificates
      - --namespace=kubernetes-dashboard
...

Now add --enable-skip-login so we get:

...
containers:
  - name: kubernetes-dashboard
    image: kubernetesui/dashboard:v2.6.1
    imagePullPolicy: Always
    ports:
      - containerPort: 8443
        protocol: TCP
    args:
      - --auto-generate-certificates
      - --namespace=kubernetes-dashboard
      - --enable-skip-login
...

In addition we give bind the kubernetes-dashboard ServiceAccount to the cluster-admin ClusterRole (really, don’t do this anywhere near production!).

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-cluster-admin
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin

Once deployed you can test everything by using the kubectl proxy command and access http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ but of course the interface is also reachable from within the cluster other Pods (see also “Cluster internal networking“).

Because of the added missconfiguration we can simply skip the login step.

And we gain access to the Kubernetes Dashboard (see also “Access Kubernetes dashboard“).

References