Cómo eludir el control de aplicaciones de Windows Defender con Loki C2

Primer plano de las manos de un hacker sobre un teclado

Windows Defender Application Control (WDAC) es una solución de seguridad que restringe la ejecución al software de confianza. Dado que está clasificado como un límite de seguridad, Microsoft ofrece pagos de recompensas por errores para las omisiones calificadas, lo que lo convierte en un campo de investigación activo y competitivo.

Resultados típicos de un envío de recompensas por errores de omisión de WDAC: 

  • La omisión está arreglada; posible recompensa otorgada
  • La omisión no se soluciona, sino que se “mitiga” al agregarse a la lista de bloqueo recomendada por WDAC. Es probable que no se otorgue ninguna recompensa, pero generalmente se da una mención honorífica
  • La omisión no está arreglada, no se otorga recompensa, no hay mención honorífica 

Al mirar la lista de bloqueos recomendados de WDAC de Microsoft, vemos que leyendas como Jimmy Bayne (@bohops) y Casey Smith (@subTee) descubrieron omisión de WDAC que siguen sin corregirse, pero que recibieron menciones honoríficas. Más allá de esta lista, el proyecto LOLBAS contiene omisiones adicionales no corregidas que no se han reconocido en la lista de bloqueo de Microsoft. Un ejemplo es la aplicación Microsoft Teams, que sigue siendo una omisión viable de WDAC a pesar de estar documentada en LOLBAS.

Al encontrar WDAC durante las operaciones del equipo rojo, lo omitimos con éxito y ejecutamos nuestra carga útil de comando y control (C2) de la etapa 2 utilizando las siguientes técnicas: 

1.     Utilice un LOLBIN conocido como MSBuild.exe

  • Funciona si el cliente no ha implementado las reglas recomendadas de la lista de bloqueo.
  • Muchas soluciones de ejecución de la detección y respuesta de endpoints (EDR) con “100 % de cobertura MITRE” tienen detecciones para estos LOLBIN conocidos.  

2. Carga lateral de DLL en una aplicación de confianza con una DLL que no es de confianza 

  • Efectivo si WDAC está habilitado pero no aplica la firma de DLL.  

3.     Explote la regla de exclusión personalizada de la política WDAC del cliente 

4. Encontrar una nueva cadena de ejecución en una aplicación confiable que permita el despliegue de C2 

Aplicaciones Electron

Como explicó Ruben Boonen (@FuzzySec) en su charla del Wild West Hackin' Fest Statikk Shiv: Aprovechando las aplicaciones Electron para la post-explotación, las aplicaciones de electrones funcionan como navegadores web que generan aplicaciones de escritorio usando tecnología en línea estándar como HTML, JavaScript y CSS. El motor de JavaScript en Electron es Node.js, que proporciona potentes API capaces de interactuar con el sistema operativo host. Estas API permiten acciones como leer y escribir archivos, ejecutar programas y otras operaciones típicas de las aplicaciones nativas.

Cómo las aplicaciones Electron ejecutan Node.js JavaScript

En tiempo de ejecución, una aplicación Electron lee archivos JavaScript, interpreta su código y los ejecuta dentro del proceso Electron. La siguiente animación muestra cómo la aplicación Microsoft Teams Electron lee un archivo JavaScript en tiempo de ejecución, que luego utiliza el módulo child_process para ejecutar whoami.exe.

El proceso de Teams Electron lee el archivo JavaScript

En este ejemplo, el proceso Teams Electron lee el archivo JavaScript, que a continuación genera whoami.exe utilizando el módulo child_process. Este módulo activa el proceso Electron para ejecutar su API exportada uv_spawn, responsable de interactuar con el sistema operativo para crear un nuevo proceso.

Hombre mirando una computadora

Fortalezca su inteligencia de seguridad 


Adelántese cada semana a las amenazas con novedades e información sobre seguridad, IA y más con el boletín Think. 


Aplicaciones típicas de Windows frente a aplicaciones Electron

La arquitectura tradicional de una aplicación de Windows consiste en: 

  • Un ejecutable (EXE) que ejecuta la lógica principal del programa.
  • Bibliotecas de enlaces dinámicos (DLL) que proporcionan funcionalidad adicional. 

El EXE llama a las funciones exportadas desde las DLL para ampliar sus capacidades. Sin embargo, las aplicaciones Electron invierten esta arquitectura. En lugar de que el EXE llame a las API desde las DLL, el propio Electron EXE expone las exportaciones de API, que son llamadas por: 

  • Archivos JavaScript de Node.js
  • Módulos de nodo (que funcionan como DLL) 

