Zero Day en la respuesta activa de una solución de seguridad: investigación y hallazgo

Una vez que un atacante ha conseguido acceso inicial y ha establecido persistencia dentro de un entorno corporativo, sus objetivos fundamentales son claros: evadir los mecanismos de detección y extraer información sensible de valor estratégico.

Sin embargo, en escenarios con un entorno de seguridad maduro —con todos los parches de seguridad aplicados y sin errores de configuración— lograr estos objetivos desde un usuario estándar puede resultar extremadamente complejo. En escenarios donde el equipo comprometido está aislado del Directorio Activo o carece de conectividad limitada con recursos críticos, la escalada de privilegios suele convertirse en un requisito indispensable para avanzar en el ataque.

Es precisamente en este tipo de escenarios donde las vulnerabilidades de día cero en software de seguridad —que opera inherentemente con privilegios elevados— representan un vector de escalada crítico y difícil de mitigar mediante controles preventivos tradicionales.

Escenario de partida

Una de las diferencias fundamentales entre un ejercicio de Red Team y una prueba de penetración tradicional (pentesting) radica en la profundidad y sofisticación de las técnicas empleadas. Mientras que el pentesting se centra en identificar vulnerabilidades conocidas mediante metodologías establecidas, el Red Team simula adversarios reales que desarrollan técnicas personalizadas y explotan vulnerabilidades desconocidas para evadir las defensas más avanzadas.

Esta aproximación requiere de una inversión significativa en investigación de seguridad ofensiva, donde los analistas dedican tiempo a identificar nuevos vectores de ataque, encontrar vulnerabilidades de día cero, desarrollar herramientas que faciliten el movimiento lateral, acceso inicial, evasión de defensas, entre otros.

Escalada de privilegios en la respuesta activa de una solución de seguridad

Durante un ejercicio, el equipo de Red Team de KPMG logró descubrir una nueva vulnerabilidad de escalada de privilegios que reside en todas las integraciones de respuesta activa de un producto de seguridad.

Cabe destacar que se trata de una vulnerabilidad que afecta a la configuración por defecto en las integraciones de respuesta activa distribuidas por sus canales oficiales, pero no al propio agente, por lo que, una vez que un usuario implementa cualquier respuesta activa ante amenazas, este se vuelve vulnerable por defecto. Si los usuarios no implementan ningún módulo de respuesta activa esta vulnerabilidad no es aplicable a su entorno.

La vulnerabilidad consiste en una eliminación arbitraria de archivos que, mediante ‘Alternate Data Streams’ y el uso de ‘MSI rollback’, permite el compromiso completo de la máquina escalando a SYSTEM, más allá de un borrado arbitrario de fichero el cual “simplemente” generaría un Denial of Service (DoS).

¿Borrar la amenaza? ¡Yo soy la amenaza!

Las vulnerabilidades en el proceso de borrado de archivos son comunes, es por esta razón que se decidió analizar el flujo de eliminación de archivos maliciosos con ‘Process Monitor’ (ProcMon).

Para analizar el comportamiento legítimo de eliminación de archivos, configuramos el siguiente filtro de ProcMon para observar operaciones privilegiadas de los procesos implicados:

Filtros de ProcMon

Una vez establecido el filtro, creamos un archivo EICAR (Standard Anti-Virus Test File) en una carpeta sobre la que tengamos control total con el fin de generar una detección. Este archivo es comúnmente usado para verificar la eficacia de los antivirus por lo que será detectado y eliminado.

El agente monitoriza constantemente los directorios especificados en la configuración de FIM, en los cuales se encuentran en la carpeta de usuario:

Aperturas y escrituras en el archivo de log

Cuando el agente detecta un archivo nuevo, este envía su hash a VirusTotal (lista CDB, YARA, o integración en uso), y en el caso de que este haya sido marcado como malicioso, inicia el proceso de eliminación. Para ello, ejecuta un nuevo proceso con el ejecutable creado mediante pyinstaller. Dicho binario, escribe un log notificando el proceso de borrado, esta operación resultará especialmente útil para ganar la condición de carrera:

proceso de eliminación

Desde ProcMon, se puede observar la apertura del archivo y escritura, entre otras operaciones:

Aperturas y escrituras en el archivo de log

Una vez escrito el log, el agente procede a la eliminación de la amenaza sin hacer uso de impersonación de un usuario con menos privilegios mediante el comando os.remove(), que ejecuta la WinAPI DeleteFileW por debajo.

Borrado de fichero con privilegios de System

Por lo tanto, el flujo final de eliminación de archivo es el siguiente:

Proceso de borrado de un archivo con respuesta activa

Redirigiendo el borrado

Sobre los symlinks en Windows

Los ‘NTFS reparse points’, son un tipo de objeto en el filesystem NTFS que pretenden extender la funcionalidad de este, gracias a ellos, podemos llevar a cabo la explotación de este tipo de bugs.

