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-2019-1458_POC — POC para cve-2019-1458 | Kitploit
Herramientas/GitHubGitHub/piotrflorczyk/cve-2019-1458_poc
Análisis de VulnerabilidadesExplotaciónIngeniería InversaAprendizaje y EducaciónExplotación de Binarios
GitHubpiotrflorczyk/cve-2019-1458_poc

cve-2019-1458_POC

POC para cve-2019-1458

Ver Repositorio
181539hace 4 añosRevisado por Kitploit

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

CVE-2019-1458: Del 'informe in the wild' al POC

Introducción

En diciembre, Kaspersky publicó una entrada de blog sobre [un exploit de día cero usado en ataques reales][1]. Me picó el interés porque, aunque describían cómo funcionaba el exploit, no proporcionaban ningún POC en su análisis.
Por eso decidí intentar escribir un POC para esta vulnerabilidad basándome en la entrada de blog de Kaspersky y en el análisis del parche.
Este post describe mi viaje haciendo eso.

Recopilación de información:

Lo primero fue recopilar toda la información posible sobre esta vulnerabilidad.
Leyendo la entrada de blog mencionada, extraje la siguiente información:

  • La vulnerabilidad está relacionada con la funcionalidad de conmutación de ventanas
  • Requiere simular pulsaciones de la tecla ALT para activarse
  • Se necesitan dos llamadas a la API no documentada NtUserMessageCall
  • Es necesario crear una ventana de conmutación especial
  • Había alguna referencia a la función del kernel win32k!DrawSwitchWndHilite

Además, hay una buena captura de pantalla del código descompilado que muestra algunas de las cosas enumeradas anteriormente.
Para ser exacto, muestra: la creación de la ventana de conmutación, la llamada a una función llamada toggle_alt_key y múltiples llamadas a NtUserMessageCall.

Parte del código de exploit descompilado [Fuente de la imagen][1]

Mucha información útil, pero aún no describe exactamente cómo funciona esta vulnerabilidad ni cómo activarla.

Diffing del parche

[El módulo afectado era win32k.sys][2]. Descargué las versiones parcheada y sin parchear de este módulo.
Para Win7 x64 fueron:

  • parcheada: KB4530692
  • sin parchear: KB4525233

Se pueden descargar desde [Microsoft Update Catalog][3]

Aquí está el resultado de bindiff al comparar ambas versiones

comparación win32k

Después de descartar las funciones relacionadas con la funcionalidad DebugHook, todo lo que realmente nos queda es esta función ligeramente modificada InitFunctionTables()

cambios en InitFunctionTables

Definitivamente no es el parche más grande que hay.
Esto no ayudará a identificar de inmediato la causa raíz de esta vulnerabilidad. Pero vale la pena señalar que se han añadido algunos valores iniciales para variables en *(gpsi+0x14E), *(gpsi+0x154), *(gpsi+0x180). Así que esto podría ser un error relacionado con una variable no inicializada.

Construcción del POC: paso a paso

En esta sección presentaré cómo fui construyendo progresivamente un POC que activa esta vulnerabilidad, mientras al mismo tiempo descubría qué era realmente la vulnerabilidad.

Por dónde empezar

El diffing del parche no dio demasiada información útil al principio, así que en la primera etapa del desarrollo me apoyé principalmente en la entrada de blog de Kaspersky.
Para tener un buen entorno de pruebas preparé una VM con Win7 SP1 x64 con la última versión vulnerable de win32k en ejecución. Además, conecté Windbg a esta VM para hacer depuración del kernel y, mientras hacía eso, también configuré la ruta del servidor de símbolos.
Empecé mi investigación mirando win32k!DrawSwitchWndHilite, que se mencionaba en la entrada de blog. Se llama desde dos lugares: xxxMoveSwitchWndHilite y xxxPaintSwitchWindow; este último llamó inmediatamente mi atención por las llamadas a GetKeyState/GetAsyncKeyState que lo rodean y que se mencionaban en el informe original. Es más, esas llamadas comprueban si se está pulsando la tecla ALT.

