PwnKit : une grave vulnérabilité nichée dans toutes les distributions Linux depuis 12 ans

Par:
fredericmazue

mer, 26/01/2022 - 13:28

L'équipe de recherche Qualys a découvert une vulnérabilité de corruption de mémoire dans l'application pkexec de polkit.

Polkit, anciennement PolicyKit, est une boîte à outils au niveau de l'application pour définir et gérer la politique qui permet aux processus non privilégiés de parler aux processus privilégiés, afin d'accorder à un utilisateur le droit d'effectuer certaines tâches dans certaines situations. Polkit est parfois surnommé "le sudo de systemd".

Les applications graphiques, à savoir les bureaux Linux, utilisent couramment Polkit pour des opérations telles que permettre à l'utilisateur d'éteindre la machine ou la mettre en veille, de gérer les connexions sans fil, de monter/éjecter un support amovible (CD/DVD, clés USB...), d'accéder aux périphériques, comme l'audio, le scanner, etc.

La vulnérabilité, nichée dans l'exécutable pkexec, est présente dans toutes les versions, depuis la première version sortie en 2009, et permet une escalade de privilèges pouvant aboutir à la prise de contrôle du système attaqué.

Qualys n'a pas publié de preuve de concept d'exploit de la vulnérabilité, mais la vidéo ci-dessous montre que la vidéo est exploitable.

Elle est même très facilement exploitable. Le code de la fonction main de pkexec semble avoir été écrit par un débutant ou un codeur très distrait pour le moins... Le code effectue un mauvais traitement des arguments de la ligne de commande reçus par pkexec. Du très classique en langage C.

Comme un billet de blog de Qualys l'explique, dans code ci-dessous

435 main (int argc, char *argv[])
436 {
...
534   for (n = 1; n < (guint) argc; n++)
535     {
...
568     }
...
610   path = g_strdup (argv[n]);
...
629   if (path[0] != '/')
630     {
...
632       s = g_find_program_in_path (path);
...
639       argv[n] = path = s;
640     }

si le nombre d'arguments de ligne de commande argc est 0 - ce qui signifie si la liste d'arguments argv qui est passée à execve() est vide, alors argv[0] est NULL. C'est le terminateur de la liste d'arguments. Donc:

  •  à la ligne 534, l'entier n est fixé en permanence à 1 ;
  •  à la ligne 610, le chemin du pointeur est lu hors limites à partir de argv[1] ;
  •  à la ligne 639, le pointeur s est écrit hors limites vers argv[1].

Les exploits de cette vulnérabilité ne vont donc pas tarder à fleurir. C'est pourquoi les administrateurs doivent appliquer sans tarder les correctifs qui sont fort heureusement disponibles, au moins pour les grandes distributions.

Si aucun correctif n'est disponible pour votre système, vous pouvez supprimer le bit SUID de pkexec à titre de solution temporaire, ce qui bien sur cassera les fonctionnalités des environnements graphiques, mentionnées plus ci-dessus.