Una de las funcionalidades de los ‘reparse points’ más útiles, son los ‘directory junctions’, los cuales permiten crear “mount points (junctions)” (similar a los symlinks de directorios en unix) entre carpetas como usuario de bajos privilegios. Estos pueden ser útiles en casos donde el archivo accedido sea arbitrario, casuística que no suele ser común. Es por ello por lo que, en este, y la mayoría de los bugs lógicos, hay que ligarlo con otras funcionalidades.

Por otro lado, la creación de enlaces simbólicos entre archivos en Windows requiere el permiso ‘SeCreateSymbolicLinkPrivilege’, lo que limita su uso para procesos sin privilegios elevados. Sin embargo, existe un mecanismo diferente dentro del sistema operativo que no requiere privilegios elevados para escribir en ciertas rutas: los enlaces simbólicos del ‘Object Manager’.

El ‘Windows Object Manager’ es un componente del kernel que mantiene un ‘namespace’ jerárquico para todos los objetos del sistema—dispositivos, drivers, mutexes, eventos, pipes, endpoints RPC, etc.—independientemente del sistema de archivos. Este ‘namespace’ solo existe en memoria y su función es unificar la representación de recursos del kernel. Como describe la documentación de Microsoft:

«The Windows kernel-mode object manager component manages objects. Files, devices, synchronization mechanisms, registry keys, and so on, are all represented as objects in kernel mode. Each object has a header (containing information about the object such as its name, type, and location), and a body (containing data in a format determined by each type of object).»

Como curiosidad, la unidad C: es un DOS device representado como un enlace simbólico del Object Manager en el directorio \?? (que generalmente apunta a \GLOBAL??). En ese directorio, C: es un enlace simbólico hacia \Device\HarddiskVolumeX. Este es precisamente el tipo de enlace del Object Manager que utilizaremos.

Visualización con WinObj de los enlaces simbólicos del Object Manager

Sin embargo, tal como hemos mencionado, los dispositivos del Object Manager no son archivos y no pertenecen al sistema de ficheros NTFS. Por tanto, su existencia o resolución no depende del sistema de archivos. Para conseguir una redirección completa que pueda interactuar con operaciones realizadas desde el sistema de archivos, es necesario combinar dos primitivas distintas:

1. Enlace simbólico en el Object Manager

Un usuario de bajos privilegios puede escribir en las siguientes rutas del object directory:

  • \RPC Control
  • \Sessions\X\BaseNamedObjects
  • \Sessions\X\AppContainerNamedObjects\SID\{SID_USER}

Siendo la más común \RPC Control por su evidente simplicidad.

Sabiendo esto, podemos crear un enlace como, por ejemplo: \RPC Control\foo → \??\C:\Destino”. Este symlink puede apuntar a cualquier ruta, incluido el filesystem.

2. Un NTFS junction que apunte a \RPC Control\

Como se mencionó al principio del punto, es posible hacer mount points entre carpetas de Windows, es decir, directory Junctions. Por ejemplo, que la carpeta C:\Users\lowpriv\test, apunte a C:\Users\Administrator\juicy_folder.

Lo que resulta especialmente de este tipo de reparse point, es que permite crear un mount point a “\RPC Control\”, sirviendo de esta manera, como una especie de “salto” entre el filesystem NTFS y el Object Directory, donde reside nuestro symlink.

La combinación de ambas capas permite construir lo que se conoce como un pseudo-symlink: una redirección que comienza en NTFS y continúa su resolución en el Object Manager. De esta manera, cuando el programa vulnerable busque un archivo de nombre ya conocido/cacheado, lo hará sobre “\RPC Control\archivo”, por lo que seguirá la ruta definida en el Object Manager.

Pseudo-symlink seguido por la solución

Time is (not) on my side

Los Opportunistic Locks (oplocks) son un mecanismo de sincronización de Windows que permite a una aplicación recibir notificaciones cuando otro proceso intenta acceder a un archivo que está monitorizando. Cuando se establece sobre un archivo, el hilo queda bloqueado hasta que el proceso bloqueador lo libera, eliminando de esta manera el problema con el espacio de tiempo entre la lectura del archivo y su borrado.

Para explotar exitosamente esta vulnerabilidad, es imprescindible ganar la condición de carrera TOCTOU (Time of Check Time of Use). El desafío principal radica en el timing: necesitamos detectar el momento exacto en que el agente va a ejecutar la eliminación del archivo malicioso, es decir, posterior al envío del hash malicioso a VirusTotal y antes del borrado. Pero disponemos de apenas milisegundos para preparar toda la infraestructura de redirección.

Si estableciéramos un oplock directamente sobre el archivo EICAR, bloquearíamos el proceso antes de que el agente pudiera calcular su hash y enviarlo a VirusTotal, impidiendo que el archivo sea marcado como malicioso y frustrando así todo el flujo de ataque. En su lugar, necesitamos un indicador más preciso que nos notifique cuando el análisis ha completado y la eliminación está a punto de ejecutarse.

Desarrollando el exploit

El primer paso para explotar esta vulnerabilidad consiste en establecer un oplock sobre el archivo de log del Active Response:  active-responses.log. Este archivo es crítico porque, como observamos en el análisis del código, el agente escribe en él inmediatamente antes de ejecutar la eliminación del archivo malicioso.

