Encore un nouvel exploit : Injection de commande dans Kubernetes Log Query

Tomer Peled

écrit par

Tomer Peled

January 24, 2025

Tomer Peled

écrit par

Tomer Peled

Tomer Peled est chercheur en sécurité chez Akamai. Dans son travail quotidien, il mène des recherches allant de la recherche sur les vulnérabilités aux systèmes d'exploitation internes. Pendant son temps libre, il aime cuisiner, faire du Krav-maga et jouer sur son PC.

Si vous n'avez pas encore apporté de correctif à cette vulnérabilité, il est préférable de le faire en priorité.
Si vous n'avez pas encore apporté de correctif à cette vulnérabilité, il est préférable de le faire en priorité.

Commentaires éditoriaux et additionnels de Tricia Howard

Synthèse

  • Cette vulnérabilité permet l'exécution de code à distance (RCE) avec des privilèges SYSTÈME sur tous les terminaux Windows au sein d'un cluster Kubernetes. Pour exploiter cette vulnérabilité, le cluster doit être configuré pour exécuter le nouveau mécanisme de journalisation « Log Query ».

  • La vulnérabilité peut être déclenchée par une simple requête GET adressée au nœud distant.

  • Une exploitation réussie de 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 qui ont choisi d'opter pour les fonctionnalités bêta (antérieures à la version 1.32.1) 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 une commande curl de démonstration et évoquons les possibles atténuations.

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 pour nous). Notre parcours de recherche nous a d'abord conduits à CVE-2023-3676 : une vulnérabilité d'injection de commandes qui pourrait être exploitée en appliquant un fichier YAML malveillant au cluster. Cette recherche a mené à la découverte de plusieurs autres problèmes dans le code source de Kubernetes qui permettent également une prise de contrôle complète du cluster.

Ces vulnérabilités n'étaient pas les seules que nous avons trouvées : il y a également eu une découverte significative dans le projet d'extension git-sync. Nous avons présenté ces conclusions au Red Team Village de la DEF CON 32, et en préparation de la conférence, nous sommes tombés sur le sujet de cet article de blog : une autre opportunité pour l'injection de commandes : fonctionnalité bêta de Kubernetes pour un cadre de journalisation plus large Log Query.

Qu'est-ce que Log Query ?

La requête de journal permet aux utilisateurs d'interroger les machines distantes pour connaître l'état de leur système à l'aide de l'interface de ligne de commande ou de cURL. Par exemple, un utilisateur peut taper la commande suivante pour interroger l'état du service Kubelet sur un nœud distant :

  kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet"

Lorsque nous avons vu l'exemple de commande ci-dessus, notre recherche précédente nous est venue à l'esprit : La requête envoyée à la machine distante sera-t-elle validée ?

La Figure 1 est un exemple du code source de Log Query dans lequel nous avons trouvé plusieurs commandes PowerShell en cours de construction.

Ces commandes sont utilisées pour récupérer les journaux d'un nœud donné en fonction d'un certain nombre de paramètres différents, tels que les noms de service Windows, le modèle de temps d'utilisation, etc.

D'après l'expérience précédente (CVE-2023-3676), Kubernetes ne valide pas nécessairement les entrées utilisateur avant de les insérer en tant que paramètre lors de la création d'une commande PowerShell. Nous voulions voir si c'est également le cas avec Log Query et nous avons constaté que les noms de service sont en fait validés à l'aide d'une regex prédéfinie (figure 2).

Le nom reServiceNameUnsafeCharacters suggère que cette vérification concerne uniquement les services. Cette hypothèse est encore renforcée par le fait qu'il n'y a pas d'autre regex présent dans le processus d'analyse.

Après examen d'autres paramètres, il est apparu que, en effet, le seul paramètre validé est le nom du service. Cela signifie que nous pouvons examiner d'autres paramètres dans l'espoir de réaliser une injection de commande. Dans Log Query, les utilisateurs peuvent fournir plusieurs paramètres facultatifs différents, mais le seul paramètre qui est une chaîne est le paramètre Pattern (figure 3). Comme nous l'avons mentionné ci-dessus, il n'y a pas de validation sur le paramètre (hormis sa longueur).

Il est à noter que l'exploitation de cette vulnérabilité n'était pas anodine. Nous avons essayé de déclencher les commandes sur l'ordinateur distant en utilisant plusieurs permutations différentes pour la charge utile PowerShell, par exemple en ajoutant des crochets, en utilisant des séparateurs, etc., mais rien ne semblait fonctionner. Il n'y avait pas non plus d'erreurs, ce qui rendait la compréhension encore plus difficile.

Ce n'est pas la charge utile qui pose un problème

Après avoir essayé de nombreuses méthodes différentes d'injection de commandes, nous avons finalement découvert que le problème ne venait pas de la charge utile elle-même. Pour exploiter cette vulnérabilité, nous devions spécifier un service qui consigne son état nativement dans Event Tracking for Windows (ETW) et non dans le framework klog normal, car la vérification des vulnérabilités existe uniquement lors de la connexion à ETW.

