# Container Escape to Shadow Admin: GKE Autopilot Vulnerabilities

GKE Autopilot allowlisted-workload check verified only image and command, letting a pod masquerade as Datadog agent, mount host paths, escape to node, and escalate to shadow cluster admin.

- Payout: Research
- Severity: high
- Program: Google VRP
- Credited: Unit 42
- Disclosed: 2022-03-08
- Write-up quality: 9/10
- Original: https://unit42.paloaltonetworks.com/gke-autopilot-vulnerabilities/
- Library page: https://bugbountylibrary.com/r/blog%3Aunit42-paloaltonetworks-com-gke-autopilot-vulnerabilities
- Tags: domain:cloud impact:internal-access impact:privesc kind:research platform:threat-intel sev:high tech:kubernetes technique:chained technique:source-review vuln:access-control vuln:misconfiguration vuln:privilege-escalation

**Target:** Kubernetes admission policy (OPA Gatekeeper + GKEAutopilot authz) and kube-system service accounts
**Root cause:** The allowlistedworkloads verification checked only container image and command, not the actual binary, so attacker code could run under an allowlisted identity and mount host paths. Separately, kube-system service accounts were fully exempt from policy, and metrics-server/stackdriver pods could update deployments.
**Steps:**
1. Create Autopilot cluster; inspect Gatekeeper constraints and the allowlistedworkloads CRD.
2. Read Datadog allowlist config: matching image+command permits mounting host paths read-only.
3. Deploy pod with the allowlisted image/command but attacker-controlled entrypoint, mounting the containerd socket and host paths.
4. From inside, use containerd socket to spawn a privileged container mounting the host filesystem.
5. Install a systemd service on the node spawning a reverse shell to attacker host.
6. Harvest kube-system pod service account tokens (metrics-server / stackdriver-metadata-agent) from node filesystem.
7. Use token to update an existing deployment: set serviceAccountName to target SA, add malicious container, read `/run/secrets/kubernetes.io/serviceaccount/token`.
8. Target clusterrole-aggregation-controller SA; update its bound ClusterRole to grant all privileges.
9. Schedule breakout pod onto target node via `nodeName` field (nodeSelectors rejected).
10. Install mutating admission webhook invisible to Autopilot admins as persistent backdoor.
**How found:** Started from Autopilot docs inviting VRP submissions on node access; enumerated Gatekeeper constraints and found the allowlistedworkloads CRD; noticed verification only checked image and command, insufficient to prove Datadog code runs. Built sa-hunter to map running pods to permissions, revealing metrics-server and stackdriver pods with deployment-update rights, and noticed kube-system SAs exempt from policy.
**Exploitation:** Attacker with pod-create rights deploys a pod masquerading as an allowlisted Datadog agent, mounts containerd socket, escapes to node, steals kube-system SA tokens, abuses deployment-update privilege to assume CRAC SA, grants itself full cluster admin, and installs invisible mutating webhooks for persistence.
**Escalation:** Node compromise -> steal neighboring pod SA tokens -> abuse metrics-server/stackdriver deployment-update permission to assume any SA -> CRAC SA grants all privileges -> exempt from Autopilot policy -> invisible webhook backdoor.
**Insight:** When a platform allowlists workloads by image/command strings, test whether you can supply the same strings with a different entrypoint or binary. Also map which running pods hold 'innocuous' verbs like update-deployments — that permission alone lets you swap a deployment's serviceAccountName and steal any SA token.
