
Investigación de tesis de maestría sobre CVE-2024-30051 (desbordamiento de montón de DWM en Windows). Incluye un exploit de alta fiabilidad con optimización automatizada de heap spray, registro en tiempo real y análisis empírico de la tasa de éxito. Pieza de portafolio que demuestra explotación avanzada de binarios de Windows, manipulación del diseño del montón y LPE a través del Administrador de ventanas de escritorio.
Desbordamiento de búfer basado en heap en el Administrador de ventanas de escritorio de Windows (
dwmcore.dll)
Escalada de privilegios local → nivel de integridad SYSTEM a través del proceso DWM
Objetivo de compilación: Windows 11 22H2 (10.0.22621.3447) · Parche: KB5037771
Este repositorio contiene mi investigación de Tesis de Máster sobre CVE-2024-30051, una vulnerabilidad de elevación de privilegios de severidad alta (CVSS 7.8) en la librería principal del Administrador de ventanas de escritorio de Windows (dwmcore.dll).
La vulnerabilidad se origina en un error de cálculo de tamaño por división entera en CCommandBuffer::Initialize. El tamaño usado para new() y el usado para memcpy() divergen debido a este error de cálculo, produciendo un desbordamiento de heap de 0x8F bytes. Un exploit exitoso provoca que dwm.exe cargue una DLL controlada por el atacante, ejecutando código arbitrario bajo la cuenta window manager\dwm-1 con nivel de integridad SYSTEM.
CVE-2024-30051-Masters-Thesis/
├── README.md
├── LICENSE
├── setup.bat # Copies s11.dll to required location
│
├── exploit/
│ ├── C21.sln # Visual Studio 2022 solution
│ ├── exploit_src/
│ │ ├── c26f.vcxproj
│ │ ├── c26f.filters
│ │ └── main.cpp # Exploit — heap spray + hooking + overflow
│ └── payload/
│ ├── payload.vcxproj
│ ├── payload.vcxproj.filters
│ ├── dllmain.cpp # Payload DLL — spawns SYSTEM shell + cleanup
│ ├── framework.h
│ ├── pch.h
│ └── pch.cpp
│
└── docs/
├── screenshots/ # Patch diffing, WinDbg, and forensic captures
└── analysis/
├── 01-root-cause.md # Integer division bug in CCommandBuffer::Initialize
├── 02-heap-spray.md # 50-session empirical data and statistical findings
└── 03-timeline.md # Discovery, disclosure, and patch chronology
Abre C21.sln en Visual Studio 2022. Compila el proyecto payload en Release x64.
Ejecuta setup.bat desde la raíz del repositorio. Copia s11.dll a C:\Users\Public\Documents\s11.dll (la ruta definida por PAYLOAD_DLL_PATH).
⚠️ La DLL debe estar en esta ruta exacta antes de ejecutar
C26f.exe. Colocarla junto al ejecutable no funcionará.
Compila el proyecto C26f en Release x64.
x64\Release\C26f.exe
Ejecuta desde un CMD estándar (sin elevación). El exploit reintenta automáticamente hasta 10 veces. En caso de éxito, dwm.exe carga s11.dll y abre un CMD con nivel de integridad SYSTEM. Se escribe un registro de sesión en %TEMP%\cve_30051_log.txt.
#define MAX_ATTEMPTS 10 // Max auto-retry attempts per session
#define SPRAY_STEP 0x10 // Hole spacing index (1024 holes)
#define SPRAY_RANGE_START 0x3000 // Spray range start index
#define SPRAY_RANGE_END 0x7000 // Spray range end index
#define SLEEP_POST_SPRAY 0xC8 // ms wait after spray (200ms)
#define SLEEP_POST_HOLES 0xC8 // ms wait after freeing holes (200ms)
#define PAYLOAD_DLL_PATH "C:\\Users\\Public\\Documents\\s11.dll"
En CCommandBuffer::Initialize (dwmcore.dll 10.0.22621.3447), CD2DSharedBuffer::GetBufferSize se llama dos veces. El tamaño pasado a new() se somete a una división entera por 0x90 antes de la multiplicación, mientras que memcpy() usa el valor bruto:
buffer_size = GetBufferSize() → e.g. 0x23F
size_new = (0x23F / 0x90) * 0x90 = 0x1B0 ← allocated
size_memcpy = 0x23F ← copied
overflow = 0x23F - 0x1B0 = 0x8F bytes
Comparación BinDiff entre la compilación 10.0.22621.3447 (vulnerable) y la 10.0.22621.3593 (parcheada):
La puntuación anómala de 0.32 frente a una similitud global de 0.98 es la firma directa del lugar de la vulnerabilidad.
1. Hook RtlCreateHeap → capture dwmcore heap handle
2. Hook RtlAllocateHeap → capture base chunk address
3. Hook NtDCompositionCreateChannel → capture MappedAddress (shared memory region)
4. Hook NtDCompositionCommitChannel → overwrite size field (0x120 → 0x23F)
inject additional batch commands
5. Heap spray 0x10000 CHolographicInteropTexture objects (size=0x1B0)
6. Free holes every 0x10 indices → create gaps for overflow landing
7. Write payload into overflow buffer → KCBTable+0x388 + LoadLibraryA + DLL path
8. Release all spray objects → trigger overflow → LoadLibraryA("s11.dll")
9. dwm.exe loads payload DLL → spawns CMD as SYSTEM integrity
¿Influye la RAM disponible en el número de intentos necesarios para lograr un heap spray exitoso?
Dos bloques de 25 sesiones cada uno. Protocolo por sesión: restaurar un snapshot limpio posterior al arranque → esperar 100 segundos de estabilización → lanzar el exploit → registrar el intento de éxito.
| Bloque | RAM | Sesiones | Éxitos | Fallos |
|---|---|---|---|---|
| A | 8,192 MB | 25 | 24 |
| Prueba | Estadístico | Valor p | Conclusión |
|---|---|---|---|
| Mann-Whitney U | U = 184.0 | p = 0.031 | Rechaza H₀ |
| Prueba t de Welch | t(23) = −2.695 | p = 0.011 | Rechaza H₀ |
base = heap_base + 0x720 confirma que el diseño reproducible del heap tras el arranque es el principal impulsor del determinismo, y no la densidad de huecos.Los datos brutos completos, el formato del registro de sesión y las observaciones del heap determinista están documentados en docs/analysis/02-heap-spray.md.
En caso de éxito, se abre una ventana de CMD bajo window manager\dwm-1:
=====================================================
CVE-2024-30051 - Windows DWM Heap Overflow EoP
CWE-122 | CVSS 7.8 | Elevation of Privilege
=====================================================
Researched and reproduced by : devianntsec
Original PoC by : Ricardo Narvaja (Fortra)
Target : Windows 11 22H2 (22621.3447)
=====================================================
[*] Current user:
window manager\dwm-1
[*] Mandatory Integrity Level:
Mandatory Label\System Mandatory Level S-1-16-16384
[*] Enabled privileges:
SeImpersonatePrivilege Enabled
=====================================================
Shell running under DWM process - SYSTEM level
=====================================================
Los artefactos (s11.dll y el script .bat) se eliminan automáticamente a los 5 segundos mediante un proceso de limpieza diferida.
| Documento | Descripción |
|---|---|
Esta investigación forma parte de mi Tesis de Máster en Ciberseguridad (UCAM — Campus Internacional de Ciberseguridad), que analiza vulnerabilidades N-Day en múltiples entornos.
Este CVE representa el vector de aplicación de escritorio de Windows dentro de la tesis, demostrando:
Palabras clave: EoP · Heap Overflow · DirectComposition · DWM · Patch Diffing · BinDiff · WinDbg · Heap Spray · Empirical Analysis · CVE-2024-30051
Annais Molina (devianntsec) — Estudiante de Máster en Ciberseguridad
Licencia MIT — consulta LICENSE
Este repositorio se proporciona solo con fines educativos y de investigación en seguridad, como parte de una Tesis de Máster académica. Todas las pruebas se realizaron en máquinas virtuales aisladas, sin exposición a la red. Úsalo únicamente en sistemas que poseas o para los que tengas autorización escrita explícita para realizar pruebas. El uso no autorizado contra sistemas es ilegal y puede dar lugar a un proceso penal.
| Aspecto | Descripción |
|---|
| Diffing de parches | Análisis BinDiff completo que identifica CCommandBuffer::Initialize como el lugar exacto de la vulnerabilidad (puntuación de similitud de 0.32 frente a 0.98 global en 14,062 funciones coincidentes) |
| Análisis dinámico con WinDbg | Verificación paso a paso de los 4 hooks, de la sobrescritura del campo de tamaño y de la construcción del payload |
| Análisis empírico del heap spray | 50 sesiones controladas en dos configuraciones de RAM (8,192 MB y 4,096 MB) con pruebas estadísticas formales |
| Hallazgos estadísticos | Mann-Whitney U (p = 0.031) y prueba t de Welch (p = 0.011) confirman el efecto de la RAM; medias observadas 12.9–19× mejores que la predicción teórica de ~64 intentos |
| Ruta de la DLL del payload centralizada | Ruta hardcodeada extraída a la constante de preprocesador #define PAYLOAD_DLL_PATH |
| Registro de sesiones | Registro completo con marcas de tiempo por sesión escrito en %TEMP%\cve_30051_log.txt |
| Documentación académica | Causa raíz, análisis de heap spray de 50 sesiones y cronología del CVE |
| Métrica | Valor |
|---|
| Similitud global | 0.98 |
| Confianza | 0.99 |
| Funciones coincidentes | 14,062 (99.1 %) |
Similitud de CCommandBuffer::Initialize | 0.32 |
| Bloques básicos — versión vulnerable | 4 |
| Bloques básicos — versión parcheada | 20 (16 bloques de validación añadidos) |
| 1 |
| B | 4,096 MB | 25 | 24 | 1 |
| Bloque | RAM | Media de intentos | Desviación estándar | IC 95 % | Factor frente a la teoría (64) |
|---|
| A | 8,192 MB | 3.375 | 1.135 | [2.896; 3.854] | ≈ 19× más rápido |
| B | 4,096 MB | 4.958 | 2.645 | [3.841; 6.076] | ≈ 12.9× más rápido |
| Artefacto | Ubicación | Persistencia | Herramienta de detección |
|---|
cmd.exe hijo de dwm.exe | Registro de eventos de seguridad | Sí (si la auditoría de procesos está activa) | Event ID 4688 |
Proceso externo accediendo a dwm.exe | Sysmon | Sí | Sysmon Event ID 10 |
Bloqueo de dwm.exe en intentos fallidos | Registro de eventos de aplicación | Sí | Event ID 1000 |
DLL del payload s11.dll en disco | C:\Users\Public\Documents\ | Solo los primeros ~5 segundos | Monitorización SHA-256 |
Bug de división entera en CCommandBuffer::Initialize, metodología de diffing de parches |
| Análisis del heap spray | Datos empíricos de 50 sesiones, datos brutos de sesión, pruebas estadísticas |
| Cronología del CVE | Descubrimiento, divulgación y cronología del parche |