hacktricks/pentesting/pentesting-kubernetes/enumeration-from-a-pod.md
2021-04-28 17:15:53 +00:00

5.4 KiB

Enumeration from a Pod

In a situation where you have managed to break into a Kubernetes Pod you could start enumerating the kubernetes environment from within.

Service Account Tokens

Before continuing, if you don't know what is a service in Kubernetes I would suggest you to follow this link and read at least the information about Kubernetes architecture.

ServiceAccount is an object managed by Kubernetes and used to provide an identity for processes that run in a pod.
Every service account has a secret related to it and this secret contains a bearer token. This is a JSON Web Token JWT, a method for representing claims securely between two parties.

Usually in the directory /run/secrets/kubernetes.io/serviceaccount or /var/run/secrets/kubernetes.io/serviceaccount you can find the files:

  • ca.crt: It's the ca certificate to check kubernetes communications
  • namespace: It indicates the current namespace
  • token: It contains the service token of the current pod.

The service account token is being signed by the key residing in the file sa.key and validated by sa.pub.

Default location on Kubernetes:

  • /etc/kubernetes/pki

Default location on Minikube:

  • /var/lib/localkube/certs

Taken from the Kubernetes documentation:

“When you create a pod, if you do not specify a service account, it is automatically assigned the default service account in the same namespace.”

Hot Pods

Hot pods are pods containing a privileged service account token. A privileged service account token is a token that has permission to do privileged tasks such as listing secrets, creating pods, etc.

RBAC

If you don't know what is RBAC, read this section.

Enumeration CheatSheet

To enumerate the environment you can upload the kubectl binary and use it. Also, using the service token obtained before you can manually access some endpoints of the API Server.
In order to find the the IP of the API service check the environment for a variable called KUBERNETES_SERVICE_HOST.

Get namespaces

{% tabs %} {% tab title="kubectl" %}

./kubectl get namespaces

{% endtab %}

{% tab title="API" %}

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/

{% endtab %} {% endtabs %}

Get Current Privileges

{% tabs %} {% tab title="kubectl" %}

./kubectl auth can-i --list #Get privileges in current namespace
./kubectl auth can-i --list -n custnamespace #Get privileves in custnamespace

{% endtab %} {% endtabs %}

Once you know which privileges you have, check the following page to figure out if you can abuse them to escalate privileges:

{% page-ref page="hardening-roles-clusterroles.md" %}

Get Current Context

{% tabs %} {% tab title="Kubectl" %}

kubectl config current-context

{% endtab %} {% endtabs %}

Get/List secrets

{% tabs %} {% tab title="kubectl" %}

./kubectl get secrets -o yaml
./kubectl get secrets -o yaml -n custnamespace

./kubectl list secrets -o yaml
./kubectl list secrets -o yaml -n custnamespace

{% endtab %}

{% tab title="API" %}

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/default/secrets/

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/custnamespace/secrets/

{% endtab %} {% endtabs %}

Get deployments

{% tabs %} {% tab title="kubectl" %}

./kubectl get deployments
./kubectl get deployments -n custnamespace

{% endtab %}

{% tab title="API" %}

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/default/deployments/

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/custnamespace/deployments/

{% endtab %} {% endtabs %}

Get pods

{% tabs %} {% tab title="kubectl" %}

./kubectl get pods
./kubectl get pods -n custnamespace

{% endtab %}

{% tab title="API" %}

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/default/pods/

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/namespaces/custnamespace/pods/

{% endtab %} {% endtabs %}

Get nodes

{% tabs %} {% tab title="kubectl" %}

./kubectl get nodes

{% endtab %}

{% tab title="API" %}

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/api/v1/nodes/

{% endtab %} {% endtabs %}

Get daemonsets

{% tabs %} {% tab title="kubectl" %}

./kubectl get daemonsets

{% endtab %}

{% tab title="API" %}

curl -v -H "Authorization: Bearer <jwt_token>" \
https://<Kubernetes_API_IP>:<port>/apis/extensions/v1beta1/namespaces/default/daemonsets

{% endtab %} {% endtabs %}

Get "all"

{% tabs %} {% tab title="kubectl" %}

./kubectl get all

{% endtab %} {% endtabs %}

Pod Breakout

If you are lucky enough you may be able to escape from it to the node:

{% page-ref page="../../linux-unix/privilege-escalation/docker-breakout.md" %}