Browse CTFs New CTF Sign in

Kubernetes Dashboard Unauthenticated Access: Pod Creation, Secret Enumeration and Admin Escalation

binary_exploitation Difficulty 1–5 30 min certifiable

Theory

Why This Matters

In 2018, Tesla's Kubernetes clusters were compromised by attackers who discovered a Kubernetes Dashboard exposed to the internet without authentication. The dashboard's service account had cluster-admin privileges, and the attackers used it to enumerate running pods, extract AWS credentials from pod environment variables, and deploy cryptomining workloads. This incident, disclosed by RedLock, was the case that made Kubernetes Dashboard security a mainstream concern. The same misconfiguration — unauthenticated dashboard with cluster-admin RBAC bindings — has been found in subsequent assessments at financial institutions, healthcare providers, and SaaS companies. The dashboard is a legitimate operations tool; the vulnerability is in how it is deployed and what RBAC permissions its service account holds.

Core Concept

The Kubernetes Dashboard is a web-based UI for managing Kubernetes clusters. When properly configured, it requires token-based authentication or integrates with an identity provider via OIDC, and its service account holds only the permissions needed to display cluster state. When misconfigured, it is deployed with:

  1. --enable-skip-login or the skip button enabled, allowing anonymous access to the dashboard UI.
  2. A service account bound to the cluster-admin ClusterRole, granting full control over every resource in the cluster.
  3. Exposed via a NodePort, LoadBalancer, or Ingress without network restrictions — accessible from the internet.

The combination of these three misconfigurations allows any unauthenticated internet user to interact with the cluster as a cluster administrator: create pods, read secrets, modify deployments, and execute commands inside existing containers.

RBAC analysis for the dashboard: The default dashboard service account (kubernetes-dashboard in the kubernetes-dashboard namespace) has minimal permissions by design. The vulnerability arises when operators create a ClusterRoleBinding attaching cluster-admin to the dashboard service account, typically to "fix" permission errors rather than diagnosing the correct minimal permission set.

Network exposure analysis: The dashboard service type and ingress rules determine whether external access is possible. ClusterIP (the default) requires kubectl port-forward for access — not externally reachable. NodePort exposes it on all cluster nodes. LoadBalancer creates a cloud load balancer with a public IP. Ingress with no authentication middleware is equivalent to LoadBalancer exposure.

Metrics Server is often co-deployed with the dashboard and may expose its own API endpoint without authentication — a separate but related finding.

Technical Deep-Dive

# Enumerate all services across namespaces to find the dashboard
kubectl get services -A | grep -i dashboard

# Check the service type and external IPs
kubectl get service kubernetes-dashboard -n kubernetes-dashboard 
  -o jsonpath='{.spec.type}: {.status.loadBalancer.ingress[*].ip}'

# Check all ingress resources for dashboard exposure
kubectl get ingress -A | grep -i dashboard

# Describe the dashboard service account
kubectl describe serviceaccount kubernetes-dashboard -n kubernetes-dashboard

# Find all ClusterRoleBindings for the dashboard service account
kubectl get clusterrolebindings -o json | 
  python3 -c "
import sys, json
bindings = json.load(sys.stdin)
for b in bindings['items']:
    for subj in b.get('subjects', []):
        if 'dashboard' in subj.get('name', '').lower():
            role = b['roleRef']['name']
            print(f"Binding: {b['metadata']['name']}  Role: {role}  Subject: {subj['name']}")
"

# Check if skip-login is enabled (in dashboard deployment args)
kubectl get deployment kubernetes-dashboard -n kubernetes-dashboard 
  -o jsonpath='{.spec.template.spec.containers[0].args}' | tr ',' '
' | grep skip

# List all secrets accessible from the dashboard namespace
kubectl get secrets -n kubernetes-dashboard

# Check if the dashboard can access secrets cluster-wide (if cluster-admin bound)
kubectl auth can-i get secrets --all-namespaces 
  --as=system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard

# Use pacu for AWS credential harvesting from dashboard (if cluster has AWS workloads)
# First: use the dashboard to exec into a pod and extract IMDS credentials
# kubectl exec -n production deployment/api-server -- 
#   curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Run kube-bench to check dashboard-related CIS controls
kube-bench run --targets=node,policies --check 1.2.1,5.1.1,5.1.2
# Secure dashboard deployment pattern
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
---
# Bind to minimal read-only role — NOT cluster-admin
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view               # read-only, no secret values
  # DO NOT use cluster-admin here
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
---
# Expose only as ClusterIP — access via kubectl port-forward only
apiVersion: v1
kind: Service
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: ClusterIP           # NOT NodePort or LoadBalancer
  ports:
  - port: 443
    targetPort: 8443

