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

Des chercheurs en sécurité de l'entreprise Qualys ont révélé des détails sur deux vulnérabilités affectant le noyau Linux et le gestionnaire de système systemd. La vulnérabilité dans le noyau (CVE-2021-33909) permet à un utilisateur local d'exécuter du code avec des droits root en manipulant des répertoires avec une grande profondeur.

La gravité de la vulnérabilité est aggravée 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 en configuration par défaut. D'autres distributions n'ont pas été vérifiées, mais théoriquement, elles pourraient aussi être sujettes au problème et peuvent être attaquées. Le code complet des exploits sera publié après la correction généralisée du problème, et pour l'instant, seul un prototype limité en fonctionnalités, provoquant un crash du système, est disponible. Le problème est présent depuis juillet 2014 et affecte les versions du noyau à partir de 3.16. Le correctif de la vulnérabilité a été coordonné avec la communauté et intégré au noyau le 19 juillet. Les principales distributions ont déjà préparé des mises à jour de paquets avec le noyau (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

La vulnérabilité est causée par l'absence de vérification du résultat de la conversion de type size_t en int avant l'exécution d'opérations dans le code seq_file, qui crée des fichiers à partir d'une séquence d'enregistrements. L'absence de vérification peut entraîner l'écriture en dehors des limites du tampon lors de la création, du montage et de la suppression d'une structure de répertoires avec un très grand niveau d'imbrication (taille du chemin supérieure à 1 Go). En conséquence, un attaquant peut provoquer l'écriture d'une chaîne de 10 octets «//deleted» avec un décalage de «-2 Go - 10 octets», indiquant une zone juste avant le tampon alloué.

L'exploit préparé nécessite 5 Go de mémoire et 1 million d'inodes libres. Le fonctionnement de l'exploit consiste à créer, via l'appel mkdir(), une hiérarchie d'environ un million de répertoires imbriqués pour atteindre une taille du chemin de fichier dépassant 1 Go. Ce répertoire est monté via un bind-mount dans un espace de noms d'identifiants d'utilisateurs (user namespace), après quoi la fonction rmdir() est appelée pour le supprimer. Parallèlement, un thread est créé pour charger un petit programme eBPF, qui se bloque à l'étape après la vérification du pseudo-code eBPF, mais avant sa compilation JIT.

Dans l'espace de noms non privilégié des identifiants d'utilisateurs, le fichier /proc/self/mountinfo est ouvert et le long chemin du répertoire monté via bind-mount est lu, ce qui entraîne l'écriture de la chaîne «//deleted» dans la zone avant le début du tampon. La position pour écrire la chaîne est choisie de manière à écraser une instruction dans un programme eBPF déjà vérifié, mais pas encore compilé.

Ensuite, au niveau du programme eBPF, l'écriture non contrôlée en dehors du tampon se transforme en une possibilité contrôlée de lecture et d'écriture dans d'autres structures du noyau par 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 y écrase le chemin «/sbin/modprobe», ce qui permet d'initier l'exécution de tout fichier exécutable avec les droits root en cas d'appel à request_module(), qui est exécuté, par exemple, lors de la création d'un socket netlink.

Les chercheurs proposent plusieurs méthodes de protection alternatives, qui sont efficaces uniquement pour un exploit spécifique, mais ne résolvent pas le problème fondamental. Il est recommandé de définir le paramètre «/proc/sys/kernel/unprivileged_userns_clone» à 0 pour interdire le montage de répertoires dans un espace de noms distinct d'identifiants d'utilisateurs, ainsi que «/proc/sys/kernel/unprivileged_bpf_disabled» à 1 pour interdire le chargement de programmes eBPF dans le noyau.

Il est intéressant de noter qu'en examinant une alternative à l'attaque, liée à l'utilisation du mécanisme FUSE plutôt que du bind-mount pour monter un grand répertoire, les chercheurs ont découvert une autre vulnérabilité (CVE-2021-33910) affectant le gestionnaire système systemd. Il s'est avéré que lors de la tentative de montage via FUSE d'un répertoire avec une longueur de chemin dépassant 8 Mo, le processus d'initialisation (PID1) subit une exhaustion de la mémoire de la pile et un crash qui met le système dans un état de «panic».

Le problème est lié au fait que systemd surveille et analyse le contenu de /proc/self/mountinfo, et traite chaque point de montage dans la fonction unit_name_path_escape(), où l'opération strdupa() est exécutée, plaçant les données sur la pile, et non dans une mémoire allouée dynamiquement. Étant donné que la taille maximale de la pile est limitée par RLIMIT_STACK, le traitement d'un chemin de point de montage trop long entraîne l'arrêt du processus PID1 et l'arrêt du système. Une attaque peut être réalisée en utilisant un module FUSE simple associé à un répertoire ayant un niveau d'imbrication élevé, où la taille du chemin dépasse 8 Mo.

Le problème se manifeste à partir de systemd 220 (avril 2015), a déjà été corrigé dans le dépôt principal de systemd et corrigé dans les distributions (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Il est intéressant de noter que dans la version systemd 248, l'exploit ne fonctionne pas à cause d'une erreur dans le code de systemd, entraînant un échec lors du traitement de /proc/self/mountinfo. De plus, en 2018, une situation similaire a eu lieu et lors de la tentative d'écriture d'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

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster