
Investigación de tesis de maestría sobre CVE-2024-51324 (BYOVD). Exploit avanzado con 4 modos operativos (SCANNER, LOADER, KILLER, CLEANUP), verificación de drivers mediante SHA-256 y documentación académica completa. La pieza de portafolio cubre la seguridad de los drivers del kernel de Windows, la ingeniería inversa de IOCTL y la explotación Bring Your Own Vulnerable Driver.
Bring Your Own Vulnerable Driver (BYOVD) — Antivirus Baidu
BdApiUtil64.sys
Tres primitivas de kernel no documentadas: terminación de procesos, eliminación arbitraria de archivos y eliminación de archivos en uso con bypass deSectionObjectPointer
Afecta a: Antivirus Baidu v5.2.3.116083 (BdApiUtil64.sys)
Cargando el controlador vulnerable en el kernel (modo LOADER)
Este repositorio contiene mi investigación de Tesis de Máster sobre CVE-2024-51324, una
vulnerabilidad Bring Your Own Vulnerable Driver (BYOVD) en el controlador de kernel
BdApiUtil64.sys del Antivirus Baidu.
El registro NVD asigna una puntuación base CVSS v3.1 de 3.8 (Baja) con el vector
AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N y CWE-269 (Gestión inadecuada de privilegios).
Esta puntuación no refleja la realidad del ataque local documentada en esta investigación: una vez
que el controlador es cargado por un administrador (un paso único alcanzable mediante ingeniería
social o cualquier escalada de privilegios local), cualquier proceso posterior — incluidos los
procesos en espacio aislado o de usuario estándar — puede enviar IOCTLs sin comprobaciones de
privilegios adicionales. Una puntuación CVSS v3.1 evaluada por el investigador de 7.8 (Alta) con
el vector AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H refleja con mayor precisión la realidad de la
explotación posterior a la carga. Ambas puntuaciones se analizan en la documentación técnica.
El controlador crea el objeto de dispositivo \Device\BdApiUtil con
SecurityDescriptor = NULL, lo que permite que cualquier proceso, independientemente de su nivel de
integridad, abra un handle y envíe IOCTLs. El análisis estático mediante Ghidra 11.0.3 revela que el
mecanismo interno es más significativo de lo documentado anteriormente: el controlador utiliza
PsLookupProcessByProcessId + ObOpenObjectByPointer(KernelMode) en lugar de
ZwOpenProcess, omitiendo SeAccessCheck por completo. Se caracterizaron por completo tres
primitivas IOCTL, dos de las cuales no cuentan con documentación pública previa.
CVE-2024-51324/
├── README.md
├── LICENSE
│
├── drivers/
│ └── BdApiUtil64.sys # Driver (not distributed)
│
├── exploit/
│ ├── exploit-explanation.md
│ └── byovd_killer.py # Main exploit — 4 operational modes
│
└── docs/
├── screenshots/
│ ├── 01-byovd-scan.png
│ ├── 02-byovd-scan-target.png
│ ├── 03-byovd-load.png
│ ├── 04-byovd-load-custom.png
│ ├── 05-kill-name.gif
│ ├── 06-kill-pid.gif
│ ├── 07-kill-limit.gif
│ ├── 08-dry-run.gif
│ └── 09-byovd-cleanup.png
│
└── analysis/
├── 01-root-cause.md
├── 02-driver-analysis.md # Full Ghidra RE, three primitives, PPL testing
└── 03-timeline.md
BdApiUtil64.sys (SHA-256: 47EC51B5F0EDE1E70BD66F3F0152F9EB536D534565DBB7FCC3A05F542DBE4428)python exploit/byovd_killer.py --scan
python exploit/byovd_killer.py --scan --target lsass.exe
python exploit/byovd_killer.py --load
python exploit/byovd_killer.py --load --driver C:\path\to\BdApiUtil64.sys
python exploit/byovd_killer.py --load --service-name MyService
python exploit/byovd_killer.py --kill notepad.exe
python exploit/byovd_killer.py --pid 1234
python exploit/byovd_killer.py --kill notepad.exe --max-instances 2
python exploit/byovd_killer.py --kill notepad.exe --dry-run
python exploit/byovd_killer.py --cleanup
python exploit/byovd_killer.py --cleanup --service-name MyService