Esta estructura permite que Node.js y los módulos de nodo interactúen con el sistema operativo de formas que el JavaScript tradicional en un navegador no puede.

En la imagen de abajo examinamos la aplicación Teams Electron usando PE Bear, una herramienta asombrosa creada por @hasherezade, que revela que el ejecutable de Teams Electron contiene 2.977 API exportadas. Esta gran superficie de API proporciona una amplia funcionalidad que los archivos JavaScript de Node.js y los módulos de nodo pueden aprovechar para interactuar con el sistema operativo.

Examen de la aplicación Teams Electron con PE Bear

Ejecución de código JavaScript arbitrario con aplicaciones Electron firmadas

Dado que las aplicaciones Electron ejecutan JavaScript en tiempo de ejecución, la modificación de estos archivos JavaScript permite a los atacantes inyectar código Node.js arbitrario en el proceso de Electron. Al aprovechar las API de Node.js y Chromium, el código JavaScript puede interactuar con el sistema operativo.

No descubrí la capacidad de modificar archivos JavaScript de aplicaciones Electron confiables para ejecutar código JavaScript Node.js arbitrario. Las primeras referencias que puedo encontrar datan de 2022.

A principios de 2022, Andrew Kisliakov publicó el blog "Microsoft Teams and other Electron Apps as LOLbins". Andrew y @mrd0x contribuyeron con sus hallazgos al proyecto LOLBAS.

Más adelante, en 2022, Valentina Palmiotti (@chompie1337), Ellis Springe (@knavesec) y Ruben exploraron este enfoque, lo que llevó al desarrollo de una herramienta de persistencia interna que desde entonces se ha utilizado en operaciones del equipo rojo.

También en 2022, Michael Taggart lanzó el proyecto quASAR, una herramienta diseñada para modificar aplicaciones Electron para permitir la ejecución de comandos. En su blog “Quasar: Compromising Electron Apps”, compartió que en septiembre de 2022, un miembro del proyecto Electron se puso en contacto con él y le dijo que la verificación de integridad era una característica experimental y que, con suerte, sería totalmente compatible en el futuro.

Tras experimentar personalmente con aplicaciones más recientes de Electron como Signal, confirmé que ahora existen comprobaciones de integridad para algunas aplicaciones de Electron que impiden que sus archivos JavaScript sean modificados. Aun así, muchas aplicaciones Electron distribuidas activamente siguen siendo vulnerables.

Esta técnica también se ha observado en ataques del mundo real. En 2022, un actor de amenazas hizo una puerta trasera a la aplicación de chat MiMi modificando sus archivos JavaScript incluidos en el servidor de distribución. Trend Micro identificó esto como un ataque a la cadena de suministro, donde la aplicación Electron comprometida se distribuyó a los usuarios finales, lo que permitió la ejecución de código JavaScript malicioso que descargó y ejecutó una carga útil C2 de segunda etapa.

A la caza de los elusiones de WDAC

En abril de 2024, Yo, Bobby Cooke (@0xBoku) estaba buscando una nueva cadena de ejecución para usar en la preparación de una próxima operación del equipo rojo para un cliente del sector financiero. Este sector tiene estándares de seguridad más altos y regulaciones más estrictas, y a menudo implementa controles de seguridad adicionales como WDAC. Durante mi investigación, me encontré con otra aplicación Electron vulnerable. Sin embargo, dado que no estaba firmado por Microsoft, era poco probable que eludiera la política WDAC del cliente.

Reexploración de la superficie de ataque de Teams

Luego pasé a la aplicación heredada de Microsoft Teams, que está firmada por Microsoft y puede eludir incluso las políticas WDAC más estrictas. En este punto, Dylan Tran (@d_tranman) se unió a mí en esta búsqueda, y comenzamos a buscar una forma de pasar de la ejecución arbitraria de JavaScript en Node.js a la ejecución de nuestro shellcode C2 de etapa 2.

Si bien Node.js puede interactuar con el sistema operativo a través de sus API, carece de la funcionalidad completa de C, donde los desarrolladores pueden llamar directamente a WINAPI y NTAPI. Para cerrar esta brecha, los desarrolladores crearon módulos de nodo, que amplían las capacidades de la infraestructura Node.js. Estos módulos, compilados a partir de código C++, pueden llamar a WINAPI, interactuar con las API de Node.js y ejecutar JavaScript dentro de las aplicaciones Electron. Los módulos de nodo compilados tienen un nodo y se cargan en los procesos de Windows mediante un evento de carga DLL.

Inversión de módulos de nodos firmados