Punto de llamada interesante a DrawSwitchWndHilite
Llamada a DrawSwitchWndHilite desde xxxPaintSwitchWindow

Siguiendo las referencias cruzadas de llamadas (xxxWrapSwitchWndProc->xxxSwitchWndProc->xxxPaintSwitchWindow->DrawSwitchWndHilite), descubrí que el primer elemento de esa cadena se referencia en InitFunctionTables, la función que se corrigió en el parche.

Después miré NtUserMessageCall de la captura de pantalla del código descompilado.
Aquí está la declaración de esta función```cpp NtUserMessageCall(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOLEAN bAnsi)

El exploit lo llama con `msg = 0x14` y `dwType = 0xE0`. Veamos qué hace.```cpp
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wcx;
ZeroMemory(&wcx, sizeof(wcx));
wcx.hInstance = hInstance;
wcx.cbSize = sizeof(wcx);
wcx.lpszClassName = L"SploitWnd";
wcx.lpfnWndProc = DefWindowProc;

printf("[*] Registering window\n");
ATOM wndAtom = RegisterClassEx(&wcx);
if (wndAtom == INVALID_ATOM) {
    printf("[-] Failed registering SploitWnd window class\n");
    exit(-1);
}

printf("[*] Creating instance of this window\n");
HWND sploitWnd = CreateWindowEx(0, L"SploitWnd", L"", 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (sploitWnd == INVALID_HANDLE_VALUE) {
    printf("[-] Failed to create SploitWnd window\n");
    exit(-1);
}
NtUserMessageCall(sploitWnd, WM_ERASEBKGND, 0, 0, 0, 0xE0, 1);

Aquí registré una clase de ventana simple y creé una ventana de esa clase. Luego llamé a NtUserMessageCall con los mismos parámetros que el exploit. Para ver qué ocurre internamente, establecí el punto de interrupción kd> ba e 1 win32k!NtUserMessageCall y ejecuté el código. Se realizan bastantes llamadas a esta función, así que tuve que capturar la correcta, pero no fue tan difícil: era la que tenía una pila de llamadas realmente corta.

NtUserMessageCall
NtUserMessageCall

Al recorrer el código paso a paso se revela que llama a una función del array gapfnMessageCall; el índice se calcula a partir del valor de msg y es igual a 0, por lo que la llamada se hace a NtUserfnDWORD.

NtUserfnDWORD
NtUserfnDWORD

La siguiente llamada se hace usando el valor de dwType, y ahora el offset de gpsi es igual a 0x40, y la llamada conduce a xxxWrapSwitchWndProc (esta función ya apareció cuando revisaba la cadena de llamadas de DrawSwitchWndHilite).
xxxWrapSwitchWndProc simplemente llama a xxxSwitchWndProc.

xxxSwitchWndProc
xxxSwitchWndProc

Y este es el final; el código falla aquí y no avanza hasta xxxPaintSwitchWindow, que es donde queremos llegar según el valor de msg (0x14). Veamos por qué.

Desencadenando la ruta correcta

El código falla en esta etapa porque, como se resalta en la imagen anterior, el fnid de nuestra ventana no es igual a 0x2A0 (FNID_SWITCH) y el mensaje que enviamos no es igual a 1, por lo que terminamos en xxxDefWindowProc. Para evitar este escenario, tenemos que llamar a xxxSwitchWndProc con fnid establecido a FNID_SWITCH, de modo que vayamos directamente a la sentencia switch y luego a xxxPaintSwitchWindow.
¿Cómo establecer el fnid correcto? En realidad, la misma función lo hace en el primer bloque if; solo tenemos que fallar todas las comprobaciones dentro de él para llegar a la instrucción que establece el fnid.

Estas son las condiciones que debemos cumplir para fallar las tres comprobaciones if:

Descargar herramienta