
Un script pour vérifier si un environnement de conteneurs est vulnérable aux évasions de conteneurs via CVE-2022-0492
Un script pour vérifier si un environnement conteneurisé est vulnérable aux évasions de conteneurs via CVE-2022-0492
Le 4 février, Linux a annoncé CVE-2022-0492, une nouvelle vulnérabilité d'élévation de privilèges dans le noyau.
CVE-2022-0492 représente un bug logique dans les groupes de contrôle (cgroups), une fonctionnalité Linux qui est un bloc fondamental des conteneurs. Ce problème se distingue comme l'une des élévations de privilèges Linux les plus simples découvertes récemment : le noyau Linux a exposé par erreur une opération privilégiée à des utilisateurs non privilégiés.
Heureusement, les durcissements de sécurité par défaut dans la plupart des environnements conteneurisés suffisent à empêcher l'évasion de conteneur. Les conteneurs exécutés avec AppArmor ou SELinux sont protégés. Cela dit, si vous exécutez des conteneurs sans durcissements conformes aux bonnes pratiques, ou avec des privilèges supplémentaires, vous pouvez être en danger. La section « Suis-je concerné ? » énumère les configurations de conteneurs vulnérables et fournit des instructions pour tester si un environnement conteneurisé est vulnérable.
Outre les conteneurs, la vulnérabilité peut également permettre à des processus hôtes root sans capacités, ou à des processus hôtes non root dotés de la capacité CAP_DAC_OVERRIDE, d'élever leurs privilèges et d'obtenir toutes les capacités. Cela peut permettre aux attaquants de contourner une mesure de durcissement utilisée par certains services, qui abandonnent les capacités afin de limiter l'impact en cas de compromission.
CVE-2022-0492 est désormais la troisième vulnérabilité du noyau ces derniers mois à permettre à des conteneurs malveillants de s'échapper. Dans ces trois vulnérabilités, sécuriser les conteneurs avec Seccomp et soit AppArmor, soit SELinux a suffi à empêcher l'évasion de conteneur.
Le montage d'un cgroupfs nécessite la capacité CAP_SYS_ADMIN dans l'espace de noms utilisateur hébergeant l'espace de noms cgroups actuel. Par défaut, les conteneurs s'exécutent sans CAP_SYS_ADMIM et ne peuvent donc pas monter cgroupfs dans l'espace de noms utilisateur initial. Mais grâce à l'appel système unshare(), les conteneurs peuvent créer de nouveaux espaces de noms utilisateur et cgroups où ils possèdent la capacité CAP_SYS_ADMIN et peuvent monter un cgroupfs.

Fig. 1 - Un conteneur créant un nouvel espace de noms utilisateur où il disposera de la capacité CAP_SYS_ADMIN.
Tous les conteneurs ne peuvent pas créer un nouvel espace de noms utilisateur – l'hôte sous-jacent doit avoir activé les espaces de noms utilisateur non privilégiés. C'est le cas par défaut sur les versions récentes d'Ubuntu, par exemple. Comme Seccomp bloque l'appel système unshare(), seuls les conteneurs fonctionnant sans Seccomp peuvent créer un nouvel espace de noms utilisateur. Le conteneur montré dans la capture d'écran ci-jointe fonctionne sans Seccomp, AppArmor ou SELinux.

Fig. 2 - Le conteneur monte le cgroup mémoire dans les nouveaux espaces de noms utilisateur et cgroups.
Dans la capture d'écran ci-dessus, le conteneur a monté avec succès un cgroup mémoire, mais vous remarquerez peut-être que le fichier release_agent n'est pas inclus dans le répertoire monté !
Comme mentionné précédemment, le fichier release_agent n'est visible que dans le cgroup racine. Une limite du montage d'un cgroupfs dans un espace de noms cgroups est que vous montez le cgroup auquel vous appartenez, et non le cgroup racine.

Fig. 3 - Le conteneur montant le cgroup RDMA racine dans les nouveaux espaces de noms utilisateur et cgroups.
Pour exploiter le problème, nous devons écrire un agent de libération malveillant dans le fichier release_agent. Comme on le voit dans Fig. 3 ci-dessus, ce fichier appartient à root, donc seuls les processus du conteneur root peuvent définir l'agent de libération. Fig. 4 montre le conteneur définissant l'agent de libération, tandis que Fig. 5 montre un conteneur non root échouant à le faire.

Fig. 4 - Un conteneur root définissant l'agent de libération.

Fig. 5 - Un conteneur non root ne peut pas définir l'agent de libération.
La dernière étape de l'évasion consiste à invoquer l'release_agent configuré, ce qui ne nécessite aucun privilège. Comme cette étape est toujours réalisable, elle n'a aucune incidence sur la vulnérabilité d'un environnement à CVE-2022-0492, et nous avons donc décidé de l'omettre. Vous pouvez toujours voir à quoi ressemble une exploitation complète dans la capture d'écran ci-dessous.

Fig. 6 - Exploitation de CVE-2022-0492 pour une évasion de conteneur, via les espaces de noms utilisateur..
Plutôt que de créer de nouveaux espaces de noms utilisateur et cgroups, une exploitation plus simple est possible si le conteneur dispose de la capacité CAP_SYS_ADMIN. Un conteneur exécuté avec la capacité CAP_SYS_ADMIN est autorisé à monter cgroupfs, sans poser de questions. En prime, la plupart des conteneurs actuels s'exécutent sans espaces de noms cgroups, ce qui signifie que le cgroup monté serait le cgroup racine hôte et le fichier release_agent.

Fig. 7 - Dans l'espace de noms cgroups initial, monter cgroupfs montera toujours le cgroup racine, quel que soit le cgroup du conteneur.
Même avec la capacité CAP_SYS_ADMIN, AppArmor et SELinux empêchent toujours le montage, donc les conteneurs fonctionnant avec l'un ou l'autre ne peuvent pas exploiter CVE-2022-0492. Fig. 8 montre un conteneur fonctionnant sans AppArmor et SELinux, et avec la capacité CAP_SYS_ADMIN, exploitant CVE-2022-0492 pour s'échapper.

Fig. 8 - Exploitation de CVE-2022-0492 pour une évasion de conteneur via la capacité CAP_SYS_ADMIN.
CVE-2022-0492 marque une autre vulnérabilité Linux exploitable pour une évasion de conteneur. Heureusement, les environnements qui suivent les bonnes pratiques sont protégés contre cette vulnérabilité. Les environnements dotés de contrôles de sécurité laxistes hébergeant des conteneurs non fiables ou exposés publiquement sont, sans surprise, à haut risque. Comme toujours, il est préférable de mettre à niveau vos hôtes vers une version corrigée du noyau.
Nous recommandons vivement d'exécuter les conteneurs avec Seccomp et soit AppArmor, soit SELinux activés, pour vous protéger contre cette vulnérabilité et contre de futures vulnérabilités zero-day de Linux. De nombreuses vulnérabilités d'élévation de privilèges dans le noyau Linux ne peuvent être exploitées pour une évasion de conteneur que lorsque le conteneur est autorisé à créer un nouvel espace de noms utilisateur, ou en d'autres termes, lorsque le conteneur s'exécute sans Seccomp.
© 2022 - Pas Sofiane Hamlaooui - Rendre le monde meilleur 🌎