Silenciando a los silenciadores de EDR

Como muchos profesionales de seguridad saben, manipular productos de Detección y respuesta para endpoints (EDR) es un deseo profundo tanto para los actores de amenazas como para los red teamers. Hablé de esto brevemente en BlackHat este año en mi charla en el stand de Huntress, "EDR Blinded, Now What?".

__wf_reserved_inherit
Hablando en BlackHat. Crédito de foto a mi gemelo John Hammond.

En una de las diapositivas, hablé sobre cómo una de las formas más comunes de "cegar" los EDR es aplicar reglas de firewall contra las aplicaciones EDR deseadas. Esta técnica es única en el sentido de que un atacante no necesita acceder directamente a la aplicación de un EDR (abrir un handle al proceso o archivo). En cambio, altera la capacidad de la aplicación para comunicarse hacia afuera con su servidor, y también altera la capacidad del servidor para comunicarse hacia adentro con la aplicación. Entonces, aunque el EDR puede recopilar telemetría de una acción, esas acciones no se envían para detecciones o investigaciones. En este blog, tocaré esta técnica y hablaré de cómo los productos pueden protegerse de este ataque.

Mecanismos de bloqueo 

Mientras discutimos las distintas formas de bloquear las comunicaciones de red de una aplicación, hay dos formas que vienen a la mente como las más comunes hoy en día:

  1. Crear reglas de Windows Defender Firewall con seguridad avanzada
  2. Crear reglas de Windows Filtering Platform (WFP) 

Esto podría sonar repetitivo porque, en parte, lo es. Eso se debe a que el firewall integrado de Windows Defender aprovecha Windows Filtering Platform para hacer cumplir sus reglas. Sin embargo, lo menciono porque, como veremos más adelante, tenemos que ajustar la solución, ya que, según cómo interactúes con cada función, la configuración se guarda en lugares distintos.

Nota: Antes de continuar, es importante aclarar que solo veremos las capacidades predeterminadas del firewall de Windows, no las de terceros. Este blog también se enfoca únicamente en cuando las reglas de firewall se configuran mediante Windows Firewall o WFP.

Windows FirewallI

El Windows Firewall tiene la capacidad de crear reglas personalizadas que permiten o no permiten que una aplicación se comunique a través de la red. Tanto de entrada como de salida. No hay restricciones sobre qué procesos pueden ser el objetivo de estas reglas de firewall, así que, siempre que un atacante tenga derechos de administrador local, puede agregar con éxito un agente EDR a la regla de firewall y bloquear las conexiones de red. La mayoría de las personas probablemente hayan visto la siguiente página relacionada con Windows Firewall:

Figura 1: Ventana de Windows Defender Firewall con seguridad avanzada

También existe una herramienta integrada fácil de usar para crear reglas de firewall llamada netsh:

Figura 2: netsh advfirewall ejemplo

Para algo más personalizado, alguien podría aprovechar las interfaces COM INetFwRule y INetFwRules. Los usuarios pueden implementar esto ellos mismos con bastante facilidad. Una herramienta conocida que hace esto es EDRSandblast, que eventualmente aprovecha el método Add en la interfaz COM INetFwRules para crear una nueva regla de firewall contra un binario de EDR conocido.

Figura 3: EDRSandblast ejemplo de creación de firewall

Ahora, vale la pena notar que, con el antivirus de Windows activado, Defender sí bloquea la creación de reglas de firewall contra MsMpEng.exe. Sin embargo, el punto clave es que esto se puede hacer contra cualquier EDR, y si no están monitoreando, las comunicaciones de red se cortarán. Cuando se crean estas reglas de firewall, en realidad se almacenan en el registro bajo:

HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\{GUID}

{GUID} representa la regla de firewall. Esto se almacena como un valor REG_SZ donde los datos contienen la información sobre la regla:

v2.32|Action=Block|Active=TRUE|Dir=In|App={application-path}|Name={firewall-rule-name}|Desc={firewall-rule-name}|

