# 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**](/githubimport/pentesting/pentesting-kubernetes.md#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](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server):

*“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**](/githubimport/pentesting/pentesting-kubernetes.md#cluster-hardening-rbac).

## Enumeration CheatSheet

To enumerate the environment you can upload the [**kubectl**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-kubectl-binary-with-curl-on-linux) 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`.

### Differences between `list` and `get` verbs

With **`get`** permissions you can access the API:

```
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
```

If you have the **`list`** permission, you are allowed to execute these API requests:

```bash
#In a namespace
GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments
```

If you have the **`watch`** permission, you are allowed to execute these API requests:

```
GET /apis/apps/v1/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name}  [DEPRECATED]
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments  [DEPRECATED]
GET /apis/apps/v1/watch/deployments  [DEPRECATED]
```

They open a streaming connection that returns you the full manifest of a Deployment whenever it changes (or when a new one is created).

{% hint style="danger" %}
The following `kubectl` commands indicates just how to list the objects. If you want to access the data you need to use `describe` instead of `get`
{% endhint %}

### Get namespaces

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

```bash
./kubectl get namespaces
```

{% endtab %}

{% tab title="API" %}

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

{% endtab %}
{% endtabs %}

### Get secrets

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

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

{% endtab %}

{% tab title="API" %}

```bash
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 %}

If you can read secrets you can use the following lines to get the privileges related to each to token:

```bash
for token in `./kubectl describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; ./kubectl --token $token auth can-i --list; echo; done
```

### Get Current Privileges

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

```bash
./kubectl auth can-i --list #Get privileges in general
./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:

{% content-ref url="/pages/-MaoHEppsTOktGIvih7u" %}
[Hardening Roles/ClusterRoles](/githubimport/pentesting/pentesting-kubernetes/hardening-roles-clusterroles.md)
{% endcontent-ref %}

### Get Current Context

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

```
kubectl config current-context
```

{% endtab %}
{% endtabs %}

### Get deployments

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

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

{% endtab %}

{% tab title="API" %}

```bash
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" %}

```bash
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 services

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

```
./kubectl get services
./kubectl get services -n custnamespace
```

{% endtab %}

{% tab title="API" %}

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

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

{% endtab %}
{% endtabs %}

### Get nodes

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

```
./kubectl get nodes
```

{% endtab %}

{% tab title="API" %}

```bash
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" %}

```bash
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:**

![](https://sickrov.github.io/media/Screenshot-161.jpg)

{% content-ref url="/pages/-MaoHEnLexLkmzfCLQCi" %}
[Docker Breakout](/githubimport/linux-unix/privilege-escalation/docker-breakout.md)
{% endcontent-ref %}

## Sniffing

By default there isn't any encryption in the communication between pods .Mutual authentication, two-way, pod to pod.

#### Create a sidecar proxy app <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>

Create your .yaml

```bash
kubectl run app --image=bash --comand -oyaml --dry-run=client > <appName.yaml> -- shj -c 'ping google.com'
```

Edit your .yaml and add the uncomment lines:

```yaml
#apiVersion: v1
#kind: Pod
#metadata:
#  name: security-context-demo
#spec:
#  securityContext:
#    runAsUser: 1000
#    runAsGroup: 3000
#    fsGroup: 2000
#  volumes:
#  - name: sec-ctx-vol
#    emptyDir: {}
#  containers:
#  - name: sec-ctx-demo
#    image: busybox
    command: [ "sh", "-c", "apt update && apt install iptables -y && iptables -L && sleep 1h" ]
    securityContext:
      capabilities:
        add: ["NET_ADMIN"]
 #   volumeMounts:
 #   - name: sec-ctx-vol
 #     mountPath: /data/demo
 #   securityContext:
 #     allowPrivilegeEscalation: true
```

See the logs of the proxy:

```bash
kubectl logs app -C proxy
```

More info at: <https://kubernetes.io/docs/tasks/configure-pod-container/security-context/>

## Search vulnerable network services

As you are inside the Kubernetes environment, if you cannot escalate privileges abusing the current pods privileges and you cannot escape from the container, you should **search potential vulnerable services.**

### Services

**For this purpose, you can try to get all the services of the kubernetes environment:**

```
kubectl get svc --all-namespaces
```

![](/files/-MaoHWwGlYuW9KYt5zjq)

### Scanning

The following Bash script (taken from a [Kubernetes workshop](https://github.com/calinah/learn-by-hacking-kccn/blob/master/k8s_cheatsheet.md)) will install and scan the IP ranges of the kubernetes cluster:

```bash
sudo apt-get update
sudo apt-get install nmap
nmap-kube () 
{ 
nmap --open -T4 -A -v -Pn -p 443,2379,8080,9090,9100,9093,4001,6782-6784,6443,8443,9099,10250,10255,10256 "${@}"
}
nmap-kube-discover () {
local LOCAL_RANGE=$(ip a | awk '/eth0$/{print $2}' | sed 's,[0-9][0-9]*/.*,*,');                                                                  
local SERVER_RANGES=" ";
SERVER_RANGES+="10.0.0.1 ";
SERVER_RANGES+="10.0.1.* ";
SERVER_RANGES+="10.*.0-1.* ";
nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
}
nmap-kube-discover
```

## References

{% embed url="<https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-3>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chinnidiwakar.gitbook.io/githubimport/pentesting/pentesting-kubernetes/enumeration-from-a-pod.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