Security Assessment Methodology

  1. Discover the dashboard service. Run kubectl get services -A | grep -i dashboard and kubectl get ingress -A. Check service types: LoadBalancer or NodePort with external IPs is an internet-exposure finding. Check ingress rules for authentication middleware (oauth2-proxy, auth annotations).
  2. Test unauthenticated access. Port-forward to the dashboard (kubectl port-forward -n kubernetes-dashboard svc/kubernetes-dashboard 8443:443) and browse to https://localhost:8443. If the login page has a "Skip" button or if you can reach the dashboard UI without a token, unauthenticated access is confirmed. If externally exposed, test directly from a browser without any tokens.
  3. Enumerate RBAC bindings for the dashboard service account. Check all ClusterRoleBindings and RoleBindings for the kubernetes-dashboard service account. A binding to cluster-admin is a critical finding even if authentication is required — the service account should have only read access.
  4. Assess what the service account can access. Use kubectl auth can-i --list --as=system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard to enumerate all permitted actions. Focus on: get secrets, exec into pods, create pods, list nodes.
  5. Check network policies. Verify whether a NetworkPolicy restricts ingress to the dashboard pod to internal IPs only. Missing network policies combined with NodePort exposure mean the dashboard is reachable from any node IP.
  6. Remediate by: setting the dashboard service type to ClusterIP; disabling --enable-skip-login in dashboard deployment args; binding the dashboard service account to the view ClusterRole (or a custom role with only required permissions); adding an authentication proxy (oauth2-proxy + OIDC) in front of any ingress exposure; enforcing a NetworkPolicy restricting ingress to the dashboard namespace from admin VPN CIDRs only.

Common Assessment Errors

  • Assuming authentication means safe. A dashboard that requires a bearer token is still a critical finding if the service account is cluster-admin and the token is stored insecurely (in a developer's ~/.kube/config or a CI/CD environment variable). Authentication without least-privilege RBAC is incomplete remediation.
  • Missing the metrics-server API exposure. Metrics Server, commonly deployed alongside the dashboard, exposes the /apis/metrics.k8s.io endpoint. In older versions, this was accessible without authentication. Always enumerate API server extensions alongside the dashboard.
  • Not checking for dashboard in non-default namespaces. Operators sometimes deploy the dashboard in kube-system, monitoring, or a custom namespace. kubectl get services -A | grep -i dashboard covers all namespaces.
  • Ignoring the kubernetes-dashboard Helm chart skip-auth flag. Helm chart installations of the dashboard may have extraArgs: [--enable-skip-login] set in values.yaml. Always inspect the dashboard deployment's container args, not just the Helm chart defaults.
  • Treating ClusterIP as definitely safe. ClusterIP is not accessible from outside the cluster, but pods inside the cluster — including any compromised workload — can reach it. An attacker with a foothold on any pod can access a ClusterIP dashboard. Always assess RBAC regardless of service type.
  • Missing the Kubernetes API server directly. The Kubernetes API server itself (kubectl proxy or direct HTTPS access) may be accessible to the dashboard service account token. Enumerate what the token can do against the API server directly, not only through the dashboard UI.

NICE Framework Alignment

Code Knowledge/Skill/Task Statement How This Card Develops It
K0053 Knowledge of security risk management processes Understanding that dashboard exposure is a risk multiplier: it provides a GUI for every RBAC permission the service account holds, lowering the skill bar for cluster compromise
K0167 Knowledge of system administration, network, and OS hardening techniques Hardening Kubernetes dashboard deployments: ClusterIP service type, disabled skip-login, least-privilege RBAC, authentication proxy, and NetworkPolicy restrictions
S0073 Skill in conducting vulnerability scans and recognizing vulnerabilities Using kubectl get services, RBAC enumeration, and kube-bench to identify exposed dashboards, over-privileged service accounts, and missing authentication controls
T0144 Conduct penetration testing as required for new or updated applications Enumerating Kubernetes Dashboard exposure and RBAC bindings during cluster penetration tests to demonstrate unauthenticated cluster-admin access paths
T0395 Write code to address security vulnerabilities Writing secure Kubernetes RBAC manifests with minimal dashboard service account permissions and ClusterIP service configurations with NetworkPolicy restrictions

Further Reading

  • Kubernetes Security — Best Practices Guide — Kubernetes Documentation (kubernetes.io/docs/concepts/security)
  • CIS Kubernetes Benchmark — Center for Internet Security, Section 5.1: RBAC and Service Accounts (cisecurity.org)
  • Kubernetes Goat — Dashboard Attack Scenario — Madhu Akula, interactive Kubernetes security training (github.com/madhuakula/kubernetes-goat)

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.