
Analyse technique et exploit de preuve de concept pour CVE-2021-1732, une vulnérabilité d'élévation de privilèges du noyau Windows dans win32kfull, démontrant l'exploitation via la manipulation de tagWND.
win32kfull!NtUserCreateWindowEx du pilote graphique Windows, à cause d'une désynchronisation entre l'allocation mémoire par rappel en mode utilisateur et la définition de l'attribut tagWND->flag. Cela permet de falsifier la valeur tagWND->offset, provoquant un dépassement mémoire.win32kfull.sys appelle NtUserCreateWindowEx pour créer une fenêtre, il vérifie tagWND->cbWndExtra (mémoire supplémentaire allouée à l'instance de fenêtre). Si cette valeur n'est pas nulle, il appelle la fonction win32kfull!xxxClientAllocWindowClassExtraBytes pour rappeler user32.dll!__xxxClientAllocWindowClassExtraBytes en mode utilisateur afin d'allouer de l'espace. L'adresse allouée est corrigée sur la pile via NtCallbackReturn, puis retournée en mode noyau où elle est enregistrée et le programme continue. Cependant, lorsque l'attribut tagWND->flag contient la valeur 0x800, cette valeur enregistrée devient un offset.user32.dll!_xxxClientAllocWindowClassExtraBytes et appeler NtUserConsoleControl pour modifier l'attribut tagWND->flag afin d'inclure la valeur 0x800, puis utiliser NtCallbackReturn pour retourner une valeur personnalisée dans tagWND->offset au niveau du noyau.win32kfull!NtUserCreateWindowEx du pilote graphique Windows.win32kfull.sys appelle NtUserCreateWindowEx pour créer une fenêtre, il vérifie tagWND->cbWndExtra (mémoire supplémentaire allouée à l'instance de fenêtre). Si cette valeur n'est pas nulle, il appelle win32kfull!xxxClientAllocWindowClassExtraBytes pour rappeler user32.dll!__xxxClientAllocWindowClassExtraBytes en mode utilisateur afin de créer la mémoire. L'adresse allouée est corrigée sur la pile via NtCallbackReturn, puis retournée en mode noyau où elle est enregistrée et le programme continue. Cependant, lorsque l'attribut tagWND->flag contient la valeur 0x800, cette valeur est traitée comme un offset.NtUserConsoleControl pour modifier le flag afin d'inclure la valeur 0x800.17763:[[gpKernelHandleTable] + 0x18 * ((hwnd->cx * [gSharedInfo+0x10]) >> 5)]
Il est mentionné que l'appel à NtUserConsoleControl réinitialise les valeurs tagWND->offset et tagWND->flag incluant l'attribut 0x800. Lorsque flag contient 0x800, l'adressage se fait par offset. Notre objectif en appelant NtUserConsoleControl est de modifier tagWND->flag pour inclure la valeur 0x800, puis d'appeler NtCallbackReturn pour retourner une valeur spécifique, ce qui permet de modifier tagWND->offset, car win32kfull!xxxClientAllocWindowClassExtraBytes place la valeur de retour dans tagWND->offset.
+0x058 KernelCallbackTable : 0x00007ffb0e9d1070 Void
00007ffb0e9d1448`