Skip to content
KitploitKITPLOIT
OutilsBlog
Log in
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/pravin761/cve-2026-54107
Analyse StatiqueAnalyse des VulnérabilitésExploitationRétro-ingénierieDébogueursArticles et RechercheApprentissage et ÉducationExploitation de Binaires
GitHubpravin761/cve-2026-54107

CVE-2026-54107

Analyse des causes profondes de la CVE-2026-54107 : une use-after-free dans win32kfull.sys de Windows avec débogage de conditions de course, analyse statique, informations sur le triage MSRC et recherche pratique sur l'exploitation du noyau.

112il y a 2 moisPas encore vérifié
Voir le dépôt

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Quand ValidateHwnd n'est pas une barrière : analyse racine de CVE-2026-54107

Un use-after-free dans la gestion du cycle de vie des fenêtres de win32kfull.sys — comment je l'ai trouvé, comment je me suis convaincu qu'il était réel, et à quoi ressemblait vraiment le processus MSRC vu du côté du chercheur.

CVE-2026-54107 CWE-362 CVSS 8.8 MSRC 11xxxxx Bounty $8,000

Il était presque 2 h du matin quand la VM cible a cessé de répondre au heartbeat du débogueur et s'est arrêtée sur un break à exactement l'instruction dont j'avais passé des semaines à soutenir qu'elle était atteignable. Pas une assertion, pas un arrêt sur pool corrompu — une simple violation d'accès sur le chemin de dispatch des messages, déréférençant un objet qu'un autre thread avait déjà démonté.

Ce break est devenu CVE-2026-54107, cas MSRC 11xxxxx, corrigé dans la mise à jour de sécurité de juillet 2026 sur 27 produits Windows.

Ce billet est la moitié non soumise à embargo de l'histoire : cause racine, pourquoi cette classe de bug est ce qu'elle est, et le raisonnement qui m'y a mené. Les détails d'exploitation restent hors champ.

Table des matières

  • 1. Pourquoi win32k, et pourquoi spécifiquement les objets fenêtres
  • 2. L'indice qui m'a fait m'arrêter
  • 3. Cause racine
  • 4. Pourquoi le score d'impact est ce qu'il est
  • 5. La réfutation d'abord — la plupart des candidats sont morts
  • 6. Vérification : le statique donne des hypothèses, le débogueur donne la vérité
  • 7. De l'usage de l'IA dans la recherche noyau
  • 8. La chronologie MSRC, honnêtement
  • 9. Récapitulatif
  • 10. Ce que je dirais à quelqu'un qui commence
  • 11. Et ensuite

1. Pourquoi win32k, et pourquoi spécifiquement les objets fenêtres

Win32k est la moitié en mode noyau du sous-système graphique de Windows. C'est ancien, c'est énorme, et — point crucial — c'est atteignable depuis des contextes censés être non fiables. Cette dernière propriété explique pourquoi cela reste une cible de recherche permanente malgré vingt ans de durcissement, de filtrage et de restrictions sur les appels système.

Dans win32k, l'objet tagWND (PWND) est particulièrement intéressant parce que sa durée de vie est gérée par plusieurs mécanismes à la fois. Une fenêtre est :

  • référencée par handle, via la table des handles utilisateur et les recherches de type ValidateHwnd,
  • référencée par pointeur, conservée à travers des appels imbriqués et le dispatch des messages,
  • référencée implicitement par les relations parent/enfant, propriétaire/appartenu et thread/bureau,
  • et démontée via un chemin de destruction qui doit dérouler tout ce qui précède dans le bon ordre.

Tout objet avec plusieurs chemins de référence indépendants et un chemin de destruction partagé mérite d'être lu lentement. Ce n'est pas une affirmation de vulnérabilité — c'est une heuristique pour savoir où passer du temps.

2. L'indice qui m'a fait m'arrêter

Ce qui m'a fait m'attarder sur ce composant, c'est la surface d'imports. win32kfull.sys tire de ntoskrnl trois primitives distinctes de référencement d'objets :```c NTSTATUS ObReferenceObjectByPointer( void *Object, uint32_t DesiredAccess, POBJECT_TYPE ObjectType, char AccessMode);

NTSTATUS ObReferenceObjectByHandle( HANDLE Handle, uint32_t DesiredAccess, POBJECT_TYPE ObjectType, char AccessMode, void **Object, OBJECT_HANDLE_INFORMATION *HandleInformation);

NTSTATUS ObReferenceObjectByName(/* ... */);

Trois façons d'entrer, une seule sortie via `ObfDereferenceObject`.

Cela ne signifie pas que le code est incorrect. Cela signifie que l'**invariant est distribué** — aucune fonction ne possède à elle seule *"cet objet est vivant en ce moment"*, donc l'exactitude dépend de l'accord de chaque appelant sur la référence qu'il détient et sa durée de validité. Les invariants distribués sont là où vivent les conditions de course, car une course n'est jamais un bug de logique visible dans une seule fonction. C'est un bug dans une hypothèse partagée entre deux fonctions.

Aussi, la question que j'ai commencé à poser à chaque fonction qui touchait un `PWND` n'était pas *"ce code est-il correct ?"* mais :

> **Si ce corps de fonction exact s'exécute sur deux threads à quelques instructions d'écart, lequel des deux est dans l'erreur ?**

## 3. Cause racine

Le défaut est un **écart entre le temps de vérification et le temps d'utilisation entre la libération de la référence et le démontage de l'objet** dans le chemin de destruction de la fenêtre, sans synchronisation adéquate face à un consommateur concurrent qui valide les handles.

Réduit à l'essentiel :```c
/* Thread A — teardown */
NtUserDestroyWindow(HWND hwnd)
{
    PWND pWnd = ValidateHwnd(hwnd);
    if (pWnd) {
        ObfDereferenceObject(pWnd);   /* reference released */

        /* <-- race window: object may become reclaimable here */

        FreeWindowObject(pWnd);       /* teardown proceeds on a pointer
                                         no longer guaranteed live      */
    }
}

I don't see any content to translate. The input appears to be empty after the INPUT: marker. Please provide the chunk text you'd like me to translate.```c /* Thread B — consumer, concurrent / NtUserMessageCall(HWND hwnd, UINT msg, ...) { PWND pWnd = ValidateHwnd(hwnd); / may resolve a handle whose object is mid-teardown */

if (pWnd->fnid == FNID_BUTTON)    /* use-after-free */
    ...

}

Deux conditions doivent être réunies pour que cela ait de l'importance, et les deux l'étaient :

**(a) La fenêtre est réelle.** `ValidateHwnd` est le garde-fou censé rendre l'accès basé sur les handles sûr. Si la validation peut réussir sur un objet dont la destruction a déjà commencé, le garde-fou n'est pas un garde-fou — c'est une suggestion.

**(b) La mémoire libérée est influençable par l'attaquant.** Les champs lus immédiatement après la validation incluent `fnid`, qui pilote la répartition des messages. Une décision de répartition prise à partir de mémoire récupérée fait la différence entre *« crash peu fiable »* et *« violation de frontière de sécurité »*. Cette distinction est la raison même pour laquelle il s'agit d'une CWE-362 avec impact EoP et non d'un bug de stabilité.

> La **corruption** observée est une use-after-free ; la **cause** est une CWE-362, exécution concurrente utilisant une ressource partagée avec une synchronisation inappropriée. Ce sont deux affirmations différentes et MSRC s'intéresse à la seconde. **Signalez la cause, pas seulement le symptôme.**

### Pourquoi les courses win32k sont structurellement plus dures qu'elles n'en ont l'air

Si vous avez traqué des bugs de course dans d'autres sous-systèmes, win32k vous frustrera, car l'architecture vous combat de trois manières spécifiques.
Télécharger l’outil