Vulnérabilité racine dans le noyau Linux et déni de service dans systemd

Les chercheurs en sécurité de Qualys ont révélé les détails de deux vulnérabilités affectant le noyau Linux et le gestionnaire système systemd. Une vulnérabilité dans le noyau (CVE-2021-33909) permet à un utilisateur local d'exécuter du code avec les droits root grâce à la manipulation de répertoires hautement imbriqués.

Le danger de la vulnérabilité est aggravé par le fait que les chercheurs ont pu préparer des exploits fonctionnels qui fonctionnent sur Ubuntu 20.04/20.10/21.04, Debian 11 et Fedora 34 dans la configuration par défaut. Il est à noter que d'autres distributions n'ont pas été testées, mais sont théoriquement également sensibles au problème et peuvent être attaquées. Il est promis que le code complet des exploits sera publié une fois le problème éliminé partout, mais pour l'instant, seul un prototype aux fonctionnalités limitées est disponible, provoquant le crash du système. Le problème est présent depuis juillet 2014 et affecte les versions du noyau à partir de la 3.16. Le correctif de vulnérabilité a été coordonné avec la communauté et accepté dans le noyau le 19 juillet. Les principales distributions ont déjà généré des mises à jour de leurs packages noyau (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

La vulnérabilité est due à l'incapacité de vérifier le résultat d'une conversion size_t en int avant d'effectuer des opérations dans le code seq_file, qui crée des fichiers à partir d'une séquence d'enregistrements. L'échec de cette vérification peut entraîner des écritures hors limites dans le tampon lors de la création, du montage et de la suppression d'une structure de répertoires très imbriquée (taille du chemin supérieure à 1 Go). En conséquence, un attaquant peut obtenir une chaîne de 10 octets « // supprimé » écrite avec un décalage de « -2 Go - 10 octets » pointant vers la zone précédant immédiatement le tampon alloué.

L'exploit préparé nécessite 5 Go de mémoire et 1 million d'inodes libres pour fonctionner. L'exploit fonctionne en appelant mkdir() pour créer une hiérarchie d'environ un million de sous-répertoires afin d'obtenir une taille de chemin de fichier supérieure à 1 Go. Ce répertoire est monté via bind-mount dans un espace de noms utilisateur distinct, après quoi la fonction rmdir() est exécutée pour le supprimer. En parallèle, un thread est créé qui charge un petit programme eBPF, qui est bloqué au stade après vérification du pseudocode eBPF, mais avant sa compilation JIT.

Dans l'espace de noms de l'ID utilisateur non privilégié, le fichier /proc/self/mountinfo est ouvert et le long chemin d'accès du répertoire monté en liaison est lu, ce qui entraîne l'écriture de la chaîne "//deleted" dans la zone avant le démarrage du tampon. La position d'écriture de la ligne est choisie pour qu'elle écrase l'instruction du programme eBPF déjà testé mais non encore compilé.

Ensuite, au niveau du programme eBPF, l'écriture hors tampon incontrôlée est transformée en capacité contrôlée de lire et d'écrire sur d'autres structures du noyau grâce à la manipulation des structures btf et map_push_elem. En conséquence, l'exploit détermine l'emplacement du tampon modprobe_path[] dans la mémoire du noyau et écrase le chemin « /sbin/modprobe », ce qui vous permet d'initier le lancement de n'importe quel fichier exécutable avec les droits root en cas de problème. Appel request_module(), qui est exécuté, par exemple, lors de la création d'un socket netlink.

Les chercheurs proposent plusieurs solutions de contournement efficaces uniquement pour un exploit spécifique, mais n’éliminent pas le problème lui-même. Il est recommandé de définir "/proc/sys/kernel/unprivileged_userns_clone" sur 0 pour désactiver les répertoires de montage dans un espace de noms d'ID utilisateur distinct, et "/proc/sys/kernel/unprivileged_bpf_disabled" sur 1 pour désactiver le chargement des programmes eBPF dans le noyau.

Il est à noter qu'en analysant une attaque alternative impliquant l'utilisation du mécanisme FUSE au lieu de bind-mound pour monter un répertoire volumineux, les chercheurs ont découvert une autre vulnérabilité (CVE-2021-33910) affectant le gestionnaire système systemd. Il s'est avéré que lorsque vous essayez de monter un répertoire avec une taille de chemin supérieure à 8 Mo via FUSE, le processus d'initialisation du contrôle (PID1) manque de mémoire de pile et plante, ce qui met le système dans un état de « panique ».

Le problème est que systemd suit et analyse le contenu de /proc/self/mountinfo et traite chaque point de montage dans la fonction unit_name_path_escape(), qui effectue une opération strdupa() qui place les données sur la pile plutôt que dans la mémoire allouée dynamiquement. . Étant donné que la taille maximale de la pile est limitée via RLIMIT_STACK, le traitement d'un chemin trop long vers le point de montage provoque le blocage du processus PID1 et l'arrêt du système. Pour une attaque, vous pouvez utiliser le module FUSE le plus simple en combinaison avec l'utilisation d'un répertoire hautement imbriqué comme point de montage, dont la taille du chemin dépasse 8 Mo.

Le problème apparaît depuis systemd 220 (avril 2015), a déjà été corrigé dans le référentiel principal systemd et corrigé dans les distributions (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Notamment, dans la version 248 de systemd, l'exploit ne fonctionne pas en raison d'un bogue dans le code systemd qui provoque l'échec du traitement de /proc/self/mountinfo. Il est également intéressant de noter qu'en 2018, une situation similaire s'est produite et qu'en essayant d'écrire un exploit pour la vulnérabilité CVE-2018-14634 dans le noyau Linux, les chercheurs de Qualys ont découvert trois vulnérabilités critiques dans systemd.

Source: opennet.ru

Ajouter un commentaire