Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-54107 — Análisis de causa raíz de CVE-2026-54107: un use-after-free en Windows win32kfull.sys con depuración de condiciones de carrera, análisis estático, información de clasificación de MSRC e investigación práctica de explotación del kernel. | Kitploit
Herramientas/GitHubGitHub/pravin761/cve-2026-54107
Análisis EstáticoAnálisis de VulnerabilidadesExplotaciónIngeniería InversaDepuradoresPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHubpravin761/cve-2026-54107

CVE-2026-54107

Análisis de causa raíz de CVE-2026-54107: un use-after-free en Windows win32kfull.sys con depuración de condiciones de carrera, análisis estático, información de clasificación de MSRC e investigación práctica de explotación del kernel.

111hace 2 mesesAún no revisado
Ver Repositorio

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Cuando ValidateHwnd no es una puerta: análisis de la causa raíz de CVE-2026-54107

Un use-after-free en la gestión del ciclo de vida de ventanas de win32kfull.sys — cómo lo encontré, cómo me convencí de que era real, y cómo se ve realmente el proceso de MSRC desde el lado del investigador.

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

Eran casi las 2 de la madrugada cuando la VM objetivo dejó de responder al latido del depurador y se detuvo en un break exactamente en la instrucción que había pasado semanas discutiendo que era alcanzable. No una aserción, no una parada por pool corrupto — una violación de acceso común en la ruta de despacho de mensajes, desreferenciando un objeto que otro hilo ya había derribado.

Ese break se convirtió en CVE-2026-54107, caso MSRC 11xxxxx, parcheado en la Actualización de Seguridad de julio de 2026 en 27 productos de Windows.

Esta publicación es la mitad no sujeta a embargo de la historia: causa raíz, por qué la clase de bug es lo que es, y el razonamiento que me llevó hasta allí. Los detalles de explotación quedan fuera.

Tabla de contenidos

  • 1. Por qué win32k, y por qué los objetos de ventana en particular
  • 2. El olor que me hizo detenerme
  • 3. Causa raíz
  • 4. Por qué la calificación de impacto es la que es
  • 5. La falsación llegó primero — la mayoría de los candidatos murieron
  • 6. Verificación: lo estático da hipótesis, el depurador da la verdad
  • 7. Sobre usar IA en investigación de kernel
  • 8. La cronología de MSRC, honestamente
  • 9. Resumen
  • 10. Lo que le diría a alguien que empieza
  • 11. Lo que viene

1. Por qué win32k, y por qué los objetos de ventana en particular

Win32k es la mitad en modo kernel del subsistema gráfico de Windows. Es antiguo, es enorme y — críticamente — es alcanzable desde contextos que se supone que no son de confianza. Esa última propiedad es la razón por la que sigue siendo un objetivo de investigación permanente a pesar de veinte años de endurecimiento, filtrado y trabajo de restricción de syscalls.

Dentro de win32k, el objeto tagWND (PWND) es inusualmente interesante porque su ciclo de vida se gestiona mediante más de un mecanismo a la vez. Una ventana es:

  • referenciada por manejador (handle), a través de la tabla de manejadores de usuario y búsquedas de estilo ValidateHwnd,
  • referenciada por puntero, mantenida a través de llamadas anidadas y despacho de mensajes,
  • referenciada implícitamente por relaciones padre/hijo, propietario/propiedad y hilo/escritorio,
  • y derribada a través de una ruta de destrucción que tiene que deshacer todo lo anterior en el orden correcto.

Cualquier objeto con varias rutas de referencia independientes y una ruta de destrucción compartida merece ser leído lentamente. Eso no es una afirmación de vulnerabilidad — es una heurística de dónde invertir tiempo.

2. El olor que me hizo detenerme

Lo que me hizo quedarme en este componente fue la superficie de importación. win32kfull.sys incorpora tres primitivas distintas de referencia a objetos desde ntoskrnl:```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(/* ... */);

Tres formas de entrar, una única salida a través de `ObfDereferenceObject`.

Eso no significa que el código sea incorrecto. Significa que el **invariante está distribuido** — ninguna función posee en exclusiva *«este objeto sigue vivo ahora mismo»*, por lo que la corrección depende de que cada llamador se ponga de acuerdo sobre qué referencia tiene y durante cuánto tiempo es válida. Los invariantes distribuidos son donde viven las condiciones de carrera, porque una carrera nunca es un bug lógico que puedas ver en una sola función. Es un bug en una suposición compartida entre dos.

Así que la pregunta que empecé a hacerle a cada función que tocaba un `PWND` no era *«¿es correcto este código?»*, sino:

> **Si este cuerpo de función exacto se ejecuta en dos hilos con unas pocas instrucciones de diferencia, ¿cuál de ellos es el equivocado?**

## 3. Causa raíz

El defecto es una **brecha de tiempo de comprobación / tiempo de uso entre la liberación de la referencia y la destrucción del objeto** en la ruta de destrucción de la ventana, sin sincronización adecuada frente a un consumidor concurrente que valida el handle.

En esencia:```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      */
    }
}

No se recibió contenido en el bloque de entrada (INPUT) para traducir.```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 */
    ...

}

Dos cosas tienen que ser ciertas para que esto importe, y ambas lo eran:

**(a) La ventana es real.** `ValidateHwnd` es la puerta que se supone que hace seguro el acceso basado en identificadores. Si la validación puede tener éxito contra un objeto cuyo desmontaje ya ha comenzado, la puerta no es una puerta — es una sugerencia.

**(b) La memoria liberada es influenciable por el atacante.** Los campos leídos inmediatamente después de la validación incluyen `fnid`, que impulsa el despacho de mensajes. Una decisión de despacho tomada desde memoria reclamada es la diferencia entre *"caída no fiable"* y *"violación del límite de seguridad"*. Esa distinción es la razón completa por la que esto es CWE-362 con impacto de EoP y no un error de estabilidad.

> La **corrupción** observada es un use-after-free; la **causa** es CWE-362, ejecución concurrente que usa un recurso compartido con sincronización inadecuada. Son dos afirmaciones distintas y a MSRC le importa la segunda. **Reporta la causa, no solo el síntoma.**

### Por qué las carreras de win32k son estructuralmente más difíciles de lo que parecen

Si has corrido contra errores en otros subsistemas, win32k te frustrará, porque la arquitectura lucha contra ti de tres maneras específicas.
Descargar herramienta