Remarque perev. : Cette note a été rédigée par un chercheur en sécurité informatique chez Aqua Security, une société DevSecOps. Elle est une excellente illustration des subtilités de la configuration de Kubernetes, qu'il est important de toujours garder à l'esprit lorsque vous servez des clusters en production. Bien sûr, si vous pensez à leur sécurité ...
Kubernetes se compose de nombreux composants, et parfois leur combinaison d'une certaine maniÚre conduit à des résultats inattendus. Dans cet article, je montrerai comment un pod lancé avec des privilÚges root et un répertoire
/var/log
montĂ© d'un nĆud peut
étendre le contenu de l'ensemble du systÚme de fichiers hÎte à un utilisateur ayant accÚs à ses journaux. Nous discuterons également des solutions à ce problÚme.
Comment Kubernetes voit les journaux
Vous ĂȘtes-vous dĂ©jĂ demandĂ© comment
kubectl logs <pod_name>
extrait les journaux du pod? Qui est responsable de la collecte des grumes dans les conteneurs? Et comment arrivent-ils sur votre ordinateur?
Le diagramme suivant illustre le processus:

Kubelet crée une structure à l'intérieur du répertoire
/var/log
sur l'hÎte qui représente les pods sur l'hÎte. Il y a un fichier
0.log
(1) dans le répertoire de notre
0.log
, mais en fait c'est un lien symbolique vers le journal du conteneur situé dans
/var/lib/docker/containers
. Tout cela du point de vue de l'hĂŽte.
Kubelet ouvre le noeud final
/logs/
(2), qui fonctionne simplement avec le serveur de fichiers HTTP dans le répertoire (3), rendant les journaux disponibles pour les demandes provenant du serveur API.
Imaginez maintenant que nous avons déployé pod avec
hostPath
monté dans
/var/log
. Un tel pod aura accÚs à tous les fichiers journaux de l'hÎte. Bien que cela soit en soi un problÚme potentiel, nous pouvons franchir la prochaine étape logique. Et si nous remplaçons
0.log
par un lien symbolique pour ... par exemple,
/etc/shadow
?
â âââ var â âââ logs â â âââ pods â â â âââ default_mypod_e7869b14-abca-11e8-9888-42010a8e020e â â â â âââ mypod â â â â â âââ 0.log -> /etc/shadow â â â â â â
Maintenant, en essayant de télécharger les journaux à l'aide des journaux
kubectl logs
sur la machine cliente, nous obtenons:
$ kubectl logs mypod failed to get parse function: unsupported log format: "root:*:18033:0:99999:7:::\n"
Kubelet suit le lien et lit le contenu du fichier vers lequel il pointe (il peut s'agir de n'importe quel fichier sur le nĆud).
Comme JSON était attendu, kubectl s'est écrasé aprÚs la premiÚre ligne, cependant, nous pouvons facilement lire les lignes spécifiques du fichier
shadow
en exécutant la commande avec l'
â-tail=-<line_number>
.
C'est incroyable. Puisque kubelet suit le lien symbolique, vous pouvez utiliser ses privilĂšges root pour lire n'importe quel fichier sur le nĆud, simplement en crĂ©ant un lien symbolique Ă l'intĂ©rieur du pod.
Ăchapper au pod
Allons encore plus loin. Nous savons que lors du dĂ©marrage d'un pod dans Kubernetes, le jeton ServiceAccount y est installĂ©. Ainsi, si le compte de service permet d'accĂ©der aux journaux, nous pouvons accĂ©der directement aux privilĂšges kubelet et root sur le nĆud.
J'ai écrit une preuve de concept (POC) démontrant ce vecteur d'attaque:
- déploiement de pod avec point de montage
/var/log
; - créer un lien symbolique vers le répertoire racine de l'hÎte;
- lecture de la clé privée ssh de l'utilisateur sur l'hÎte.
La
vidéo suivante montre deux commandes spéciales qui s'exécutent à l'intérieur d'un pod:
lsh == ls
(sur le systĂšme de fichiers hĂŽte);cath == cat
(sur le systĂšme de fichiers hĂŽte).
Remarque perev. : Malheureusement, ils n'ont pas corrigĂ© l'insertion de contenu d'asciinema sur le hub, bien que nous ayons dĂ©jĂ rĂ©solu ce problĂšme, nous sommes donc obligĂ©s «d'intĂ©grer» la vidĂ©o avec le lien simple ci-dessus.Tous les fichiers impliquĂ©s dans ce POC peuvent ĂȘtre trouvĂ©s dans le
référentiel GitHub correspondant . Il existe un autre script POC qui collecte automatiquement les clés privées et les jetons ServiceAccount du systÚme de fichiers hÎte.
Le montage de rĂ©pertoires peut ĂȘtre dangereux
Est-ce donc une vulnérabilité ou une mauvaise pratique?
Le déploiement d'un pod avec un
hostPath
ouvert en écriture dans
/var/log
est rare (en outre, il existe d'autres façons d'abuser du montage de rĂ©pertoires secrets d'hĂŽte dans le pod). Mais mĂȘme si vous saviez que le montage
/var/log
Ă©tait une pratique douteuse, vous ne vous attendiez probablement pas Ă ce qu'il vous permette de reprendre le nĆud avec une telle facilitĂ©.
Avant la publication, nous avons contacté l'équipe de sécurité de Kubernetes pour savoir si elle considérait cela comme une vulnérabilité. Ils ont conclu que ce n'était qu'une triste conséquence de la création d'un répertoire hÎte privé avec des autorisations d'écriture: les risques impliqués sont bien
documentés . Cependant, cette vulnérabilité est assez facile à exploiter. Dans le monde, de
nombreux projets utilisent cette monture. Si vous utilisez l'un de ces projets, n'oubliez pas que votre déploiement sera vulnérable à cette façon de détourner l'hÎte.
Cette méthode a été testée sur Kubernetes 1.15 et 1.13, mais affecte trÚs probablement d'autres versions.
Ălimination
Une telle «fuite» n'est possible que si le pod s'exécute en tant que root. Cela
devrait généralement
ĂȘtre Ă©vitĂ© . Aqua CSP vous permet de dĂ©finir une politique avec un minimum d'efforts qui empĂȘche les conteneurs de s'exĂ©cuter sous la racine ou accorde des autorisations uniquement Ă un groupe spĂ©cifique d'images qui ont vraiment besoin de la racine.
Une autre façon consiste simplement à ne pas déployer de pods avec
hostPath
avec des autorisations d'écriture dans
/var/log
. Cette approche n'est pas définie par défaut et n'est pas une pratique courante, il est donc nécessaire de la déterminer consciemment (cependant, la possibilité demeure). Mais comment vérifier?
Nous avons ajoutĂ© un nouveau script (hunter) Ă
kube-hunter - notre outil Open Source léger pour tester Kubernetes - qui vérifie le cluster pour les pods avec de tels points de montage dangereux.
( Remarque : Kube-hunter Ă©tait prĂ©sent dans une rĂ©cente revue des utilitaires de sĂ©curitĂ© K8, que nous avons publiĂ©e sur notre blog.)Les utilisateurs d'Aqua peuvent se protĂ©ger de ce risque en utilisant la stratĂ©gie d'exĂ©cution pour empĂȘcher le montage de certains volumes:
Remarque perev. : Une partie de ce problĂšme peut ĂȘtre rĂ©solue Ă l'aide des stratĂ©gies de sĂ©curitĂ© des AllowedHostPaths
, Ă savoir AllowedHostPaths
. Cependant, ce n'est pas non plus une protection contre les liens symboliques. Enfin, comme le suggÚrent les commentaires, nous pouvons simplement limiter le lancement en tant que root, là encore guidé par la PSP .Résumé
Kubernetes est un systĂšme complexe avec beaucoup de subtilitĂ©s dans les paramĂštres de sĂ©curitĂ©, qui ne sont pas toujours Ă©vidents pour l'utilisateur moyen et mĂȘme expĂ©rimentĂ©. Dans cet article, j'ai montrĂ© comment, dans certaines circonstances, une journalisation innocente peut entraĂźner une vulnĂ©rabilitĂ© potentielle. Dans la plupart des cas, cela n'est pas possible, mais Kubernetes offre aux utilisateurs une plus grande libertĂ© d'action qui peut affecter la sĂ©curitĂ©. Il est important de garder cela Ă l'esprit et de mettre en Ćuvre des contrĂŽles appropriĂ©s pour Ă©viter de telles erreurs.
PS du traducteur
Lisez aussi dans notre blog: