Inyección reflejada de DLLs en Windows

Normalmente cuando se carga una DLL en Windows se llama a la función LoadLibrary, que toma la ruta del archivo de la DLL y la carga en la memoria. Sin embargo, existe una técnica que permite a un atacante inyectar una librería en un proceso remoto (víctima) desde la memoria en lugar de desde disco, una forma más sigilosa de ejecutar código malicioso: hablamos de la inyección reflejada de DLLs o, en inglés, "reflective DLL loading".

No obstante, Windows no tiene una función como LoadLibrary para llevarlo a cabo, así que para obtener la funcionalidad tendremos que escribirla nosotros mismos.

Implementando la técnica

La técnica más común para inyectar DLLs de una forma reflejada, bien documentada por el irlandés Stephen Fewer, es doble. En primer lugar, la DLL que queremos inyectar debe estar escrita en el espacio de direcciones del proceso de destino/host. En segundo lugar, la DLL debe cargarse en ese proceso host de tal manera que se cumplan todos los requisitos de tiempo de ejecución de la librería, como resolver sus importaciones o reubicarlas en una ubicación adecuada en la memoria.

Suponiendo que tenemos ejecución de código en el proceso del host y que la librería que deseamos inyectar se ha escrito en una ubicación arbitraria de la memoria en el proceso del host, la inyección reflejada de DLLs funciona de la siguiente manera:

- La ejecución se pasa, ya sea a través de CreateRemoteThread(), una función de API no documentada equivalente como RtlCreateUserThread o un pequeño shellcode bootstrap, a la función ReflectiveLoader de la librería, que es una función exportada que se encuentra en la tabla de exportación de la librería.
- Como la imagen de la librería existirá actualmente en una ubicación arbitraria en la memoria, ReflectiveLoader primero calculará la ubicación actual de su propia imagen en la memoria para poder analizar sus propios headers para su uso posterior.
- ReflectiveLoader luego analizará la tabla de exportación de los procesos del host kernel32.dll para calcular las direcciones de las tres funciones requeridas por el cargador, a saber, LoadLibraryA, GetProcAddress y VirtualAlloc.
- ReflectiveLoader ahora asignará una región continua de memoria en la que procederá a cargar su propia imagen. La ubicación no es importante ya que el cargador re-ubicará correctamente la imagen más adelante.
- Los headers y las secciones de la librería se cargarán en sus nuevas ubicaciones en la memoria.
- ReflectiveLoader procesará la copia recién cargada de la tabla de importación de su imagen, cargando las librerías adicionales y resolviendo sus respectivas direcciones de función importadas.
- ReflectiveLoader procesará la copia recién cargada de la tabla de reubicación de su imagen.
- ReflectiveLoader llamará a la función de punto de entrada de su imagen recién cargada, DllMain con DLL_PROCESS_ATTACH. La librería ahora se habrá cargado con éxito en la memoria.
- Finalmente, ReflectiveLoader devolverá la ejecución al shellcode inicial que lo llamó, o si fue llamado a través de CreateRemoteThread, el hilo terminará.

* Si queréis ver código C/C++ para implementar muchas de las funciones necesarias os aconsejo que echéis un vistazo al post de 0x00Sec aquí.

Reflective dll inject en Metasploit

Asumimos que el atacante ya ha obtenido una shell de meterpreter en el sistema víctima y ahora intentará realizar una inyección reflexiva de DLL en un proceso remoto, más específicamente en un proceso notepad.exe con PID 6156.

El módulo de post-explotación de Metasploit windows/manage/reflective_dll_inject configurado:


* Reflective_dll.x64.dll es la DLL compilada del repo de Steven Fewer en github.

Después de ejecutar el módulo de post-explotación, notepad.exe ejecutará el payload malicioso que proviene de una DLL reflejada que se envió desde el sistema del atacante:


También podemos verlo en acción en el siguiente vídeo:


Otras técnicas

Sin embargo, en el intento de evadir AV, los atacantes hacen todo lo posible para evitar la función de ejecución del código de inyección reflexivo común, CreateRemoteThread(). Las técnicas alternativas incluyen la creación de subprocesos de API nativa (ntdll) y APC de usuario (necesarios para SysWow64-> x64), etc.
En este contexto, zerosum0x0 publicó una técnica que utiliza SetThreadContext() para cambiar los registros de un threat seleccionado, y realiza un proceso de restauración con NtContinue(). Esto significa que el threat secuestrado puede seguir haciendo lo que estaba haciendo, lo que puede ser una función crítica de la aplicación inyectada.


En el repo de zerosum0x0 hay una PoC para x64 que usa las funciones comunes VirtualAllocEx() y WriteVirtualMemory(). Pero en lugar de crear un nuevo subproceso remoto, usa uno ya existente y restaura el contexto original cuando termina con él. Esto se puede hacer localmente (proceso actual) y de forma remota (proceso objetivo).

Detectando inyecciones reflejadas de DLLs

Malfind es el complemento de Volatility responsable de encontrar varios tipos de inyección de código y, por lo general, pueden detectarse inyecciones reflejadas de DLL con la ayuda de este complemento.

El complemento, a alto nivel, escaneará varias regiones de memoria descritas por Virtual Address Descriptors (VAD) y buscará cualquier región con protección de memoria PAGE_EXECUTE_READWRITE y luego buscará los bytes mágicos 4d5a (MZ en ASCII) al comienzo de esas regiones (como sabéis, esos bytes significan el inicio de un ejecutable de Windows, es decir, exe, dll):

volatility -f /mnt/memdumps/w7-reflective-dll.bin malfind --profile Win7SP1x64


 Más recursos y fuentes:

- stephenfewer/ReflectiveDLLInjection
- Red Teaming Experiments - Reflective DLL Injection
- ThreadContinue - Reflective DLL Injection Using SetThreadContext() and NtContinue()
- zerosum0x0/ThreadContinue
- Reflective DLL Injection 0x00sec 
- What is Reflective DLL Injection and how can be detected?
- Detecting reflective DLL loading with Windows Defender ATP 
- Reflective Injection Detection – RID.py
- sRDI – Shellcode Reflective DLL Injection
- Reflective DLLs and You
- An Improved Reflective DLL Injection Technique
- Reflective DLL Injection with PowerShell

Comentarios

  1. la verdad quisiera aprender con un poco mas de destalles porque no entiendo ni mierda.

    ResponderEliminar

Publicar un comentario