If workload identity or GKE metadata concealment are not enabled (not enabled by default), this attack is the only publicly known one that has a good chance to work in a GKE environment with your initial service account having zero rights. Being in GCP, a metadata server is available and used to store interesting information, including secrets. The kube-env
metadata endpoint is particularly interesting:
curl -s -H 'Metadata-Flavor: Google' '<http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env'
>
The output should contain bootstrapping credentials within the KUBELET_KEY, KUBELET_CERT and CA_CRT environment variables. As stated by Google: GKE uses instance metadata to configure node VMs, but some of this metadata is potentially sensitive and should be protected from workloads running on the cluster.
Those credentials have certificate signing request (CSR) permissions and an attack vector has been found that abuses those credentials to request certificates on behalf of nodes (see https://www.4armed.com/blog/hacking-kubelet-on-gke/ and https://github.com/bgeesaman/kube-env-stealer, congrats to both of them!).
Since CSRs are automatically signed, once a certificate is obtained, this certificate can be used to interact with the master API, impersonating the node that was chosen in the certificate signing request.
4armed nicely released kubeletmein to automate the process of getting the initial keys, submitting CSRs and creating config files for the kubectl
binary.
Bard Geesaman also released some scripts to automate all this.
At the time of writing, in a default GKE cluster install, the attack still works as it does not rely on a bug but on a default configuration (if the two protections mentioned at the beginning of this paragraph are not used). Depending which nodes you can impersonate, their permissions and the secrets they have access to, you may be able to get to cluster-admin
. You should refer to the table in the "Authorization" paragraph to look for service accounts that are the most interesting to impersonate.
The pods in GKE are running over a GCP VM (their Node) and if requests to the metadata server are made, they will be seen as originating from the node. This allows the pods to query the Node default service account information/credentials. As for the previous attack path, this will only work if workload identity is not enabled (or, if enabled, you could be lucky and a "binding" between the k8s service account and an underlying powerful GCP service account has been configured, but it is less likely). Depending on the rights/scope associated with the account, it may allow you to expand into GCP (you may want to refer to Chris's post about GCP privilege escalation at this point!).
To get this service account information:
curl <http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email> -H 'Metadata-Flavor:Google'
/token
instead of /email
for the oauth token and /scope
to know the scope granted.If you see the name of the account being <something>.svc.id.goog
, it means workload identity has been enabled and this is not the "real" GCP VM/Node service account. It is a "special" GCP account mapped to the pod service account, usually having no rights but it could have explicitly been configured with a few rights.