Durante nuestra investigación, examinamos varias aplicaciones Electron y analizamos sus módulos de nodo firmados. Descubrimos que se podía interactuar con estos módulos directamente desde JavaScript, lo que nos permitía aprovechar sus capacidades integradas.

Si bien crear nuestros propios módulos de nodo personalizados para ejecutar shellcode es un enfoque viable y es una capacidad de Loki C2, presenta un problema del huevo y la gallina. La carga de un módulo de nodo desde JavaScript desencadena un evento de carga de DLL, que puede bloquearse mediante políticas de WDAC que aplican reglas estrictas contra DLL sin firmar. Afortunadamente, existe una gran cantidad de módulos de nodo firmados en aplicaciones Electron legítimas.

Este enfoque para ejecutar nuestra carga útil parecía prometedor, por lo que compartimos nuestros hallazgos con Valentina y ella se unió a nosotros en esta búsqueda. Con su ayuda, profundizamos en la reversión de módulos de nodo firmados, buscando vulnerabilidades o capacidades que nos permitan ejecutar código de shell arbitrario.

Aprovechar las capacidades de los módulos de nodo firmados

Un ejemplo de un módulo de nodo con capacidades útiles es windows_process_tree.node, un módulo firmado por Microsoft que se incluye con Visual Studio Code. Cuando se examina en PE Bear, revela dos funciones exportadas, como se ve a continuación.

windows_process_tree.nodo, examinado en PE Bear, revela dos funciones exportadas

A diferencia de las DLL tradicionales, los módulos de nodo no enumeran todas sus funciones disponibles en la tabla de exportación. El proceso Electron llama a la función exportada napi_register_module_v1 y es responsable de cargar el módulo y exponer su funcionalidad exportada al proceso Electron. Esto actúa como un puente, permitiendo que JavaScript dentro del proceso Electron llame e interactúe con las funciones del módulo.

Una forma sencilla de enumerar todas las funciones invocables en un módulo de nodo es aprovechar el código Node.js que se muestra a continuación.

Un código Node.js utilizado para enumerar todas las funciones invocables en un módulo de nodo

Al ejecutar este script Node.js en PowerShell, vemos que hay dos funciones invocables en windows_process_tree.node. Son getProcessList y getProcessCpuUsage.

La ejecución de este script de Node.js en PowerShell revela 2 funciones llamables en windows_process_tree.nodo

Con persistencia, es posible determinar cómo llamar a estas funciones desde JavaScript. Una limitación de Node.js es que carece de una API integrada para enumerar todos los procesos en ejecución en el sistema. Esta limitación es la razón por la que Microsoft introdujo la función getProcessList en este módulo, ampliando las capacidades de la aplicación VS Code Electron.

Es posible recuperar esta información directamente en JavaScript utilizando el módulo child_process para ejecutar PowerShell en un proceso secundario, que devuelve detalles sobre los procesos en ejecución. En la imagen a continuación, Loki C2 genera un proceso secundario de PowerShell para recuperar la lista de procesos.

Loki C2 genera un proceso secundario de PowerShell para recuperar la lista de procesos en JavaScript

Este enfoque presenta importantes riesgos de seguridad operativa. La ejecución de procesos secundarios de PowerShell es altamente detectable y aumenta la probabilidad de que una operación se marque o queme. Para evitar esto, Loki C2 aprovecha módulos de nodo firmados como windows_process_tree.nodo para ampliar las capacidades de Node.js.

Loki C2 incluye el comando ps, que recupera información del proceso cargando el módulo windows_process_tree.nodo firmado por Microsoft y llamando a la función getProcessList, como se ve en la imagen siguiente.

Loki C2 incluye el comando ps, que recupera la información del proceso cargándolo en el módulo windows_process_tree.nodo firmado por Microsoft y llamando a la función getProcessList

A continuación se muestra el código JavaScript de Loki C2 que llama a la función getProcessList en el módulo windows_process_tree.node. getProcessList devuelve datos de procesos en formato JSON, que Loki C2 formatea en una tabla estructurada para mejorar la legibilidad.

Código JavaScript Loki C2 que llama a la función getProcessList en el módulo windows_process_tree.nodo

Determinar cómo llamar correctamente a funciones dentro de los módulos de nodo puede ser complicado, ya que sus estructuras internas no están documentadas. Sin embargo, mediante el uso de herramientas como Ghidra, desarrollada por la NSA, y la colaboración con ingenieros inversos calificados como Valentina, hemos analizado con éxito estos módulos e identificado cómo interactuar con sus funciones.

Descubriendo nuestra primera técnica de ejecución de shellcode

