# Pentesting Kubernetes Services

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

Kubernetes utilise plusieurs **services réseau spécifiques** que vous pourriez trouver **exposés à Internet** ou dans un **réseau interne une fois que vous avez compromis un pod**.

## Trouver des pods exposés avec OSINT

Une façon pourrait être de rechercher `Identity LIKE "k8s.%.com"` dans [crt.sh](https://crt.sh) pour trouver des sous-domaines liés à kubernetes. Une autre façon pourrait être de rechercher `"k8s.%.com"` sur github et de chercher des **fichiers YAML** contenant la chaîne.

## Comment Kubernetes expose des services

Il pourrait être utile pour vous de comprendre comment Kubernetes peut **exposer des services publiquement** afin de les trouver :

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

## Trouver des pods exposés via le scan de ports

Les ports suivants pourraient être ouverts dans un cluster Kubernetes :

| Port            | Process        | Description                                                            |
| --------------- | -------------- | ---------------------------------------------------------------------- |
| 443/TCP         | kube-apiserver | Port API Kubernetes                                                    |
| 2379/TCP        | etcd           |                                                                        |
| 6666/TCP        | etcd           | etcd                                                                   |
| 4194/TCP        | cAdvisor       | Métriques de conteneur                                                |
| 6443/TCP        | kube-apiserver | Port API Kubernetes                                                    |
| 8443/TCP        | kube-apiserver | Port API Minikube                                                    |
| 8080/TCP        | kube-apiserver | Port API non sécurisé                                                |
| 10250/TCP       | kubelet        | API HTTPS qui permet un accès en mode complet                          |
| 10255/TCP       | kubelet        | Port HTTP en lecture seule non authentifié : pods, pods en cours d'exécution et état des nœuds |
| 10256/TCP       | kube-proxy     | Serveur de vérification de santé Kube Proxy                           |
| 9099/TCP        | calico-felix   | Serveur de vérification de santé pour Calico                          |
| 6782-4/TCP      | weave          | Métriques et points de terminaison                                     |
| 30000-32767/TCP | NodePort       | Proxy vers les services                                               |
| 44134/TCP       | Tiller         | Service Helm à l'écoute                                              |

### 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

C'est le **service API Kubernetes** avec lequel les administrateurs communiquent généralement en utilisant l'outil **`kubectl`**.

**Ports communs : 6443 et 443**, mais aussi 8443 dans minikube et 8080 comme non sécurisé.
```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
```
**Vérifiez la page suivante pour apprendre comment obtenir des données sensibles et effectuer des actions sensibles en communiquant avec ce service :**

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

### API Kubelet

Ce service **s'exécute sur chaque nœud du cluster**. C'est le service qui va **contrôler** les pods à l'intérieur du **nœud**. Il communique avec le **kube-apiserver**.

Si vous trouvez ce service exposé, vous pourriez avoir trouvé un **RCE non authentifié**.

#### API Kubelet
```bash
curl -k https://<IP address>:10250/metrics
curl -k https://<IP address>:10250/pods
```
Si la réponse est `Unauthorized`, cela nécessite une authentification.

Si vous pouvez lister les nœuds, vous pouvez obtenir une liste des points de terminaison kubelets avec :
```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 (Lecture seule)
```bash
curl -k https://<IP Address>:10255
http://<external-IP>:10255/pods
```
### API etcd
```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
```
Vous pourriez abuser de ce service pour élever les privilèges à l'intérieur de Kubernetes :

### cAdvisor

Service utile pour recueillir des métriques.
```bash
curl -k https://<IP Address>:4194
```
### NodePort

Lorsqu'un port est exposé sur tous les nœuds via un **NodePort**, le même port est ouvert sur tous les nœuds, proxifiant le trafic vers le **Service** déclaré. Par défaut, ce port sera dans la **plage 30000-32767**. Ainsi, de nouveaux services non vérifiés pourraient être accessibles via ces ports.
```bash
sudo nmap -sS -p 30000-32767 <IP>
```
## Configurations vulnérables

### Accès anonyme à Kube-apiserver

L'accès anonyme aux **points de terminaison de l'API kube-apiserver n'est pas autorisé**. Mais vous pouvez vérifier certains points de terminaison :

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

### **Vérification de l'accès anonyme à ETCD**

L'ETCD stocke les secrets du cluster, les fichiers de configuration et d'autres **données sensibles**. Par **défaut**, l'ETCD **ne peut pas** être accessible **anonymement**, mais il est toujours bon de vérifier.

Si l'ETCD peut être accessible anonymement, vous devrez peut-être **utiliser** l'outil [**etcdctl**](https://github.com/etcd-io/etcd/blob/master/etcdctl/READMEv2.md). La commande suivante récupérera toutes les clés stockées :
```bash
etcdctl --endpoints=http://<MASTER-IP>:2379 get / --prefix --keys-only
```
### **Kubelet RCE**

La [**documentation de Kubelet**](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) explique qu'en **default, l'accès anonyme** au service est **autorisé :**

> Permet les requêtes anonymes au serveur Kubelet. Les requêtes qui ne sont pas rejetées par une autre méthode d'authentification sont traitées comme des requêtes anonymes. Les requêtes anonymes ont un nom d'utilisateur de `system:anonymous`, et un nom de groupe de `system:unauthenticated`

Pour mieux comprendre comment fonctionne **l'authentification et l'autorisation de l'API Kubelet**, consultez cette page :

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

L'**API du service Kubelet n'est pas documentée**, mais le code source peut être trouvé ici et trouver les points de terminaison exposés est aussi simple que **d'exécuter** :
```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/").
```
Tous semblent intéressants.

Vous pouvez utiliser l'outil [**Kubeletctl**](https://github.com/cyberark/kubeletctl) pour interagir avec les Kubelets et leurs points de terminaison.

#### /pods

Ce point de terminaison liste les pods et leurs conteneurs :
```bash
kubeletctl pods
```
#### /exec

Ce point de terminaison permet d'exécuter du code à l'intérieur de n'importe quel conteneur très facilement :
```bash
kubeletctl exec [command]
```
> [!NOTE]
> Pour éviter cette attaque, le service _**kubelet**_ doit être exécuté avec `--anonymous-auth false` et le service doit être segregé au niveau du réseau.

### **Vérification de l'exposition des informations du Kubelet (Port en lecture seule)**

Lorsqu'un **port en lecture seule du kubelet** est exposé, il devient possible pour des parties non autorisées de récupérer des informations de l'API. L'exposition de ce port peut conduire à la divulgation de divers **éléments de configuration du cluster**. Bien que les informations, y compris **les noms des pods, les emplacements des fichiers internes et d'autres configurations**, ne soient pas critiques, leur exposition pose néanmoins un risque pour la sécurité et doit être évitée.

Un exemple de la façon dont cette vulnérabilité peut être exploitée implique un attaquant distant accédant à une URL spécifique. En naviguant vers `http://<external-IP>:10255/pods`, l'attaquant peut potentiellement récupérer des informations sensibles du kubelet :

![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)

## Références

{{#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}}