Una vez establecido el oplock, accionamos el comportamiento vulnerable creando un archivo señuelo EICAR en una carpeta sobre la que tengamos control total, por ejemplo C:\Users\lowpriv\Documents\eicar.test. El módulo FIM detectará casi instantáneamente la creación del nuevo archivo, calculará su hash y lo enviará a VirusTotal para su análisis.

¿Quieres saber cómo integrar el Red Team en la estrategia de seguridad?

Cuando VirusTotal confirma que el archivo es malicioso, el agente procede a ejecutar el binario de respuesta activa, creando un nuevo proceso con privilegios de SYSTEM.

Como primera acción, este proceso escribe una línea en active-responses.log indicando que va a proceder con la eliminación. Es precisamente en este momento cuando nuestro oplock se dispara, bloqueando el hilo de borrado y permitiéndonos ejecutar las acciones pertinentes sobre el sistema de archivos antes de liberar el hilo.

OPLock Callback

Una vez activado el primer oplock, es decir, que el archivo ya ha sido analizado, y está en proceso de ser eliminado, se establece un oplock sobre el propio archivo eicar (en modo delete) para que cuando se ejecute la operación SetDispositionInformationEx con flag FILE_DISPOSITION_DELETE, el thread quede bloqueado con el fin de crear finalmente la redirección, por lo tanto, el flujo final del exploit es el siguiente:

Diagrama de explotación

1. Creación del enlace simbólico en el Object Manager

Utilizando las herramientas ‘symboliclink-testing-tools’ de James Forshaw, creamos un enlace simbólico en el directorio “\RPC Control\eicar.test”:

Creación de un enlace simbólico a RPC Control

Es justo en ese enlace simbólico donde nace la necesidad de hacer uso deAlternate Data Streams (ADS)’.

En NTFS, los metadatos de la carpeta se almacenan un ADS en la misma. Por ende, para la carpeta ‘C:\Config.msi’, el metadato ‘IndexData’ residirá en ‘C:\Config.msi::$INDEX_ALLOCATION’.

Cabe destacar que el borrado de ese ADS, eliminará la carpeta, pudiendo de esta manera obtener un arbitrary folder delete partiendo de un ‘arbitrary file delete’, ya que DeleteFileW acepta ese tipo de rutas en versiones de Windows previas a 24H2 (en versiones posteriores, la operación resultará en IS DIRECTORY).

2. Movimiento del archivo usando el handle del oplock

Como el archivo EICAR reside en un directorio no vacío (C:\Users\lowpriv\Documents\), no podemos crear un mount point directamente en esa ubicación—los mount points solo pueden crearse en directorios vacíos- Para sortear esta limitación, debemos mover el archivo a una ubicación temporal como C:\Windows\Temp\random_file.

Este movimiento debe realizarse usando el ‘handle’ del oplock que establecimos en el paso anterior, ya que el archivo sigue bloqueado por el opportunistic lock y no nos permitirá moverlo con un handle diferente.

Código para mover el fichero reutilizando el handle anterior

3. Creación del NTFS directory junction

Una vez que el directorio se encuentra vacío, y la operación de borrado está a la espera de ser liberada, es preciso crear el directory junction’ a ‘\RPC Control’, donde se seguirá el ‘symlink’ de eicar.test al ADS de la carpeta config.msi:

Creación de un junction point a RPC Control

4. Liberando el bloqueo

Una vez se libera el segundo ‘oplock’, la carpeta “C:\Config.msi” es eliminada completamente con privilegios de SYSTEM, proporcionándonos la primitiva necesaria para la fase final de explotación.

Borrado de la carpeta con privilegios de System

Escalada de Privilegios mediante MSI Rollback

La eliminación arbitraria de “C:\Config.msi” nos proporciona el vector para explotar el mecanismo de ‘rollback’ de ‘Windows Installer’. Esta carpeta es utilizada por el servicio msiexec.exe para almacenar scripts de ‘rollback’ que se ejecutan con privilegios de SYSTEM cuando una instalación falla o es revertida con el fin de volver al estado anterior del sistema previo a la instalación. Para más información sobre esta técnica os recomendamos leer el siguiente artículo.

Con la carpeta eliminada, es posible recrearla bajo nuestro control, añadiendo scripts de rollback maliciosos. Al disparar una instalación MSI que falle intencionalmente, Windows Installer ejecutará nuestros scripts con privilegios elevados, completando la escalada de privilegios y otorgándonos control total sobre el sistema comprometido.

En definitiva, la explotación de vulnerabilidades de día cero en la organización es imposible de prevenir. Este hallazgo enfatiza la importancia de mantener una correcta postura de defensa en profundidad, subrayando que no solo es relevante ejecutar pruebas de penetración habituales —ya que siempre habrá un punto de entrada— sino comprobar la respuesta de la organización ante intrusiones y vectores de ataque no contemplados por el equipo defensivo.

Este artículo se basa en un proyecto de investigación continuo realizado por el equipo de research ofensivo del área de ciberseguridad de KPMG en España y, en concreto, por Eduardo Pérez-Malumbres Cervera, miembro senior del equipo de Red Team.