Un environnement Kubernetes utilisant Calico (interface réseau open source populaire pour Kubernetes) fournit un moyen fiable d'exploiter cette vulnérabilité par le biais de non-Sucking Service Manager (NSSM).

  • Dans une configuration Calico, NSSM est généralement présent pour contrôler l'état des services Kubernetes. Dans d'autres environnements/configurations, ils utilisent différentes façons de gérer les états de service.

  • Kubernetes ne gère pas la sortie de journalisation de NSSM, s'assurant que les journaux sont écrits directement dans ETW et non via klog.

Montrez-moi une requête d'exploitation

Voici à quoi ressemblerait une requête d'exploitation :

  curl  "<Kubernetes API Proxy server IP>/api/v1/nodes/<NODE name>/proxy/logs/?query=nssm&pattern=’\$(Start-process cmd)’"

*Le jeton d'authentification requis pour communiquer avec le serveur API est expurgé

Les lecteurs attentifs se sont peut-être posé des questions sur les apostrophes utilisées pour échapper à notre commande malveillante. Nous en avons besoin parce que Kubernetes insère notre entrée en utilisant la commande suivante :

  …Where-Object -Property Message -Match '%s'... 

De la même manière que pour les attaques par injection SQL classiques, nous devons ajouter des apostrophes pour échapper à leur motif afin que notre entrée soit analysée comme une commande séparée (Figure 4).

Correctif prioritaire

Pour que vous soyez affecté par cette vulnérabilité, vous devez utiliser une version de Kubernetes antérieure à la version 1.32.1. Si vous n'avez pas encore apporté de correctif à cette vulnérabilité, il est préférable de le faire en priorité. Cela 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 suivante sur le contrôleur de cluster (figure 5).

Suis-je vulnérable ?

Il est facile de déterminer si vous êtes vulnérable. Remarquez 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.

Comme il s'agit d'une fonctionnalité bêta, le cluster doit également être configuré pour utiliser le framework lui-même.

Pour vérifier si la fonctionnalité est activée, les administrateurs peuvent consulter le paramètre de démarrage « feature-gate » pour « kubelet ». Vous trouverez plus d'informations sur le site Kubernetes.

Analyse des correctifs

Pour corriger cette vulnérabilité, Kubernetes a décidé d'utiliser une variable d'environnement nommée « kubelet_pattern », avant de transmettre la valeur à la commande PowerShell elle-même.

Ainsi, l'entrée utilisateur sera considérée comme une chaîne littérale au lieu d'une sous-expression qui doit être évaluée.

Atténuation

Pour atténuer cette vulnérabilité, les administrateurs peuvent utiliser le module RBAC (contrôle d'accès basé sur les rôles) pour contrôler qui a accès à Log Query et même désactiver entièrement l'accès à ce dernier. Le contrôle d'accès basé sur les rôles (RBAC) est une méthode qui segmente les opérations utilisateur en fonction de l'identité de l'utilisateur. Par exemple, chaque utilisateur ne peut créer des pods que dans son propre espace de noms ou ne peut afficher les informations que pour les espaces de noms autorisés. Cela réduirait le risque de RCE non seulement dans l'exécution mais aussi dans la détection : un comportement anormal de l'utilisateur est souvent un signe révélateur de méfait. 

Gardez à l'esprit que cette vulnérabilité affecte uniquement les nœuds Windows. Si votre cluster Kubernetes n'a pas de nœuds Windows, vous êtes en sécurité. Cependant, il est toujours recommandé de garder vos correctifs aussi à jour que possible pour éviter d'autres vulnérabilités inconnues. 

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

Dans cet article de blog, nous avons montré comment un attaquant avec des privilèges de requête peut exécuter des commandes sur n'importe quel nœud Windows à l'intérieur du cluster. Cette vulnérabilité peut être exploitée par une simple commande curl, au lieu de devoir soumettre un fichier YAML. Ce fait impose un grand risque, car son exploitation est plus difficile à atténuer et à détecter. Comme nous l'avons vu précédemment, les problèmes de nettoyage de Kubernetes ne sont pas propres à Log Query.

Les membres de l'équipe bleue doivent être à l'affût de tout comportement inhabituel au sein de leur organisation. Ce vecteur d'attaque peut mener à une prise de contrôle totale du cluster ; il est donc important pour nous de sensibiliser et d'aider les administrateurs de sécurité à appréhender ce danger potentiel.

Le groupe Security Intelligence d'Akamai continuera à étudier ces menaces et à les signaler auprès de nos clients et de l'ensemble de la communauté de la sécurité. Pour des mises à jour en temps réel sur ce que nous travaillons, suivez-nous sur X (anciennement Twitter.)

Nous tenons à remercier l'équipe Kubernetes pour sa réponse et son discours.

Chronologie

28/06/2024 — Vulnérabilité révélée à l'équipe Kubernetes

18/07/2024 — L'équipe Kubernetes a commencé à travailler pour résoudre le problème

30/07/2024 — CVE attribuées par l'équipe Kubernetes

16/01/2025 — Correctifs CVE publiés par Kubernetes 

24/01/2025 — Article de blog publié



Tomer Peled

écrit par

Tomer Peled

January 24, 2025

Tomer Peled

écrit par

Tomer Peled

Tomer Peled est chercheur en sécurité chez Akamai. Dans son travail quotidien, il mène des recherches allant de la recherche sur les vulnérabilités aux systèmes d'exploitation internes. Pendant son temps libre, il aime cuisiner, faire du Krav-maga et jouer sur son PC.