En juin 2019, des chercheurs d’ESET ont identifié un exploit jour zéro utilisé dans une campagne d’attaque très ciblée en Europe de l'Est.

L'exploit abuse d'une vulnérabilité d'escalade des privilèges locaux dans Microsoft Windows, en particulier une déréférence de pointeur NULL dans le composant win32k.sys. Une fois l'exploit découvert et analysé, il a été signalé au centre de réponse de sécurité de Microsoft, qui a rapidement corrigé la vulnérabilité et publié un correctif.

La vulnérabilité affecte les versions suivantes de Windows :

  • Windows 7 pour système 32-bit Service Pack 1
  • Windows 7 pour système x64 Service Pack 1
  • Windows Server 2008 pour système 32-bit Service Pack 2
  • Windows Server 2008 pour systèmes basés sur Itanium Service Pack 2
  • Windows Server 2008 pour systèmes x64 Service Pack 2
  • Windows Server 2008 R2 pour systèmes basés sur Itanium Service Pack 1
  • Windows Server 2008 R2 pour système x64 Service Pack 1

Cet article se concentre sur les détails techniques de la vulnérabilité et son exploitation. Notre prochain article de blogue, demain, se penchera sur l'échantillon de logiciels malveillants et ses implications plus larges.

Exploitation

Comme avec un certain nombre d'autres vulnérabilités de Microsoft Windows win32k.sys révélées ces dernières années, cet exploit utilise des objets de menu contextuel. Par exemple, l'exploit d'escalade des privilèges locaux du groupe Sednit que nous avons analysé en 2017 a utilisé des objets de menu et des techniques très similaires à l'exploit actuel.

Cet exploit crée deux fenêtres : une pour la première étape et une autre pour la deuxième étape de l'exploitation. Pour la première fenêtre, il crée des objets de menu contextuel et ajoute des éléments de menu en utilisant les fonctions CreatePopupMenu et AppendMenu. En outre, l'exploit configure les crochets (ou « hooks ») WH_CALLWNDPROC et EVENT_SYSTEM_MENUPOPUPSTART.

Ensuite, l'exploit affiche un menu à l'aide de la fonction TrackPopupMenu. C'est à ce moment que le code lié à EVENT_SYSTEM_MENUPOPUPSTART est exécuté. Ce code tente d'ouvrir comme premier élément disponible dans le menu, en envoyant une séquence de messages MN_SELECTITEM, MN_SELECTFIRSTVALIDITEM et MN_OPENHIERARCHY au menu.

La prochaine étape est très importante pour déclencher cette vulnérabilité. L'exploit doit saisir le moment où le menu initial est déjà créé, mais le sous-menu est sur le point d'être créé. Pour cela, l'exploit a du code qui gère le message WM_NCCREATE dans le crochet WH_CALLWNDPROC. Lorsque le code d'exploitation détecte que le système est dans cet état, il envoie le message MN_CANCELMENUS (0x1E6) au premier menu, qui annule ce menu. Cependant, son sous-menu est sur le point d'être créé.

Maintenant, si nous vérifions cet objet de sous-menu en mode noyau, nous verrions que tagPOPUPMENU‑> ppopupmenuRoot égale 0. Cet état permet à l'attaquant d'utiliser cet élément dans cette structure noyau comme une déréférence NULL de pointeur. L'exploit alloue une nouvelle page à l'adresse 0x0 et cette adresse sera traitée comme l’objet tagPOPUPMENU((voir Figure 1) par le noyau.

Figure 1. La structure kernel de tagPOPUPMENU

A ce stade, les attaquants utilisent la deuxième fenêtre. Le but principal de l'exploit est de retourner le bit bServerSideWindowProc dans la structure tagWND de la seconde fenêtre. Ceci provoque l'exécution d'une procédure WndProc en mode noyau.

Pour ce faire, les attaquants fuient l'adresse mémoire du noyau de la structure tagWND de la deuxième fenêtre en appelant la fonction HMValidateHandle non exportée dans la bibliothèque user32.dll. Ensuite, l'exploit crée un faux objet tagPOPUPMENU sur la page NULL et envoie un message MN_BUTTONDOWN à un sous-menu.

Après cela, le noyau exécutera éventuellement la fonction win32k!xxxMNOpenHierarchy.

Figure 2. Disassembled code of the win32k!xxxMNOpenHierarchy function

Cette fonction passe un objet fabriqué à la page NULL pour win32k!HMAssignmentLock. Le bit bServerSideWindowProc est placé à l'intérieur de la fonction win32k!HMDestroyUnlockedObject, qui se trouve quelques appels plus loin dans win32k!HMAssignmentLock.

Figure 3. Code démonté de la fonction win32k!HMDestroyUnlockedObject

Tout est fait! L'exploit peut maintenant envoyer un message spécifique à la seconde fenêtre afin d'exécuter WndProc en mode noyau.

En dernière étape, l'exploit remplace le token du processus en cours par le token du système.

Le correctif publié, entre autres, a ajouté une vérification pour un pointeur NULL dans la fonction win32k!xxxMNOpenHierarchy.

Figure 4. Différences de code entre deux versions de win32k.sys versions – original (gauche) et correctif (droite)

Conclusion

L'exploit ne fonctionne qu'avec les anciennes versions de Windows, car depuis Windows 8, un processus utilisateur n'est plus autorisé à mapper la page NULL. Microsoft a intégré cette atténuation dans Windows 7 pour les systèmes basés sur x64.

Les personnes qui utilisent encore Windows 7 pour les systèmes 32 bits du Service Pack 1 devraient envisager une mise à jour vers de nouveaux systèmes d'exploitation, puisque le support étendu de Windows 7 Service Pack 1 prendra fin au 14 janvier 2020. Ce qui signifie que les utilisateurs de Windows 7 ne recevront pas les mises à jour de sécurité critiques. Ainsi, des vulnérabilités comme celle-ci resteront non corrigées pour toujours.

Indicateurs de compromission (IoCs)

SHA-1 hash ESET detection name
CBC93A9DD769DEE98FFE1F43A4F5CADAF568E321 Win32/Exploit.CVE-2019-1132.A