Instrucciones

Diez técnicas de inyección de procesos: una encuesta técnica sobre técnicas comunes y actuales de inyección de procesos

Nota del editor: Elastic se unió a Endgame en octubre de 2019 y ha migrado parte del contenido del blog de Endgame a elastic.co/es/. Consulta Elastic Security para saber más sobre nuestras soluciones de seguridad integradas.

La inyección de procesos es una técnica de evasión defensiva ampliamente extendida, empleada a menudo en técnicas de malware y adversarios sin archivos, y consiste en ejecutar código personalizado dentro del espacio de direcciones de otro proceso. La inyección por procesos mejora el sigilo y algunas técnicas también logran persistencia. Aunque existen numerosas técnicas de inyección de procesos, en este blog presento diez técnicas que se ven en la naturaleza y que ejecutan código de malware en nombre de otro proceso. Además, proporciono capturas de pantalla de muchas de estas técnicas para facilitar la ingeniería inversa y el análisis de malware, ayudando a la detección y defensa contra estas técnicas comunes.

1. INYECCIÓN TRADICIONAL DE DLL MEDIANTE CREATEREMOTETHREAD Y LOADLIBRARY

Esta técnica es una de las más comunes para inyectar malware en otro proceso. El malware escribe la ruta hacia su biblioteca de enlace dinámico (DLL) maliciosa en el espacio de direcciones virtual de otro proceso, y se cerciora de que el proceso remoto lo cargue creando un hilo remoto en el proceso objetivo.

El malware primero debe dirigir a un proceso para la inyección (por ejemplo, svchost.exe). Esto normalmente se hace buscando entre procesos llamando a un trío de Interfaces de Programa de Aplicación (APIs): CreateToolhelp32Snapshot, Process32First, y Process32Next. CreateToolhelp32Snapshot es una API empleada para enumerar estados de heap o módulo de un proceso especificado o de todos los procesos, y devuelve una snapshot. Process32First recupera información sobre el primer proceso en la snapshot, y luego se emplea Process32Next en un bucle para iterar entre ellos. Tras encontrar el proceso objetivo, el malware obtiene el control del proceso objetivo llamando a OpenProcess.

Como se muestra en la Figura 1, el malware llama a VirtualAllocEx para tener un espacio donde escribir la ruta hacia su DLL. El malware entonces llama a WriteProcessMemory para escribir el camino en la memoria asignada. Finalmente, para que el código se ejecute en otro proceso, el malware llama a APIs como CreateRemoteThread, NtCreateThreadEx o RtlCreateUserThread. Estos dos últimos son indocumentados. Sin embargo, la idea general es pasar la dirección de LoadLibrary a una de estas APIs para que un proceso remoto tenga que ejecutar la DLL en nombre del malware.

CreateRemoteThread es rastreado y marcado por muchos productos de seguridad. Además, requiere una DLL maliciosa en el disco que pueda ser detectada. Teniendo en cuenta que los atacantes suelen inyectar código para evadir defensas, los atacantes más sofisticados probablemente no usarán este método. La captura de pantalla de abajo muestra un malware llamado Rebhip realizando esta técnica.

Figura 1: Gusano rebhip realizando una inyección típica de DLL
Sha256: 07b8f25e7b536f5b6f686c12d04edc37e11347c8acd5c53f98a174723078c365

2. INYECCIÓN EJECUTABLE PORTÁTIL (INYECCIÓN PE)

En lugar de pasar la dirección de la LoadLibrary, el malware puede copiar su código malicioso en un proceso abierto existente y hacer que se ejecute (ya sea mediante un pequeño shellcode o llamando a CreateRemoteThread). Un beneficio de la inyección de PE frente a la técnica LoadLibrary es que el malware no tiene que soltar una DLL maliciosa en el disco. Similar a la primera técnica, el malware asigna memoria en un proceso anfitrión (por ejemplo, VirtualAllocEx), y en lugar de escribir una "ruta DLL" escribe su código malicioso llamando a WriteProcessMemory. Sin embargo, el obstáculo con este enfoque es el cambio de la dirección base de la imagen copiada. Cuando un malware inyecta su PE en otro proceso, tendrá una nueva dirección base que es impredecible, lo que le obligará a recalcular dinámicamente las direcciones fijas de su PE. Para superar esto, el malware necesita encontrar la dirección de su tabla de reubicación en el proceso anfitrión y resolver las direcciones absolutas de la imagen copiada recorriendo en bucle sus descriptores de reubicación.

Esta técnica es similar a otras, como la inyección reflexiva de DLL y el módulo de memoria, ya que no sueltan ningún archivo en el disco. Sin embargo, los enfoques de inyección de módulos de memoria y DLL reflectiva son aún más sigilosos. No dependen de ninguna API adicional de Windows (por ejemplo, CreateRemoteThread o LoadLibrary), porque se cargan y ejecutan solos en la memoria. La inyección de DLL reflectiva funciona creando una DLL que se mapea a la memoria cuando se ejecuta, en lugar de depender del cargador de Windows. El módulo de memoria es similar a la inyección de DLL reflectiva, excepto que el inyector o cargador es responsable de mapear la DLL de destino en memoria en lugar de que la DLL se mapee a sí misma. En una publicación de blog anterior, estos dos enfoques en memoria fueron discutidos extensamente.

Al analizar la inyección de PE, es muy común ver bucles (normalmente dos bucles "for", uno anidado en el otro), antes de una llamada a CreateRemoteThread. Esta técnica es bastante popular entre los encriptadores (programas que cifran y ofuscan malware). En la Figura 2, la prueba unitaria de muestra aprovecha esta técnica. El código tiene dos bucles anidados para ajustar su tabla de reubicación que pueden ver antes de las llamadas a WriteProcessMemory y CreateRemoteThread. La instrucción "y 0x0fff" es otro buen indicador, mostrando que los primeros 12 bits se emplean para obtener el desplazamiento hacia la dirección virtual del bloque de reubicación que lo contiene. Ahora que el malware ha recalculado todas las direcciones necesarias, solo necesita pasar su dirección inicial a CreateRemoteThread y ejecutarlo.

Figura 2: Ejemplo de estructura de los bucles para la inyección de PE antes de las llamadas a CreateRemoteThread
Sha256: ce8d7590182db2e51372a4a04d6a0927a65b2640739f9ec01cfd6c143b1110da

3. AHUECAMIENTO DE PROCESOS (TAMBIÉN CONOCIDO COMO REEMPLAZO Y RUNPE DE PROCESOS)

En lugar de inyectar código en un programa anfitrión (por ejemplo, inyección de DLL), el malware puede realizar una técnica conocida como vaciamiento de procesos. El vaciamiento de procesos ocurre cuando un malware deja de mapear (vacía) el código legítimo de la memoria del proceso objetivo y sobreescribe el espacio de memoria del proceso objetivo (por ejemplo, svchost.exe) con un ejecutable malicioso.

El malware primero crea un nuevo proceso para alojar el código malicioso en modo suspendido. Como se muestra en la Figura 3, esto se hace llamando a CreateProcess y configurando la bandera de creación de procesos a CREATE_SUSPENDED (0x00000004). El hilo principal del nuevo proceso se crea en estado suspendido y no se ejecuta hasta que se llama a la función ResumeThread. A continuación, el malware debe intercambiar el contenido del archivo legítimo por su carga maliciosa. Esto se hace dejando de mapear la memoria del proceso destino llamando a ZwUnmapViewOfSection o NtUnmapViewOfSection. Estas dos APIs básicamente liberan toda la memoria a la que apunta una sección. Ahora que la memoria ya no se mapea, el cargador realiza VirtualAllocEx para asignar nueva memoria para el malware, y emplea WriteProcessMemory para escribir cada sección del malware en el espacio de proceso destino. El malware llama a SetThreadContext para dirigir el punto de entrada a una nueva sección de código que escribió. Al final, el malware reanuda el hilo suspendido llamando a ResumeThread para sacar el proceso del estado suspendido.

Figura 3: Rescate. Cryak realizando el proceso de vaciado
Sha256: eae72d803bf67df22526f50fc7ab84d838efb2865c27aef1a61592b1c520d144

4. SECUESTRO DE EJECUCIÓN DE HILOS (TAMBIÉN CONOCIDO COMO SUSPENDER, INYECTAR Y REANUDAR (SIR))

Esta técnica tiene algunas similitudes con la técnica de vaciado del proceso mencionada anteriormente. En el secuestro de hilos, el malware se dirige a un hilo existente de un proceso y evita cualquier operación ruidosa de proceso o creación de hilos. Por lo tanto, durante el análisis probablemente verás llamadas a CreateToolhelp32Snapshot y Thread32First seguidas de OpenThread.

Tras obtener un handle del hilo objetivo, el malware pone el hilo en modo suspendido llamando a SuspendThread para realizar su inyección. El malware llama a VirtualAllocEx y WriteProcessMemory para asignar memoria y realizar la inyección de código. El código puede contener shellcode, la ruta hacia la DLL maliciosa y la dirección de LoadLibrary.

La Figura 4 ilustra un troyano genérico usando esta técnica. Para secuestrar la ejecución del hilo, el malware modifica el registro EIP (un registro que contiene la dirección de la siguiente instrucción) del hilo objetivo llamando a SetThreadContext. Después, el malware reanuda el hilo para ejecutar el código shell que escribió en el proceso anfitrión. Desde la perspectiva del atacante, el enfoque SIR puede ser problemático porque suspender y reanudar un hilo en medio de una llamada al sistema puede provocar que el sistema se bloquee. Para evitar esto, un malware más sofisticado se reanudaría y lo intentaría más tarde si el registro EIP está dentro del rango de NTDLL.dll.

Figura 4: Un troyano genérico está realizando secuestros de ejecución de hilos
Sha256: 787cbc8a6d1bc58ea169e51e1ad029a637f22560660cc129ab8a099a745bd50e

5. INYECCIÓN DE GANCHO MEDIANTE SETWINDOWSHOOKEX

El enganche es una técnica empleada para interceptar llamadas de función. El malware puede aprovechar la funcionalidad de enganche para que su DLL malicioso se cargue cuando se active un evento en un hilo específico. Esto suele hacer llamando a SetWindowsHookEx para instalar una rutina de gancho en la cadena de gancho. La función SetWindowsHookEx tiene cuatro argumentos. El primer argumento es el tipo de evento. Los eventos reflejan la variedad de tipos de ganchos y varían desde pulsar teclas en el teclado (WH_KEYBOARD) hasta entradas para el mouse (WH_MOUSE), CBT, etc. El segundo argumento es una referencia a la función que el malware quiere invocar al ejecutar el evento. El tercer argumento es un módulo que contiene la función. Por ello, es muy común ver llamadas a LoadLibrary y GetProcAddress antes de llamar a SetWindowsHookEx. El último argumento a esta función es el hilo con el que se asociará el procedimiento del gancho. Si este valor se pone en cero, todos los hilos realizan la acción cuando se activa el evento. Sin embargo, el malware suele dirigir a un hilo para reducir el ruido, por lo que también es posible ver llamadas a CreateToolhelp32Snapshot e Thread32Next antes de SetWindowsHookEx para encontrar y dirigir un único hilo. Una vez que se inyecta el DLL, el malware ejecuta su código malicioso en nombre del proceso por el que su threadId fue transferido a la función SetWindowsHookEx. En la Figura 5, Locky Ransomware implementa esta técnica.

Figura 5: Locky Ransomware usando inyección de gancho
Sha256: 5d6ddb8458ee5ab99f3e7d9a21490ff4e5bc9808e18b9e20b6dc2c5b27927ba1

6. INYECCIÓN Y PERSISTENCIA MEDIANTE MODIFICACIÓN DEL REGISTRO (POR EJEMPLO, APPINIT_DLLS, APPCERTDLLS, IFEO)

Appinit_DLL, AppCertDll e IFEO (Image File Execution Options) son todas claves de registro que el malware emplea tanto para la inyección como para la persistencia. Las inscripciones se encuentran en los siguientes lugares:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls HKLM\System\CurrentControlSet\Control\Control\Session Manager\AppCertDlls HKLM\Software\Microsoft\Windows NT\currentversion\image opciones de ejecución de archivo

AppInit_DLLs

El malware puede insertar la ubicación de su biblioteca maliciosa bajo la clave de registro Appinit_Dlls para que otro proceso cargue su biblioteca. Cada biblioteca bajo esta clave de registro se carga en cada proceso que carga User32.dll. User32.dll es una biblioteca muy común empleada para almacenar elementos gráficos como cuadros de diálogo. Así, cuando un malware modifica esta subclave, la mayoría de los procesos cargarán la biblioteca maliciosa. La Figura 6 muestra al troyano Ginwui que se basa en este enfoque para la inyección y la persistencia. Simplemente abre la clave del registro Appinit_Dlls llamando a RegCreateKeyEx y modifica sus valores llamando a RegSetValueEx.

Figura 6: Ginwui modificando la clave del registro de AppIniti_DLLs
Sha256: 9f10ec2786a10971eddc919a5e87a927c652e1655ddbbae72d376856d30fa27c

AppCertDlls

Este enfoque es muy similar al AppInit_DLLs, salvo que las DLL bajo esta clave de registro se cargan en cada proceso que llama a las funciones de la API de Win32 CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW y WinExec.

Opciones de ejecución de archivo de imagen (IFEO)

IFEO se emplea típicamente para fines de depuración. Los desarrolladores pueden establecer el "Valor de depuración" bajo esta clave de registro para anexar un programa a otro ejecutable para la depuración. Por lo tanto, cada vez que se lanza el ejecutable, se lanzará el programa que se le anexa. Para usar esta función puedes simplemente indicar la ruta al depurador y anexarla al ejecutable que quieres analizar. El malware puede modificar esta clave de registro para inyectar en el ejecutable objetivo. En la Figura 7, el troyano Diztakun implementa esta técnica modificando el valor del depurador del Administrador de Tareas.

Figura 7: Troyano Diztakun modificando la clave de registro IFEO
Sha256: f0089056fc6a314713077273c5910f878813fa750f801dfca4ae7e9d7578a148

7. INYECCIÓN DE APC Y BOMBARDEO ATÓMICO

El malware puede aprovechar las Llamadas a Procedimientos Asíncronas (APC) para forzar que otro hilo ejecute su código personalizado anexándolo a la cola APC del hilo destino. Cada hilo tiene una cola de APCs que esperan a ser ejecutados cuando el hilo destino entra en estado alterable. Un hilo entra en un estado de alerta si llama a las funciones SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx o WaitForSingleObjectEx. El malware suele buscar cualquier hilo que esté en un estado alterable y luego llama a OpenThread y QueueUserAPC para poner un APC en cola en un hilo. QueueUserAPC toma tres argumentos: 1) un handle para el hilo de destino; 2) un puntero a la función que el malware quiere ejecutar; 3) y el parámetro que se pasa al puntero de función. En la Figura 8, el malware Amanahe primero llama a OpenThread para adquirir un handle de otro hilo, y luego llama a QueueUserAPC con LoadLibraryA como puntero de función para inyectar su DLL maliciosa en otro hilo.

El AtomBombing es una técnica que fue introducida por primera vez por la investigación de enSilo y luego empleada en Dridex V4. Como comentamos en detalle en una publicación de blog anterior, la técnica también se basa en la inyección de APC. Sin embargo, emplea tablas de átomos para escribir en memoria otro proceso.

Figura 8: Almanahe realizando la inyección de APC
Sha256: f74399cc0be275376dad23151e3d0c2e2a1c966e6db6a695a05ec1a30551c0ad

8. INYECCIÓN EXTRA DE MEMORIA DE VENTANAS (EWMI) MEDIANTE SETWINDOWLONG

