Sous Kubernetes, le conteneur qui exécute un pod est créé non par Docker mais par containerd ou CRI-O, invoqué par le kubelet via la Container Runtime Interface. Leur surface offensive reflète celle de Docker mais est à l'échelle du nœud : un socket de contrôle accessible est équivalent à root sur le nœud, leurs clients énumèrent chaque conteneur, image et task sur le nœud, et les identifiants qu'ils mettent en cache pour pull les images déverrouillent les registres privés.
Détectez quel runtime un nœud utilise et trouvez son socket :
ls -l /run/containerd/containerd.sock /run/crio/crio.sock /var/run/crio/crio.sock 2>/dev/null
crictl --runtime-endpoint unix:///run/containerd/containerd.sock version 2>/dev/null
ps -ef | grep -E 'containerd|crio' | grep -v grep | head
Sous-sujets#
- Socket containerd : contrôle des conteneurs au niveau du nœud via le socket containerd.
- Socket CRI-O : la même chose via le socket CRI-O.
- Énumération avec crictl et ctr : cartographier le nœud avec les clients de runtime.
- Vol de secret de pull d'image : dérober les identifiants de registre utilisés par le runtime.