Veamos las partes más importantes de esta regla:

  • Action - la acción de firewall a tomar (permitir o bloquear)
  • Active - si la regla de firewall está actualmente activa o no
  • Dir - dirección para permitir o denegar la comunicación, ya sea de entrada (In) o de salida (Out)
  • App - la aplicación a bloquear o permitir
  • Name - nombre de la regla de firewall
  • Desc (opcional) - descripción del firewall

Hay otras banderas opcionales que también se pueden incluir en la cadena. Las tres etiquetas más importantes aquí son Action, Dir y App.

Entonces, antes de avanzar hacia el WFP, recordemos la clave del registro HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\{GUID}. Esto será útil más adelante cuando hablemos de soluciones.

Windows Filtering Platform (WFP)

El Windows Firewall utiliza la Windows Filtering Platform para aplicar sus reglas. Aquí no profundizaremos en los detalles internos de la WFP, simplemente porque creemos que muchos otros investigadores ya lo han hecho muy bien. De hecho, estos son excelentes recursos:

Interactuar con la WFP es mucho más sencillo porque existen API directas que podemos aprovechar. Puedes encontrar una lista de las API de WFP aquí. Para crear un filtro WFP, la API que se necesita es FwpmFilterAdd0. Muchos de los que leen este blog probablemente hayan oído hablar de EDRSilencer. Esta función se aprovecha para crear un filtro WFP tanto para direcciones IPv4 como IPv6. Cuando se aplican estas reglas, deben existir dos cosas:

  • Un proveedor: un proveedor de políticas que se usa para la gestión del filtro
  • Un filtro (entrante y saliente): una regla que, si se cumplen las condiciones, ejecuta las acciones especificadas 

Existen cuatro tipos de filtros en tiempo de ejecución con los que los usuarios pueden interactuar. Dinámico, Estático, Persistente y Integrado. Los más valiosos para un atacante son los filtros persistentes, ya que permanecen activos hasta que se eliminan. Cuando se configuran los filtros, se almacenan en el registro al igual que las reglas de firewall, solo que en una ubicación distinta:

Figura 4: salida de Procmon mostrando la configuración de filtros WFP y del proveedor

Cada proveedor y filtro se almacena como un valor {GUID}, y los datos del filtro se guardan como un arreglo de bytes (REG_BINARY).

Figura 5: ejemplo de arreglo de bytes de un filtro WFP

Esto puede hacer que analizar estos datos sea un poco más difícil que con las reglas de firewall anteriores, simplemente porque no es un valor de cadena simple. Sin embargo, una forma sencilla de interactuar con los filtros es mediante el cmdlet de PowerShell Get-FwFilter . Por ejemplo, puedes obtener información sobre un filtro mediante el cmdlet Get-FwFilter si tienes el FilterId o el FilterKey:

FilterID
Loading Gist...
FilterKey
Loading Gist...

Esta es una gran opción si tienes curiosidad sobre qué está haciendo un filtro específico en tu máquina. Ahora, ¡veamos cómo evitar que esto ocurra contra una aplicación EDR!

Solución 

Hemos identificado que tanto las reglas de firewall como los filtros WFP terminan configurándose en el registro. Esto es excelente para quien busca detectar esta actividad, ya que existen varias formas de monitorear el registro. Nos gustaría proponer dos enfoques que un producto podría adoptar si quiere detener esta técnica de manipulación de raíz: Prevención e Eliminación inmediata.

Prevención

Los productos pueden prevenirlo aprovechando una rutina de pre-callback para RegSetValue (RegNtPreSetValueKey). Si un producto tiene acceso al kernel mediante un driver, puede aprovechar RegNtPreSetValueKey para recibir notificaciones cada vez que se realiza una operación de configuración de valor en el registro. Al hacerlo, podría analizar la ruta del registro y los datos que se están configurando, y si coinciden, podría devolver STATUS_ACCESS_DENIED para evitar que se configure esa clave. Una implementación exitosa se vería algo así:

Figura 6: EDRSandblast fallando al crear reglas de firewall