Valentina finalmente descubrió una forma de ejecutar nuestro shellcode C2 de la Etapa 2 sin cargar un archivo DLL sin firmar, pero dejaré que ella revele los detalles. Juntos, Dylan, Valentina y yo trabajamos en refinar la técnica para garantizar la estabilidad de la próxima campaña de phishing.

Lamentablemente, nuestra campaña inicial de phishing por correo electrónico fue denunciada y bloqueada por el Blue Team. Tras este revés, Brett Hawkins (@h4wkst3r) y yo empezamos a preparar una segunda campaña. Como encargado designado de la carga útil, no quería reutilizar la misma carga útil; hacerlo habría facilitado que el Blue Team nos rastreara y detuviera nuestra segunda campaña. Sin embargo, no tuvimos tiempo suficiente para aplicar la técnica de Valentina a una nueva carga útil, así que comencé a desarrollar una nueva carga útil utilizando un enfoque alternativo.

Los albores de Loki C2

Por lo general, la capacidad de ejecutar JavaScript arbitrario en aplicaciones Electron confiables se utiliza para ejecutar comandos que despliegan un agente C2. Sin embargo, sin la técnica de Valentina, este enfoque fallaría contra WDAC, ya que eventualmente requeriría ejecutar un programa sin firmar, que probablemente estaría bloqueado.

Con solo unos días para prepararme para la segunda campaña, pensé: ¿y si construyo una infraestructura C2 completa en JavaScript?

Si el agente C2 en sí estuviera escrito completamente en JavaScript, podría establecer un canal C2 incluso contra las políticas más estrictas de WDAC. Desde allí, se podía realizar reconocimiento para encontrar la forma de desplegar una carga útil C2 de la etapa 2. No habría eventos de carga de DLL sin firmar, solo JavaScript ejecutándose dentro del proceso de Teams de confianza.

Todo lo que necesitábamos era suficiente funcionalidad para: 

  1. Recuperar la política WDAC del sistema de destino
  2. Encontrar exclusiones explotables en la política de WDAC desplegada
  3. Subir la carga útil C2 de la etapa 2
  4. Ejecutar la carga útil C2 de la etapa 2 

Aprovechando todo el código Node.js que había escrito durante mi investigación, elaboré una prueba de concepto C2 de la noche a la mañana. Al día siguiente, se lo mostré a Dylan y, juntos, lo ampliamos rápidamente hasta convertirlo en un C2 totalmente funcional basado en JavaScript. Nuestro C2 fue capaz de: 

  • Carga y descarga de archivos
  • Archivos y directorios de listado
  • Lectura de archivos
  • Ejecución de comandos
  • Carga dinámica de módulos de nodo para capacidades ampliadas 

El JavaScript C2, ahora conocido como Loki C2, fue un éxito en la segunda campaña. Desde entonces, hemos seguido perfeccionando y ampliando Loki C2, añadiendo más características, aumentando la estabilidad y mejorando las capacidades.

Con todo el conocimiento de Electron que obtuve de esta investigación, construí una interfaz gráfica de usuario para Loki C2 utilizando la infraestructura Electron.

Omisión de WDAC con demostración de Loki C2

En el siguiente video, demuestro eludir una estricta política WDAC con Loki C2.  Las dos secciones a continuación explican lo que sucede en el video.

Creación y despliegue de políticas WDAC

Para esta demostración, WDAC se despliega a través de la política de control de aplicación en una instancia EC2 de Windows Server 2025 actualizada en AWS. El asistente proporciona tres plantillas de políticas básicas: 

  1. Modo de Windows predeterminado
  2. Permitir el modo Microsoft
  3. Modo firmado y de buena reputación 

El modo predeterminado de Windows es el más estricto y permite la ejecución de: 

  • Componentes del sistema operativo Windows
  • Aplicaciones de Microsoft Store
  • Office 365, OneDrive, Teams
  • Controladores de kernel firmados por WHQL 

En la demostración, se selecciona la política Modo de Windows predeterminado. El modo de auditoría predeterminado está deshabilitado para que WDAC aplique la política de inmediato. Además, se marcan las opciones Fusionar con listas de bloqueo recomendadas, que incluyen las reglas de la lista de bloqueo WDAC recomendada de Microsoft. El asistente de control de aplicación genera un archivo XML y CIP para la política WDAC, que luego se despliega en el servidor mediante CITool.exe.

Demostración de la elusión de WDAC

Una vez que WDAC está activo, intento ejecutar Loki C2 Agent.exe, pero WDAC lo bloquea, ya que el ejecutable no está firmado por Microsoft.