EWMI depende de inyectar en la memoria extra de la ventana de la bandeja del Explorador, y se empleó varias veces entre familias de malware como Gapz y PowerLoader. Al registrar una clase ventana, una aplicación puede especificar un número adicional de bytes de memoria, llamado memoria extra de ventana (EWM). Sin embargo, no hay mucho espacio en EWM. Para evitar esta limitación, el malware escribe código en una sección compartida de explorer.exe y emplea SetWindowLong y SendNotifyMessage para tener un puntero de función que apunta al shellcode y luego lo ejecuta.

El malware tiene dos opciones a la hora de escribir en una sección compartida. Puede crear una sección compartida y mapearse tanto a sí misma como a otro proceso (por ejemplo, explorer.exe), o simplemente puede abrir una sección compartida que ya existe. El primero tiene la sobrecarga de asignar espacio en el montón y llamar a NTMapViewOfSection además de algunas otras llamadas a la API, por lo que el segundo enfoque se emplea con más frecuencia. Después de que el malware escribe su código shell en una sección compartida, emplea GetWindowLong y SetWindowLong para acceder y modificar la memoria extra de ventana de "Shell_TrayWnd". GetWindowLong es una API empleada para recuperar el valor de 32 bits en el desplazamiento especificado en la memoria de ventana extra de un objeto de clase ventana, y SetWindowLong se usa para cambiar valores en el desplazamiento especificado. De este modo, el malware puede simplemente cambiar el desplazamiento de un puntero de función en la clase ventana y apuntarlo al código de shell escrito en la sección compartida.

Al igual que la mayoría de las otras técnicas mencionadas anteriormente, el malware necesita ejecutar el código que ha escrito. En las técnicas analizadas anteriormente, el malware lograba esto llamando a interfaces de programación de aplicaciones (API) como CreateRemoteThread, QueueUserAPC o SetThreadContext. Con este enfoque, el malware activa el código inyectado llamando a SendNotifyMessage. Al ejecutar SendNotifyMessage, Shell_TrayWnd recibe y transfiere el control a la dirección apuntando por el valor previamente establecido por SetWindowLong. En la Figura 9, un malware llamado PowerLoader emplea esta técnica.

Figura 9: PowerLoader inyectando en memoria adicional de ventana de bandeja de shell
Sha256: 5e56a3c4d4c304ee6278df0b32afb62bd0d01e2a9894ad007f4cc5f873ab5cf

9. INYECCIÓN USANDO CUÑAS

Microsoft proporciona Shims a los desarrolladores principalmente para compatibilidad hacia atrás. Las cuñas permiten a los desarrolladores aplicar correcciones a sus programas sin necesidad de reescribir el código. Aprovechando las cuñas, los desarrolladores pueden indicar al sistema operativo cómo manejar su aplicación. Las cuñas son esencialmente una forma de conectarse a APIs y dirigir a ejecutables específicos. El malware puede aprovechar las cuñas para apuntar a un ejecutable tanto para persistencia como para inyección. Windows ejecuta el Motor de Shim cuando carga un binario para comprobar si hay bases de datos de shimming y así aplicar las correcciones adecuadas.

Hay muchas correcciones que se pueden aplicar, pero las favoritas del malware son las que tienen algo de seguridad (por ejemplo, DisableNX, DisableSEH, InjectDLL, etc.). Para instalar una base de datos de shimming, el malware puede desplegar varios métodos. Por ejemplo, un enfoque común es simplemente ejecutar sdbinst.exe y apuntarlo al archivo sdb malicioso. En la Figura 10, un adware, "Search Protect by Conduit", emplea una cuña para persistencia e inyección. Realiza una cuña "InjectDLL" en Google Chrome para cargar vc32loader.dll. Existen algunas herramientas para analizar archivos sdb, pero para el análisis de los sdb que se mencionan a continuación, empleé python-sdb.

Figura 10: SDB empleado por Search Protect para fines de inyección
Sha256:


6d5048baf2c3bba85adc9ac5ffd96b21c9a27d76003c4aa657157978