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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-50416-writeup-and-poc — CVE-2026-50416: Bypass de KASLR en Windows 11 | Kitploit
Herramientas/GitHubGitHub/karollooool/cve-2026-50416-writeup-and-poc
Frameworks de ExploitsForensia de MemoriaAnálisis de VulnerabilidadesExplotaciónRecopilación de InformaciónCTFAnálisis de BinariosPapers e InvestigaciónAprendizaje y Educación
Labs y Práctica
GitHubkarollooool/cve-2026-50416-writeup-and-poc

CVE-2026-50416-writeup-and-poc

CVE-2026-50416: Bypass de KASLR en Windows 11

Ver RepositorioSitio web
44524hace 9 díasRevisado 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-2026-50416: una dirección del kernel en el heap de escritorio

En el sistema afectado, esta lectura desde la asignación de usuario del heap de escritorio de Win32 devolvió una dirección del kernel:

ULONG64 leaked = *(ULONG64 *)(desktop_heap + 0x100);

Esa es toda la divulgación. Al principio solo era un valor de ocho bytes con bits altos convincentes. Pasé más tiempo comprobando a qué seguía el valor que leyéndolo.

Microsoft publicó el problema como CVE-2026-50416, una divulgación de información de Win32k clasificada como CWE-200.

Llegar al mapeo

El PoC comienza en el TEB de x64. GS:[0x30] proporciona el TEB actual, TEB + 0x800 llega a los datos del cliente de Win32 en la compilación que probé, y la ranura 5 contiene la dirección de usuario del montón del escritorio:

PVOID teb = (PVOID)__readgsqword(0x30);
PVOID *client_info = (PVOID *)((BYTE *)teb + 0x800);
BYTE *desktop_heap = (BYTE *)client_info[5];

El slot 5 son otros 0x28 bytes dentro de esos datos del cliente. Trellix documentó la misma ruta TEB + 0x800 + 0x28 mientras estudiaba los mapeos de tagWND en Windows 10 1909. Estos offsets no son un ABI. Los codifiqué de forma fija y llamo a VirtualQuery sobre el resultado antes de usar la región mapeada.

La comprobación del puntero cubre la extensión de signo canónica de x64, la alineación de ocho bytes y patrones centinela conocidos. Después, el valor tiene que superar las pruebas de comportamiento que se describen a continuación.

Qué cambié en torno a esto

El PoC principal lee el offset 0x100, crea una ventana STATIC, una BUTTON y una EDIT, lo vuelve a leer, destruye las tres ventanas y luego lo lee una vez más.

ULONG64 before = *(ULONG64 *)(desktop_heap + 0x100);

/* Create STATIC, BUTTON and EDIT windows. */
ULONG64 after_create = *(ULONG64 *)(desktop_heap + 0x100);

/* Destroy all three. */
ULONG64 after_destroy = *(ULONG64 *)(desktop_heap + 0x100);

Los tres QWORD coincidieron. Esas asignaciones de ventana aparecieron y desaparecieron; el valor en 0x100 no lo hizo.

kaslr_sandbox_proof.c se encarga de la comparación de procesos. El padre redirige la salida estándar de cada hijo a través de una tubería, analiza el QWORD que leyó el hijo y lo compara con la línea base.

Los hijos adjuntos al escritorio predeterminado devolvieron el mismo valor. Un hijo asignado a un escritorio creado con CreateDesktop devolvió uno diferente. El arnés también ejercita hijos de integridad baja, AppContainer, su configuración LPAC y AppContainer de integridad baja. Todos realizan la lectura desde su propio TEB y mapeo en lugar de recibir el valor del padre.

supporting_proof_no_window.c realiza la lectura sin llamar a CreateWindowEx. No se necesita una nueva ventana USER.

La aritmética de direcciones

El PoC principal trata el valor filtrado menos 0x40 como la base del lado del kernel correspondiente al montón del escritorio:

ULONG64 candidate_kernel_heap_base = leaked - 0x40;

Luego busca user32!gSharedInfo, utiliza los 16 bits bajos de un HWND como índice de la tabla de handles de USER y avanza a través de aheList mediante HeEntrySize. Si el primer QWORD de esa entrada no es cero y es menor que el heap mapeado, el PoC lo utiliza como un desplazamiento relativo del heap de escritorio:

ULONG index = (ULONG)(ULONG_PTR)hwnd & 0xffff;
BYTE *entry = (BYTE *)shared->aheList + index * shared->HeEntrySize;
ULONG64 heap_offset = *(ULONG64 *)entry;

if (heap_offset > 0 && heap_offset < heap_size) {
    BYTE *user_candidate = desktop_heap + heap_offset;
    ULONG64 kernel_candidate = candidate_kernel_heap_base + heap_offset;
}

Esta es la misma relación general que se utiliza en las técnicas más antiguas de montículo de escritorio: las vistas de usuario y de kernel colocan un objeto en el mismo desplazamiento desde sus respectivas bases de montículo. Unit 42 proporciona contexto útil sobre la tabla de identificadores USER y las filtraciones de direcciones más antiguas de gSharedInfo y HMValidateHandle.

Las direcciones resultantes son los candidatos a objeto de kernel del PoC. La relación 0x40, el diseño de la entrada de identificador y los desplazamientos del TEB pertenecen a la compilación utilizada para la prueba.

Dejo los candidatos a objeto ahí. El QWORD en desktop_heap + 0x100 ya es información estable de dirección en espacio de kernel dentro de una asignación legible por el usuario. Un fallo de corrupción de memoria de Win32k independiente puede utilizarlo en lugar de adivinar una dirección.

Descargar herramienta