Para eludir esta restricción, copio el contenido del directorio /recursos/aplicación/ de Loki Agent. En el escritorio hay una carpeta llamada "teams" que contiene una aplicación legítima heredada de Microsoft Teams. Al ver las propiedades de Teams.exe, se confirma que está firmado por Microsoft.

Luego navego hasta el directorio /recursos/ de la aplicación Teams y elimino todos los archivos existentes. Una vez borrado, pego el directorio Loki C2 Agent /recursos/aplicación/ previamente copiado en ~/Escritorio/teams/recursos/aplicación/.

Con esta modificación, ejecuto Teams.exe haciendo clic en él. Dado que el ejecutable de Teams está firmado por Microsoft, WDAC no lo bloquea. En System Informer, podemos ver que el proceso de Teams se crea correctamente sin la intervención de WDAC. Sin embargo, debido a que reemplacé el directorio Teams /recursos/aplicación/ con el código de Loki C2 Agent, la aplicación Teams basada en Electron ahora ejecuta el JavaScript de Loki C2 Agent dentro del proceso de confianza de Teams.

El proceso de Teams devuelve la llamada al cliente Loki C2 y ejecuto varios comandos para demostrar el control remoto del servidor comprometido.

Actualización a un C2 de etapa 2 sigiloso

Después de obtener acceso inicial con Loki C2, identificamos varias formas de ejecutar un agente C2 de etapa 2 más capaz, como Dragon, el C2 interno desarrollado por Shawn Jones (@anthemtotheego) y yo. Si bien todos los diferentes métodos de escalamiento que hemos descubierto desde la creación inicial de Loki C2 no se divulgarán en esta publicación, planeamos cubrirlos en futuras versiones.

Cuando se implementa correctamente, esta técnica continúa eludiendo las soluciones de detección y respuesta de endpoint de primer nivel. Sin embargo, sin un C2 de etapa 2 sigiloso, los operadores deben confiar en la ejecución de comandos a través de spawn, que ejecuta comandos en procesos secundarios. Esto activará rápidamente las detecciones posteriores a la explotación contra los principales EDR.

Mapeo de MITRE ATT&CK

Loki C2 se alinea con la técnica MITRE ATT&CK T1218.011 - Ejecución de proxy binario del sistema: aplicaciones Electron.

Después de buscar en Internet, no encontré esta técnica de vaciar las aplicaciones Electron y reemplazar su código con un C2 divulgado públicamente o utilizado en la naturaleza. Sin embargo, después de compartir Loki C2 con equipos rojos de confianza, uno confirmó que han desarrollado capacidades similares internamente.

Incluso con un TTP de MITRE ATT&CK, múltiples publicaciones de investigación y una entrada LOLBAS, esta técnica de vaciado de aplicaciones Electron en sí misma permanece sin detectar. Supongo que las soluciones de ejecución de la detección y respuesta de endpoints (EDR) no se centran en detectar esto, sino en indicadores posteriores a la explotación, como generar procesos hijos para ejecutar comandos. Dado que hemos desarrollado métodos para desplegar el C2 etapa 2 evitando estas detecciones comunes posteriores a la explotación, hemos utilizado con éxito esta técnica en múltiples interacciones evitando la detección.

Con todo esto en mente, la próxima vez que escuche a un proveedor afirmar "100 % de cobertura MITRE", vale la pena preguntarse qué significa realmente...

Mixture of Experts | 12 de diciembre, episodio 85

Decodificación de la IA: Resumen semanal de noticias

Únase a nuestro panel de ingenieros, investigadores, responsables de producto y otros profesionales de talla mundial que se abren paso entre el revuelo de la IA para ofrecerle las últimas noticias e insights al respecto.

Soluciones relacionadas
IBM Guardium

Proteja sus datos más críticos: descubra, monitoree y proteja la información confidencial en todos los entornos, mientras automatiza el cumplimiento y reduce el riesgo.

Explore IBM Guardium
Soluciones de seguridad empresarial

Transforme su programa de seguridad con las soluciones del mayor proveedor de seguridad empresarial.

    Explore las soluciones de seguridad
    Servicios de Ciberseguridad

    Transforme su negocio y gestione el riesgo con servicios de consultoría de ciberseguridad, nube y seguridad gestionada.

    Explore los servicios de ciberseguridad
    Dé el siguiente paso

    Automatice la protección de datos, la detección de amenazas y el cumplimiento para proteger su empresa en entornos on premises y en la nube.

    1. Explore IBM Guardium
    2. Descubra soluciones de ciberseguridad