Qu'est-ce qu'un cluster : Vulnérabilité liée aux volumes locaux dans Kubernetes
Commentaires éditoriaux et additionnels de Tricia Howard
Synthèse
Tomer Peled, chercheur sur la sécurité d'Akamai, a récemment découvert une vulnérabilité très sévère dans Kubernetes qui a été assignée à la CVE-2023-5528 avec un score CVSS de 7,2.
Cette vulnérabilité permet l'exécution de code à distance avec des privilèges SYSTÈME sur tous les points de terminaison Windows au sein d'un cluster Kubernetes. Pour exploiter cette vulnérabilité, l'attaquant doit appliquer des fichiers YAML malveillants sur le cluster.
Cette vulnérabilité peut conduire à une prise de contrôle totale de tous les points de terminaison Windows d'un cluster.
Cette vulnérabilité peut être exploitée sur les installations par défaut de Kubernetes (antérieures à la version 1.28.4) et a été testée à la fois pour des déploiements sur site et sur Azure Kubernetes Service.
- Dans cet article de blog, nous fournissons un fichier YAML de démonstration ainsi qu'une règle Open Policy Agent (OPA) pour bloquer cette vulnérabilité.
Introduction
Kubernetes et les conteneurs en général sont devenus une force prédominante dans le monde de la sécurité - et, en tant que tels, ils constituent un point d'intérêt pour les chercheurs du monde entier (y compris nous). Notre parcours de recherche nous a d'abord conduits à la CVE-2023-3676 (CVSS de 8,8) : une vulnérabilité d'injection de commande qui pourrait être exploitée en appliquant un fichier YAML malveillant au cluster. Étant donné que le cadre Kubernetes utilise des fichiers YAML pour pratiquement tout, de la configuration de l'interface réseau des conteneurs à la gestion des pods et même à la gestion des secrets, une exploitation de cette vulnérabilité pourrait avoir des conséquences désastreuses.
La découverte de cette vulnérabilité a conduit à la découverte de deux autres qui partagent la même cause fondamentale : un appel de fonction non sécurisé et l'absence de sécurisation des saisies utilisateur.
L'absence de sécurisation du paramètre subPath des fichiers YAML qui crée des pods avec des volumes ouvre la voie à une injection malveillante. Il s'agissait de la découverte initiale, mais à la fin de cette recherche, nous avons remarqué un endroit potentiel dans le code qui semblait pouvoir conduire à une autre vulnérabilité d'injection de commande. Après plusieurs tentatives, nous sommes parvenus à un résultat similaire : l'exécution de commandes en tant que service « Kubelet » (privilèges SYSTÈME). C'est là que nous allons entamer aujourd'hui notre étude de la CVE-2023-5528.
Dans cet article de blog, nous allons passer en revue les détails de la vulnérabilité et les failles qui la permettent dans le code source de Kubernetes, ainsi qu'analyser le correctif de l'équipe Kubernetes et son efficacité. Bien qu'il soit recommandé d'appliquer les correctifs le plus rapidement possible, nous avons inclus de courts guides sur la façon de rechercher les nœuds affectés et d'appliquer une règle Open Policy Agent (OPA) pour faciliter la détection et le blocage de ce type de comportement.
Cet article souligne une fois de plus à quel point il est crucial de vérifier les YAML de configuration de Kubernetes, car la sécurisation des saisies fait défaut dans plusieurs zones de code de Kubernetes lui-même et de ses projets annexes (comme Ingress, par exemple).
Informations sur cette vulnérabilité
Avant d'aborder les spécificités de cette vulnérabilité, nous devons d'abord comprendre quelques composants clés de Kubernetes.
En quoi consistent les volumes Kubernetes ?
Les volumes Kubernetes sont une fonctionnalité visant à prendre en charge le partage de données entre les pods, ou à les stocker de manière persistante en dehors du cycle de vie d'un pod. Les développeurs peuvent utiliser de nombreux types de volumes différents. Par exemple, dans notre recherche précédente sur CVE-2023-3676, nous avons utilisé des volumes hostPath . Pour cette vulnérabilité, nous nous concentrons sur les volumes locaux, un autre type de volume dans Kubernetes. Ces volumes locaux sont conçus pour permettre aux utilisateurs de monter des partitions de disque à l'intérieur d'un pod, tandis que les volumes hostPath sont conçus pour permettre aux utilisateurs de monter des répertoires à partir de leur nœud (hôte) dans un pod.
Lors de la création d'un pod qui inclut un volume local, le service kubelet atteindra (éventuellement) la fonction « MountSensitive() ». Dans celle-ci, un appel à la ligne de commande « exec.command » établit un lien symbolique entre l'emplacement du volume sur le nœud et l'emplacement à l'intérieur du pod (Figure 1).
De nombreux terminaux utilisent une version de la concaténation de commandes (Figure 2) dans leurs opérations pour des raisons de simplicité d'utilisation. C'est aussi le cas pour l'invite de commande Windows (cmd). En utilisant le jeton « && », le terminal exécutera deux commandes ou plus l'une après l'autre.
C:\Users\user>echo "by using &&" && echo "we can execute multiple commands in the same command line"
"by using &&"
"we can execute multiple commands in the same command line"
C:\Users\user>
Figure 2 : Concaténation de commande dans cmd
Le fait de pouvoir contrôler l'un des paramètres de l'exécution cmd signifie que nous pouvons utiliser l'injection de commande. Cependant, il existe des conditions préalables : pour que les utilisateurs puissent utiliser des volumes locaux, ils doivent spécifier ou créer un persistentVolume.
En quoi consistent les persistentVolumes ?
Les persistentVolumes sont des ressources de stockage qu'un administrateur de cluster peut créer pour provisionner à l'avance un espace de stockage qui durera au-delà de la durée de vie du pod (Figure 3). Une fois un persistentVolume créé, un utilisateur peut demander de l'espace de stockage à l'aide d'une persistentVolumeClaim.
C'est là que l'injection peut être placée. Un attaquant peut modifier la valeur du paramètre « local.path » dans le fichier YAML persistentVolume pour ajouter une commande malveillante qui sera exécutée pendant le processus de montage.
Dans la figure 4, nous avons utilisé la commande bénigne « &calc.exe&& » (qui ouvre une calculatrice sur le nœud), mais ce processus peut être utilisé à des fins bien plus malveillantes.
La Figure 5 illustre une exploitation réussie sur un nœud cible après l'injection de notre commande « malveillante » de calculatrice.
Analyse des correctifs
Afin d'éliminer les possibilités d'injection, l'équipe Kubernetes a choisi de supprimer l'appel cmd et de le remplacer par une fonction GO native qui effectuera la même opération « Os.symlink() »(Figure 6).
Désormais, la bibliothèque GO « os » n'effectuera plus qu'une opération de lien symbolique, comme prévu initialement.
Suis-je vulnérable ?
Pour que les utilisateurs soient affectés par cette vulnérabilité, la version de Kubernetes doit être antérieure à 1.28.4. Si vous n'avez pas encore apporté de correctif, il est préférable de le faire en priorité. Ceci est particulièrement vrai pour les organisations ayant des nœuds Windows au sein d'un cluster, car c'est là que se trouve la vulnérabilité.
Heureusement, cela ne semble pas être la norme du secteur. Un administrateur peut facilement tester si le cluster de votre organisation contient des nœuds Windows en exécutant la commande indiquée dans la Figure 7 sur le contrôleur de cluster.
root@controller:~/$ kubectl get nodes -o wide --show-labels | grep “os=windows”
akswin000000 Ready agent 4d17h v1.26.6 agentpool=win,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows…
akswin000001 Ready agent 4d17h v1.26.6 agentpool=win,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows…
root@controller:~/$
Figure 7 : Commande qui affiche les nœuds Windows dans un cluster
Il est facile de déterminer si vous êtes vulnérable. Observez la partie « os=windows ». S'il n'y a pas de nœuds Windows, la commande ne donne aucun résultat, ce qui signifie que vous n'êtes pas vulnérable.
Atténuation
La seule mesure d'atténuation possible consiste à mettre à jour Kubernetes vers une version postérieure à la version 1.28.3.
Cela dit, nous savons que l'application immédiate de correctifs n'est pas possible dans certaines organisations et réseaux. Pour atténuer le risque lié à l'absence de correctifs, nous avons mis en place une règle OPA qui permet de détecter et de bloquer ce type de comportement.
package kubernetes.admission
deny[msg] {
input.request.kind.kind == "PersistentVolume"
path := input.request.object.spec.local.path
contains(path, "&")
msg := sprintf("malicious path: %v was found", [path])
}
OPA est un agent open source qui permet aux utilisateurs de recevoir des données sur le trafic entrant et sortant des nœuds, et d'effectuer des actions basées sur des règles sur les données reçues.
Gardez à l'esprit que cette vulnérabilité affecte uniquement les nœuds Windows. Si votre cluster Kubernetes ne possède pas de nœuds Windows, inutile de vous précipiter pour corriger cette vulnérabilité spécifique. Mais il est important de la corriger quand même lorsque vous en avez le temps.
Comme le problème réside dans le code source, cette menace restera active et son exploitation augmentera probablement. C'est pourquoi nous conseillons fortement d'appliquer un correctif à votre cluster même s'il ne comporte pas de nœuds Windows.
Conclusion
Cette vulnérabilité est un excellent exemple de la raison pour laquelle le modèle de responsabilité partagée est crucial en matière de sécurité. En étant conscient du manque de sécurisation des saisies dans le code source de Kubernetes, vous pouvez prendre des précautions extérieures afin d'éviter un impact majeur sur votre sécurité.
Sept vulnérabilités différentes d'injection de commande ont été découvertes rien qu'en 2023, avec d'autres opportunités dans d'autres parties du code. Les équipes bleues et leurs organisations devraient être plus attentives à cette tendance croissante et essayer de surveiller le contenu des fichiers YAML car ils peuvent contenir des menaces cachées. La règle OPA que nous avons fournie dans cet article peut contribuer à cet effort.
Le groupe SIG (Security Intelligence Group) d'Akamai continuera de surveiller cette menace et d'autres menaces similaires et publiera ses conclusions. Pour suivre les dernières informations sur cette vulnérabilité et découvrir nos prochains articles de recherche sur la sécurité, suivez-nous sur X (anciennement Twitter).
Nous tenons à remercier l'équipe Kubernetes pour sa réponse rapide et sa communication fluide.
Calendrier de divulgation
01/11/2023 — Vulnérabilité révélée à l'équipe Kubernetes
11/11/2023 — CVE attribuées par l'équipe Kubernetes
14/11/2023 — Correctifs CVE publiés par Kubernetes
13/03/2024 — Publication de cet article de blog Akamai