# 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**](..#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**](..#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="hardening-roles-clusterroles" %}
[hardening-roles-clusterroles](hardening-roles-clusterroles)
{% 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="../../linux-unix/privilege-escalation/docker-breakout" %}
[docker-breakout](../../linux-unix/privilege-escalation/docker-breakout)
{% 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/](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
```

![](https://4153509160-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MaoGr_g3I50alM2whW0%2Fsync%2F128d84542137419e4d0790f7c850e5c7478cc2ac.png?generation=1622227478543740\&alt=media)

### 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" %}
