
Aplica un enfoque de divide y vencerás para evadir EDRs
Divide and Conquer es un algoritmo que se aplica comúnmente en programación para resolver un problema complejo dividiéndolo en muchos subproblemas más simples. Podemos aplicar este enfoque a la seguridad ofensiva con un objetivo diferente: confundir a los EDR para que pierdan el rastro de nuestras actividades, impidiendo que generen cualquier alerta. Esto es algo similar a lo que se puede ver últimamente en casi cualquier campaña de phishing en la naturaleza: largas cadenas de infección, ejecutando múltiples archivos paso a paso (p. ej. .url -> .one -> .js -> .bat -> .dll) en lugar de ejecutar directamente el payload final. Cada uno de los archivos ejecutados realiza una tarea simple (descargar otro archivo, hacer cualquier cambio en el registro, mover archivos entre directorios o cambiar sus nombres/extensiones, etc.) que es difícil de marcar como maliciosa por sí misma, preparando el entorno para la ejecución final.
Decidí probar esta simple idea pero aplicada a algo diferente, en este caso, una inyección de procesos remotos. El código presentado en este repositorio no es nada nuevo, al contrario, es probablemente una de las formas más comunes y sencillas de inyectar un shellcode en un proceso remoto: hacer uso de NtOpenProcess, NtAllocateVirtualMemory, NtWriteVirtualMemory, NtProtectVirtualMemory y NtCreateThreadEx. La única diferencia es que estoy bifurcando (fork) el proceso usando NtCreateUserProcess después de cada una de esas llamadas. Dado que el proceso bifurcado continúa la ejecución desde RIP + 1 y la memoria se copia por completo del padre, podemos realizar la inyección de procesos remotos pero usando 5 procesos diferentes, solo necesitamos asegurarnos de que cualquier handle requerido para las llamadas API posteriores se herede correctamente.
De esta manera, dividimos el procedimiento de inyección de shellcode en tareas más simples y ejecutamos cada una de ellas en un contexto (proceso) separado.
He probado este PoC contra tres de los EDR más comunes en la actualidad: MDE, CrowdStrike y SentinelOne. Los resultados hablan por sí solos: 2 de 3 EDR generaron una alerta de Remote Process Injection al ejecutar el PoC sin los forks; por el contrario, ninguno de ellos generó ninguna alerta una vez que introduje el mecanismo de fork.
Por supuesto, incluso con el mecanismo de fork podemos ver en la telemetría cruda los eventos correspondientes a la creación de procesos, la creación de hilos y también todo el comportamiento entre procesos (cross process), pero parece que no es suficiente para que los EDR marquen la actividad como maliciosa, lo que demuestra el propósito de este PoC. Al dividir el comportamiento malicioso en tareas más simples y ejecutar cada una de ellas desde un proceso diferente, podemos confundir a los EDR y evitar que generen cualquier alerta.
Este mismo resultado se podría lograr de diferentes maneras; yo solo usé el mecanismo de fork para simplificar mi código y reducir la actividad entre procesos.
Si quieres probar esto por ti mismo, compila el código con y sin las llamadas a la función fork(), y luego ejecuta ambos payloads en un entorno con el EDR deseado.
Dado que estamos usando el plugin LITCRYPT para ofuscar literales de cadena (solo para el código Dinvoke_rs), es necesario configurar la variable de entorno LITCRYPT_ENCRYPT_KEY antes de compilar el código:
C:\Users\User\Desktop\Split> set LITCRYPT_ENCRYPT_KEY="yoursupersecretkey"
Después de eso, simplemente compila el código y ejecuta la herramienta:
C:\Users\User\Desktop\Split> cargo build --release
C:\Users\User\Desktop\Split\target\release> split.exe -h
Esta técnica por sí sola no es suficiente para evadir un EDR; si tu código no es nada opsec, es muy probable que te atrapen de todos modos. Esto no es una bala de plata, solo otra capa de evasión que puedes añadir a tus herramientas. No obstante, el código presentado en este repositorio no es nada opsec por las siguientes razones, entre otras:
Por otro lado, solo he probado este enfoque contra los EDR mencionados, y no sé si otros EDR también serán evadidos. Puedes probarlo y contarme cómo te fue ;)