Aller au-delĂ  du pod dans Kubernetes grĂące aux journaux de montage

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:

Source: https://habr.com/ru/post/fr466625/


All Articles