La ingeniería inversa de BdApiUtil64.sys mediante Ghidra 11.0.3 identificó una superficie de
ataque más amplia que cualquier fuente pública previa:
0x800024B4)La cadena de despacho tiene tres niveles:
IOCTL 0x800024B4
└─ FUN_00028630 (IRP_MJ_DEVICE_CONTROL dispatcher)
└─ FUN_00015230 (wrapper: validates IOCTL code and buffer size = 4 bytes)
└─ FUN_000152b0 (kill handler — vulnerability locus)
Manejador reconstruido (Ghidra):
if ((param_1 != 0) && (param_1 != 4)) {
PsLookupProcessByProcessId(param_1, &local_res10);
ObOpenObjectByPointer(
local_res10,
0x200, // OBJ_KERNEL_HANDLE
0, // PassedAccessState: NULL
0x1fffff, // PROCESS_ALL_ACCESS
0, // ObjectType: NULL
0, // AccessMode: KernelMode ← bypasses SeAccessCheck
local_res18
);
ZwTerminateProcess(local_res18[0], 0);
}
Por qué KernelMode omite SeAccessCheck:
ZwOpenProcess path:
NtOpenProcess → ObOpenObjectByName → SeAccessCheck
(checks DACL, caller token, integrity level)
can return STATUS_ACCESS_DENIED
ObOpenObjectByPointer(KernelMode) path:
SeAccessCheck ← NOT invoked
→ PROCESS_ALL_ACCESS handle granted unconditionally
ZwOpenProcess está ausente de la tabla de importaciones del controlador. La descripción basada
en ZwOpenProcess presente en fuentes anteriores es técnicamente incorrecta.
0x80002648)El manejador FUN_00013bb0 recibe una ruta Unicode, valida
InputBufferLength ≥ 0x208 y delega en FUN_00013c10. El submanejador abre
el archivo en modo kernel (sin SeAccessCheck sobre el token del llamador) y envía un
IRP IRP_MJ_SET_INFORMATION con FileInformationClass = 0xD
(FileDispositionInformation), marcando el archivo para su eliminación. Cualquier archivo accesible
para el kernel puede eliminarse independientemente de los permisos NTFS.
0x8000264C)El manejador FUN_000139d0 accede a FileObject->SectionObjectPointer (offset 0x28
en FILE_OBJECT) y anula temporalmente dos campos antes de enviar el IRP
de eliminación:
plVar1 = FileObject->SectionObjectPointer;
plVar1[2] = 0; // DataSectionObject → NULL
plVar1[0] = 0; // ImageSectionObject → NULL
IofCallDriver(device, irp);
KeWaitForSingleObject(...);
// Restore after completion
plVar1[2] = DataSectionObject_backup;
plVar1[0] = ImageSectionObject_backup;
IopDeleteFile comprueba estos punteros antes de atender FileDispositionInformation.
Al anularlos, el manejador hace que el archivo parezca no estar mapeado, omitiendo la
protección de archivos en uso. Esta primitiva puede eliminar de disco el binario de un agente EDR
en ejecución sin necesidad de terminar primero el proceso.
Cadena completa de eliminación de EDR:
1. Terminate EDR process (IOCTL 0x800024B4)
2. Delete EDR binary on disk (IOCTL 0x8000264C) ← works even if memory-mapped
3. Prevent restart ← executable no longer exists on disk
PPL (Protected Process Light, proceso protegido ligero) es la única mitigación en tiempo de
ejecución que resiste la terminación basada en ObOpenObjectByPointer(KernelMode) de este
controlador.
--cleanupEl Evento ID 7045 es el único artefacto que sobrevive a un ciclo de ataque completo con
limpieza. Contiene el nombre del servicio, ImagePath (ruta completa del binario), el tipo de
servicio y la marca de tiempo de creación.
Ejecutar wevtutil cl System para eliminar el Evento ID 7045 genera el Evento ID 1102
en el canal de Seguridad, registrando quién borró el registro y cuándo. Esto hace que la
manipulación de registros sea detectable incluso si el artefacto original se destruye.
| Acción del atacante | Artefacto resultante | Canal | Persistencia |
|---|---|---|---|
wevtutil cl System |
title: BYOVD Attack via BdApiUtil64.sys (CVE-2024-51324)
id: a3f7c2e1-8b4d-4f9a-b6e3-2d1c9f8a7b5e
status: experimental
logsource:
product: windows
service: system
detection:
selection_eventid:
EventID: 7045
selection_driver:
- ServiceName|contains: 'BdApi'
- ImagePath|contains: 'BdApiUtil64.sys'
condition: selection_eventid and selection_driver
level: high
tags:
- attack.defense_evasion
- attack.t1562.001
- attack.privilege_escalation
- attack.t1068
La regla Sigma completa y la configuración de Sysmon (Evento ID 6 por hash SHA-256 + Evento ID 13
por clave de registro) están disponibles en docs/detection/.
| Documento | Descripción |
|---|---|
| Análisis de causa raíz |
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 controlador de kernel de Windows / BYOVD dentro de la tesis, demostrando:
ZwOpenProcess ausente;
el mecanismo real es ObOpenObjectByPointer(KernelMode))Palabras clave: BYOVD · Kernel Driver · IOCTL · Ghidra · Process Termination ·
File Deletion · SectionObjectPointer · ObOpenObjectByPointer · Defense Evasion ·
CVE-2024-51324
Annais Molina (devianntsec) — Estudiante de Máster en Ciberseguridad
Licencia MIT — consulte LICENSE
Este repositorio se proporciona únicamente 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. El controlador vulnerable (BdApiUtil64.sys) no se distribuye en
este repositorio — debe obtenerse de forma independiente. Úselo únicamente en sistemas de su
propiedad o con 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 |
|---|
| Corrección técnica | ZwOpenProcess está ausente de la tabla de importaciones; el mecanismo real es PsLookupProcessByProcessId + ObOpenObjectByPointer(KernelMode), que omite SeAccessCheck de forma incondicional |
| Tres primitivas documentadas | Terminación de procesos (0x800024B4), eliminación arbitraria de archivos (0x80002648) y eliminación de archivos en uso con bypass de SectionObjectPointer (0x8000264C) — las dos últimas no tienen documentación pública previa |
| Cuatro modos de operación | LOADER, KILLER, SCANNER y CLEANUP — gestión completa del ciclo de vida |
| Verificación SHA-256 | Hash del controlador verificado antes de cualquier intento de carga |
| Pruebas empíricas de PPL | 10 intentos por categoría de proceso que confirman PPL como la única mitigación en tiempo de ejecución |
| Análisis forense | Persistencia del Evento ID 7045 tras la limpieza; Evento ID 1102 como artefacto autoincriminatorio de borrado de registros |
| Reglas de detección | Regla Sigma y configuración de Sysmon (Evento ID 6 por hash + Evento ID 13 por clave de registro) |
| Reevaluación CVSS | Discrepancia documentada entre la puntuación oficial de NVD (3.8 Baja) y la gravedad de explotación local evaluada por el investigador (7.8 Alta) |
| Modo | Comando | Privilegios | Descripción |
|---|
| SCANNER | --scan | Cualquier usuario | Información de estado del sistema y del controlador |
| LOADER | --load | Administrador | Carga del controlador mediante la creación de un servicio de kernel |
| KILLER | --kill / --pid | Cualquier usuario | Terminación de procesos mediante IOCTL |
| CLEANUP | --cleanup | Administrador | Detención y eliminación del servicio del controlador |
| IOCTL | Manejador | Primitiva | Documentación previa |
|---|
0x800024B4 | FUN_000152b0 | Terminación de procesos | Parcial (mecanismo incorrecto) |
0x80002648 | FUN_00013bb0 | Eliminación arbitraria de archivos | Ninguna |
0x8000264C | FUN_00013850 | Eliminación de archivos en uso (bypass de SectionObjectPointer) | Ninguna |
| Proceso | PPL activo | Terminable | Causa |
|---|
notepad.exe | No | ✅ 10/10 | Sin protección |
regedit.exe | No | ✅ 10/10 | Sin protección |
spoolsv.exe | No | ✅ 9/10 | SCM lo reinicia en 1 caso |
MsMpEng.exe | No (sin PPL en el entorno de prueba) | ✅ 8/10 | Ligera variabilidad de tiempos |
lsass.exe | No (RunAsPPL ausente) | ✅ 6/10 | Variabilidad de estado |
csrss.exe | Sí (PPL incondicional) | ❌ 0/10 | STATUS_ACCESS_DENIED |
| Presente | Ausente |
|---|
PsLookupProcessByProcessId | ZwOpenProcess |
ObOpenObjectByPointer | SeAccessCheck |
ZwTerminateProcess | SePrivilegeCheck |
PsGetCurrentProcess | |
IoGetRequestorProcess |
| Escenario | Objetivo | Impacto |
|---|
| Terminación de EDR/AV | MsMpEng.exe, SentinelAgent.exe | Evasión de defensas |
| Eliminación del binario EDR (en uso) | Ejecutable EDR en disco | Impedir el reinicio tras la terminación |
| Interrupción de los registros de auditoría | Servicio EventLog | Manipulación de evidencias forenses |
| Bypass de procesos protegidos | lsass.exe (sin RunAsPPL) | Facilitador de acceso a credenciales |
| Preparación previa al cifrado en ransomware | Agentes de seguridad | Cadena completa de evasión de defensas |
| Artefacto | Estado tras la limpieza |
|---|
| Servicio en SCM | Eliminado |
Controlador en driverquery | Eliminado |
| Objeto de dispositivo | Inaccesible |
| Clave de registro | Eliminada |
| Evento ID 7045 | Persiste — no puede eliminarse con sc delete |
| Evento ID 7045 eliminado |
| System |
| — |
wevtutil cl System | Evento ID 1102 generado | Security | Permanente |
Control de acceso ausente en el manejador de IRP_MJ_DEVICE_CONTROL |
| Análisis del controlador | Ingeniería inversa completa con Ghidra, tres primitivas IOCTL, pruebas de PPL, análisis de la tabla de importaciones |
| Cronología del CVE | Descubrimiento, divulgación y cronología del parche |