Puedes ver que las reglas de firewall no se crean con éxito porque se bloquean mediante la notificación de pre-callback del registro RegNtPreSetValueKey. Esto funciona muy bien desde el punto de vista de la prevención, pero, honestamente, no siempre creo que sea buena idea analizar o procesar datos en el kernel a menos que sea realmente liviano. Y aunque esto funciona bien para las reglas de firewall, esos datos se almacenan como un valor de cadena, mientras que los filtros WFP se almacenan como un arreglo de bytes. Al igual que con las reglas de firewall mencionadas arriba, esto no debería procesarse/analizarse en el kernel.

Eliminación inmediata

La metodología de "eliminación inmediata" es similar al método anterior, excepto que técnicamente permites que la acción no deseada ocurra antes de hacer algo al respecto. Esto se puede lograr monitoreando estas operaciones de configuración de valores del registro mediante un post-callback (RegNtPostSetValueKey). Este callback se notifica una vez que la acción ya ocurrió en el registro. Ahora bien, alguien podría procesar/analizar estos datos en el kernel y encargarse de ellos, pero recomiendo almacenar los datos del post-callback y enviarlos a un agente en modo usuario para que se encargue del análisis y procesamiento. La figura 7 muestra una arquitectura de muy alto nivel de cómo se puede hacer esto. Hay muchas formas de hacerlo, y esta no es la única manera correcta, pero así es como lo hice cuando creé la prueba de concepto dentro de JonMon.

Figura 7: Arquitectura básica de EDR para el post-callback del registro

Una vez que los datos se envían con éxito al agente en modo usuario y se analizan, el agente puede eliminar las reglas de forma segura. No puedes simplemente borrar las claves del registro porque las reglas/filtros no se restablecen de inmediato. En cambio, debes eliminarlas de modo que el motor de filtrado se actualice después de la eliminación. Podrías borrar la clave del registro, pero tendrías que reiniciar el equipo. Obviamente, este enfoque no es una opción adecuada, ya que los productos quieren hacer modificaciones durante el tiempo de ejecución. Sin embargo, hay algunas opciones eficaces para lograrlo. Para las reglas de firewall, aproveché COM para hacer esto:

Figura 8: Ejemplo de código para INetFwRules::Remove

Validé que el valor del registro contenía la política de firewall no deseada y usé el método INetFwRules Remove para eliminar la política de firewall. La figura 9 muestra cómo se ve después de la implementación:

Figura 9: Ejemplo de reglas de firewall maliciosas eliminadas en tiempo real

Puedes ver que las reglas se crearon con éxito, pero se eliminaron de inmediato, dejando inútil la técnica de manipulación.

Para los filtros y proveedores dentro del WFP, aproveché la función FwpmFilterDeleteById0 para eliminar el filtro y la función FwpmProviderDeleteByKey0 para eliminar el proveedor.

Figura 10: Ejemplo de código para eliminar filtros y proveedores maliciosos de WFP

Después de implementar esto, podemos ver que los filtros y proveedores creados por EDRSilencer se eliminaron con éxito:

Figura 11: Ejemplo de filtros WFP maliciosos eliminados en tiempo real

Aunque este método podría no estar "previniendo" que se escriban las reglas, es igual de eficaz. El producto no necesita analizar y procesar estos datos en el kernel, y la eliminación es casi inmediata. Por último, no tienes que usar los callbacks del registro, ya que el WFP tiene el evento de seguridad 5447 que indica cuándo se crea una nueva regla. Alguien podría monitorear eso y realizar las mismas acciones anteriores para eliminar esa regla.

Conclusión

La manipulación de EDR es un tema muy candente, y veo que mucha gente habla de aprovechar las políticas de firewall y los filtros WFP para cegar los EDR. Está claro que es muy eficaz. También es particular, ya que el atacante no tiene que interactuar directamente con los procesos del EDR. Todavía no he visto a nadie profundizar en cómo detener o mitigar esta técnica de manipulación, así que quise ofrecer algunas soluciones posibles. Espero que esto te ayude a entender mejor esta técnica de manipulación y cómo mitigarla.

¿Quieres profundizar en más técnicas de atacantes? ¡Únete a Tradecraft Tuesday! Sin productos, sin ventas, solo tradecraft.

También te podría interesar