Descripción general
Gootloader es un cargador de malware sofisticado basado en JavaScript que los actores de amenazas suelen usar para obtener acceso inicial. Este malware normalmente se entrega cuando los usuarios visitan sitios web comprometidos, y los actores de amenazas aprovechan el SEO poisoning para dirigir tráfico a estos sitios. El cargador usa payloads de JavaScript muy ofuscados para facilitar la entrega de payloads adicionales y ha estado activo desde 2020. Tras un período de menor actividad, las operaciones de Gootloader resurgieron brevemente en marzo de 2025 antes de volver a quedar en silencio, solo para regresar recientemente con actividad renovada. Se sabe que Gootloader lo usa el actor de amenazas identificado como Storm-0494 por MSTIC. Storm-0494 luego otorga acceso desde infecciones de Gootloader a Vanilla Tempest (anteriormente identificado como DEV-0832). Vanilla Tempest ha estado activo desde 2022 y entrega distintas familias de ransomware, incluyendo Rhysida (comúnmente observado en actividad posterior a la intrusión de Gootloader), BlackCat, Zeppelin y Quantum Locker.
Desde el 27 de octubre, Huntress ha observado tres infecciones de Gootloader, incluidas dos que derivaron en intrusiones manuales con compromiso del controlador de dominio ocurrido en menos de 17 horas desde la infección inicial.
Puntos clave
- Gootloader está de vuelta y ahora aprovecha fuentes WOFF2 personalizadas con sustitución de glifos para ofuscar los nombres de archivo
- Explota los endpoints de comentarios de WordPress para entregar payloads ZIP cifrados con XOR con claves únicas por archivo
- Pasó de tareas programadas a un mecanismo de persistencia en la carpeta de inicio y sigue usando nombres de archivo cortos 8.3 de Windows
- Supper SOCKS5 Backdoor, la herramienta preferida de Vanilla Tempest, contiene una ofuscación extensa: API hammering, construcción de shellcode en tiempo de ejecución, cálculo de resúmenes criptográficos de API y compresión LZMA personalizada de 2 bytes
- El reconocimiento comienza en menos de 20 minutos desde la infección inicial, y el compromiso del controlador de dominio se logra en tan solo 17 horas mediante patrones de ataque predecibles: enumeración de AD (Kerberoasting, escaneo de SPN), movimiento lateral vía WinRM, creación de cuentas de administrador de dominio y posible preparación de ransomware (enumeración de Volume Shadow Copy)
- Según las observaciones de @DFIRReport, el movimiento lateral hacia el controlador de dominio ocurrió dentro de la primera hora tras la ejecución inicial de JavaScript
¿Cómo ocurrió?
El usuario buscaba “missouri cover utility easement roadway” en Bing y visitó la primera página que apareció en los resultados.
Figura 1: Sitio comprometido que entrega el payload de Gootloader
El cargador abusa del endpoint de envío de comentarios de WordPress (/wp-comments-post.php) para entregar payloads cifrados. Cuando un usuario hace clic en "Download" junto a uno de los cinco payloads disponibles, el JavaScript malicioso envía una solicitud POST a /wp-comments-post.php con el parámetro comment_post_ID={document_id}. El usuario ve una ventana emergente convincente que muestra un indicador de progreso de descarga (que se ve en la Figura 2 a continuación), mientras el sitio entrega un archivo ZIP cifrado con XOR. La clave de descifrado XOR está codificada directamente en el código fuente de la página y corresponde al nombre de archivo con extensión del payload seleccionado (por ejemplo, Missouri_Utility_Easement_Guide_2023.pdf). Cada uno de los cinco payloads usa una clave XOR única basada en su respectivo nombre de archivo.
Figura 2: Cadena de infección de Gootloader
Figura 3: Ventana emergente de descarga de archivo
El código de descifrado XOR:
Una de las observaciones interesantes es que Gootloader usa una fuente web personalizada para ofuscar los nombres de archivo. Entonces, cuando el usuario intenta copiar el nombre del archivo o inspeccionar el código fuente, verá caracteres extraños como ‛›μI€vSO₽*'Oaμ==€‚‚33O%33‚€×:O[TM€v3cwv,. Sin embargo, cuando se renderizan en el navegador de la víctima, esos mismos caracteres se transforman mágicamente en texto perfectamente legible como Florida_HOA_Committee_Meeting_Guide.pdf. Esto se logra mediante un archivo de fuente WOFF2 personalizado que Gootloader incrusta directamente en el código JavaScript de la página usando codificación Z85, una variante de Base85 que comprime la fuente de 32 KB en 40 K.
En lugar de usar funciones de sustitución OpenType o tablas de mapeo de caracteres, el cargador intercambia lo que realmente muestra cada glifo. Los metadatos de la fuente parecen totalmente legítimos: el carácter “O” se asigna a un glifo llamado "O", el carácter “a” se asigna a un glifo llamado "a", y así sucesivamente. Sin embargo, las rutas vectoriales reales que definen esos glifos se han intercambiado. Cuando el navegador solicita la forma del glifo "O", la fuente entrega las coordenadas vectoriales que dibujan la letra "F" en su lugar. De manera similar, "a" dibuja "l", "9" dibuja "o", y caracteres Unicode especiales como "±" dibujan "i". La cadena sin sentido Oa9Z±h• en el código fuente se renderiza como "Florida" en la pantalla.
Esta técnica burla los métodos de análisis estático. Las búsquedas de cadenas con palabras clave como "invoice" o "contract" no devuelven nada porque esas palabras no existen en el código fuente.
Figura 4: Visualización legible del nombre de archivo frente a los caracteres reales del código fuente
Este archivo JavaScript se hace pasar por jQuery v3.0.0 mientras incrusta código malicioso muy ofuscado en muchos fragmentos de cadenas con ruido; pequeñas funciones auxiliares cortan y reensamblan esos fragmentos usando matemática de índices y bucles inversos, luego ejecutan transformaciones de cadenas predecibles y reversibles (unescape/replace, reordenamiento/inversión de fragmentos, pequeños mapas de caracteres o correcciones de desplazamiento de bytes, y matemática de índices) para reconstruir un blob de JavaScript de segunda etapa.
Figura 5: Fragmento del archivo JavaScript que contiene el fragmento del código malicioso
Si bien el script proporcionado por Mandiant no logró extraer los dominios, mediante la desofuscación del payload de múltiples capas pudimos producir un script de PowerShell de segunda etapa legible y extraer los diez dominios de C2 (Figura 5). Un contenedor VBScript inicial dentro del script realiza una detección del entorno de ejecución al verificar si se está ejecutando bajo wscript.exe o cscript.exe mediante la propiedad WScript.FullName. Cuando se ejecuta bajo wscript.exe (el valor predeterminado para archivos VBScript ejecutados con doble clic), el contenedor crea un objeto WScript.Shell y usa el método Exec() para lanzar PowerShell con el comando "powershell & powershell" (En 2022, Gootloader lanzó PowerShell con el comando “pOWErsHELl”). Aunque el operador de ampersand (&) encadena dos comandos, solo la primera instancia de PowerShell recibe y ejecuta realmente los comandos descritos a continuación.
El script exfiltra todas las variables de entorno cuyos valores tengan 99 caracteres o menos, capturadas mediante (Get-ChildItem env:*).Where({$_.value -match "^.{0,99}$"}). Este límite de 99 caracteres parece estar diseñado para evitar variables PATH extremadamente largas, mientras sigue capturando datos confidenciales como USERNAME, COMPUTERNAME y APPDATA. Luego se agrega el nombre del sistema operativo usando Get-CimInstance Win32_OperatingSystem.
Además de las variables de entorno, el script enumera todos los procesos en ejecución y busca específicamente procesos con ventanas de GUI visibles. Para extraer los títulos de las ventanas, convierte cada objeto de proceso a formato CSV usando ConvertTo-Csv, y luego analiza el campo 26, que corresponde a la propiedad MainWindowTitle en la serialización del objeto Process de PowerShell. Esto revela en qué está trabajando activamente el usuario: documentos abiertos, sitios web, aplicaciones, lo que potencialmente expone nombres de documentos confidenciales o credenciales visibles en los títulos de las ventanas. El script también usa el objeto COM Shell.Application para enumerar los archivos del escritorio, clasificando cada uno como enlace, carpeta o archivo, e inventaría todas las unidades montadas con más de 50 KB de espacio libre para identificar ubicaciones de almacenamiento viables para alojar payloads adicionales.
Los datos recopilados pasan por una codificación de varias etapas en la que cada resultado de reconocimiento se comprime de forma independiente usando GZipStream, y luego se envuelve con marcadores binarios personalizados: un encabezado de 6 bytes [235,154,216,67,95,5] y un pie de 6 bytes [5,135,37,102,109,114], antes de la codificación en Base64. Estos marcadores ayudan al servidor de C2 a identificar y validar el formato de los datos.
Cada baliza selecciona aleatoriamente uno de los 10 dominios usando Get-Random. El mecanismo de beaconing aprovecha un bucle infinito con un intervalo de baliza de 20 segundos mediante System.Threading.AutoResetEvent, donde la condición del bucle asegura que la ejecución nunca termine. Tras una comunicación exitosa con el C2, el script ejecuta los comandos de PowerShell recibidos.
Figura 6: Script JS de segunda etapa limpio
Después de ejecutar el archivo JavaScript inicial, aproximadamente entre 10 y 20 minutos más tarde, se crearían dos mecanismos de persistencia aprovechando la carpeta de inicio (T1547.001). Gootloader anteriormente usaba tareas programadas para la persistencia.
En uno de los casos observados, los archivos de acceso directo se llamaban molecular ecology.lnk y outreach services.lnk. Los archivos de acceso directo lanzarían dos archivos de acceso directo adicionales ubicados en la carpeta %AppData%. En nuestro caso, se trata de C:\Users\username\AppData\Roaming\ISIS Drivers\Outreach Services.lnk y C:\Users\username\AppData\Roaming\PFU\Molecular Ecology.lnk. Estos últimos accesos directos serían responsables de lanzar archivos JavaScript dentro de la misma carpeta donde residen los accesos directos (%AppData%<folder_name>): EMC ControlCenter.js y Adaptive Algorithms.js. Los archivos de acceso directo hacen referencia a sus objetivos usando nombres de archivo cortos 8.3 de Windows (por ejemplo, MOLECU1.LNK en lugar de Molecular Ecology.lnk, EMCCON1.JS en lugar de EMC ControlCenter.js). Windows genera automáticamente estos alias de nombre de archivo corto por compatibilidad con sistemas heredados: cuando se crea un archivo con un nombre largo, Windows genera un alias de 8 caracteres usando los primeros seis caracteres más ~1 y una extensión de tres caracteres. También se observaron referencias similares de nombres de archivo cortos en infecciones anteriores de Gootloader desde 2022. Los dos archivos JavaScript adicionales tienen capacidades similares al inicial, pero contienen dominios distintos (consulta la sección “Indicadores de compromiso”). Vale la pena señalar que los archivos de acceso directo tienen combinaciones de teclas (en los casos observados, son "CTRL+ALT+M" y “CONTROL+ALT+G”) asignadas, lo que permite que el loader se ejecute cuando el usuario presiona esas combinaciones de teclas específicas.
Figura 7: Vista general del archivo de acceso directo usando la herramienta LECmd
Antes de adentrarnos en la actividad manual que observamos, veamos una de las herramientas favoritas en el arsenal de Vanilla Tempest: la puerta trasera Supper.
Puerta trasera Supper: el plato favorito de Vanilla Tempest
Un vistazo a la ofuscación
La puerta trasera SOCKS5 Supper es comúnmente usada por Vanilla Tempest. La puerta trasera tiene capacidades de control remoto sobre los equipos comprometidos y facilita el tunneling del tráfico de red. Esta versión de Supper es particularmente interesante, específicamente en la parte de la ofuscación.
La puerta trasera aprovecha el API hammering mediante numerosas llamadas rápidas a la API, probablemente para frustrar a los analistas y complicar el análisis manual. Esta técnica inunda los desensambladores y depuradores con llamadas a la API repetitivas y benignas que deben recorrerse o saltarse, lo que hace que el proceso de análisis sea tedioso y lento. La actividad excesiva de llamadas a la API también oscurece el flujo de control y dificulta identificar cuáles llamadas a la API son realmente relevantes para la funcionalidad principal del malware frente a las que son solo ruido, obligando a los analistas a dedicar más tiempo a distinguir el comportamiento significativo de la ofuscación deliberada.
Figura 8: Código con API hammering (a la izquierda), código que contiene el shellcode con el API hammering eliminado (a la derecha)
Lo que parecen asignaciones de datos en el pseudocódigo descompilado son en realidad instrucciones de shellcode que se escriben directamente en memoria en tiempo de ejecución. Cada asignación (_QWORD) o (_BYTE) construye instrucciones de ensamblador x86-64 byte por byte. Por ejemplo, el valor de 64 bits 0x042454890824548B escrito en memoria contiene los bytes que forman una instrucción real; cuando el procesador lee esa ubicación de memoria, interpreta estos bytes como “mov rbx, qword ptr [rsp+8]” seguido de “mov rdx, qword ptr [rsp+10]”. Una vez que estos bytes de instrucción se escriben en memoria, el código marca esa región de memoria como ejecutable (usando VirtualProtect con permisos PAGE_EXECUTE) y transfiere el flujo de control hacia ella, lo que hace que el backdoor ejecute el shellcode. El shellcode reconstruido contiene la rutina de descompresión LZMA para el payload final.
Figura 9: El código reconstruido que contiene la rutina de descompresión LZMA
Como se mencionó anteriormente, el payload final está comprimido con LZMA. La implementación usa la compresión estándar LZMA1 con un formato de encabezado personalizado. En lugar del encabezado LZMA estándar de 13 bytes (1 byte de propiedades + 4 bytes de tamaño de diccionario + 8 bytes de tamaño sin comprimir), el backdoor usa solo un encabezado personalizado de 2 bytes. El byte 0 (0x1A) contiene información de alineación de posición, y el byte 1 (0x03) contiene bits de contexto literal; ambos parámetros configuran cómo el algoritmo LZMA decodifica los datos comprimidos. El tamaño del diccionario (8 MB, la ventana máxima de retroceso que usa LZMA para encontrar secuencias de datos repetidas durante la descompresión) y el tamaño sin comprimir (260.270 bytes) están codificados directamente en el código de ensamblador en lugar de almacenarse en el encabezado.
El backdoor ofuscado también aprovecha el cálculo de resúmenes criptográficos de API para ofuscar las llamadas a la API. El backdoor usa un algoritmo de hash multiplicativo simple para ofuscar los nombres de las funciones de la API, donde cada carácter de la cadena del nombre de la función se procesa secuencialmente multiplicando el hash acumulado por 9 y sumando el valor ASCII del carácter.
Algoritmo de cálculo de resúmenes criptográficos de API:
El backdoor usa resolución de DLL basada en hashes, comparando valores de hash precalculados (como 0xA20DF064 para ADVAPI32.dll o 0x4465E058 para KERNEL32.dll) para determinar qué DLL cargar. Una vez que se encuentra una coincidencia de hash, la función reconstruye la cadena del nombre de la DLL correspondiente en memoria y la pasa a RtlInitUnicodeString para convertirla en una estructura UNICODE_STRING, que es el formato requerido por las funciones de bajo nivel LdrGetDllHandle y LdrLoadDll que el backdoor usa en lugar de LoadLibraryA. El backdoor usa deliberadamente estas funciones nativas de ntdll.dll en lugar de API de más alto nivel como LoadLibraryA para evadir los hooks en modo de usuario que suelen colocar las herramientas de seguridad, y los sandboxes que normalmente monitorean las llamadas a la API de kernel32 más utilizadas. El backdoor primero intenta obtener un identificador de DLL existente con LdrGetDllHandle, y recurre a LdrLoadDll si falla la búsqueda del identificador.
Figura 10: Comparación de hashes precalculados con los nombres de las DLL
Las API y DLL resueltas:
Justo antes de la ejecución del shellcode, se pasaron constantes de protección de memoria inválidas (0x16 y 0x06) a NtProtectVirtualMemory, lo que provoca que las tres llamadas de cambio de protección fallen con STATUS_INVALID_PAGE_PROTECTION, ya que estos valores no corresponden a ninguna constante PAGE_* válida de Windows. Este error pasó desapercibido porque el shellcode igual se ejecuta correctamente: la región de memoria asignada ya tiene permisos PAGE_EXECUTE_READWRITE (0x40) desde la llamada inicial a NtAllocateVirtualMemory, lo que brinda los permisos de ejecución necesarios para que el código reconstruido se ejecute, haciendo innecesarios los cambios de protección posteriores.
Al seguir investigando con la regla de Yara, se revelaron muestras adicionales que usan la misma ofuscación. Estas muestras se atribuyen a OysterLoader (también conocido como CleanUpLoader o Broomstick), otro backdoor que Vanilla Tempest se niega a dejar de usar. Nombramos al ofuscador "TextShell".
El menú del backdoor de Supper
El backdoor Supper se comunica con sus servidores C2 a través del puerto TCP 443; las IP de C2 están codificadas directamente en el binario (consulta la sección “Indicadores de compromiso”). El backdoor implementa un cifrado de flujo personalizado para cifrar y descifrar el tráfico. La función de cifrado cifra los datos salientes generando una clave aleatoria, mientras que la función de descifrado procesa los comandos entrantes usando una clave extraída del encabezado del mensaje. Ambas usan el mismo algoritmo XOR.
Cuando el backdoor necesita cifrar datos para enviarlos al servidor C2, genera una nueva clave de 4 bytes para cada mensaje y la coloca directamente en el encabezado del mensaje.
Cada mensaje comienza con un encabezado de 12 bytes:
La clave de cifrado se genera aleatoriamente para cada mensaje y se transmite en el encabezado. Como se mencionó anteriormente, el cifrado y el descifrado usan el mismo cifrado XOR con estado:
El cifrado usa un contador interno (llamado "state") que cambia a medida que cifra cada byte. Debido a que el estado evoluciona en cada posición, el mismo byte de texto plano se cifra de manera diferente según el lugar donde aparezca en el mensaje. Cuando el backdoor recibe datos cifrados del servidor C2, extrae la clave de los bytes 8-11 del encabezado y ejecuta el mismo algoritmo para descifrar los datos.
El misterioso archivo bajo la carpeta %TEMP%
El backdoor recibe actualizaciones de configuración del servidor C2 a través de comandos de tipo de mensaje 6 (consulta la tabla de comandos a continuación). Cuando llega este mensaje, el backdoor descifra el payload usando la clave del encabezado del mensaje. El payload contiene direcciones IP de servidores C2 de respaldo. En lugar de almacenar estas IP en texto plano, el backdoor las cifra con una clave recién generada y escribe los valores cifrados en un archivo (observamos archivos llamados s01bafg y orl en la carpeta %TEMP%). Este mecanismo de persistencia asegura que el backdoor mantenga una lista actualizada de servidores de respaldo incluso si el C2 principal deja de estar disponible.
A continuación se muestra la tabla de comandos del backdoor:
|
ID |
Propósito |
Descripción |
|
0 |
Configuración de SOCKS5 |
Establece un servidor proxy SOCKS5 en el endpoint infectado. Gestiona la negociación de autenticación y crea hilos para las conexiones a través del proxy. |
|
1 |
Desconexión de SOCKS |
Gestiona las conexiones SOCKS. El valor mágico 0x6661696C ("fail") desconecta al objetivo. De lo contrario, reenvía los datos a través de un túnel activo. |
|
2 |
Ejecución de shell |
Shell interactiva de cmd.exe. La primera llamada crea un proceso con tuberías stdin/stdout. Las llamadas siguientes envían comandos y devuelven la salida. |
|
3 |
Autoeliminación |
Cierra la conexión C2, genera “cmd.exe /C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del /f /q "<path>"” y luego sale de inmediato. El ping crea un retraso de 3 segundos antes de que se ejecute la eliminación, dando tiempo a que la puerta trasera se cierre |
|
4 |
Sin usar | |
|
5 |
Finalizar |
Apagado completo. Cierra todas las conexiones, duerme 2 segundos, realiza la limpieza y luego sale del proceso de la puerta trasera. |
|
6 |
Actualizar configuración |
Recibe direcciones IP de C2 de respaldo, las encripta y las escribe en el archivo temp/s01bafg. |
|
7 |
Establecer dirección C2 |
Actualiza la IP del servidor C2 actual. La da formato en decimal con puntos y la guarda en una variable global. |
Ahora, probablemente te estés preguntando por qué hicimos un análisis técnico completo del backdoor Supper. Creemos que es fundamental entender las capacidades de la herramienta y ver por qué los actores de amenazas la aprovechan, principalmente por su simplicidad y confiabilidad. No hay nada revolucionario aquí, es un proxy SOCKS básico y un shell simple. Pero ese es exactamente el punto. Los actores de amenazas no necesitan días cero sofisticados cuando herramientas básicas como esta cumplen su función. Entender lo mundano le da a los defensores una dosis de realidad: la mayoría de las brechas no tienen una sofisticación digna de Hollywood, son simplemente técnicas básicas bien ejecutadas que pasan desapercibidas si el endpoint no está siendo monitoreado adecuadamente por una solución de endpoint.
Cuando Gootloader trae amigos
Caso #1
Aproximadamente 20 minutos después de la ejecución inicial de JavaScript, el actor de amenazas realizó reconocimiento desde uno de los CUATRO backdoors Supper SOCKS5 implantados. Por qué el actor de amenazas decidió implantar cuatro instancias de un backdoor Supper sigue siendo un misterio.
El ejemplo de la ejecución del backdoor:
C:\Users\username\AppData\Local\Zoxsimio\Failover Dependency.exe" ./FAILOV~1.ULB ,DllRegisterServer.
Se ejecutaron los siguientes comandos de reconocimiento desde el backdoor:
- net user <username> /domain
- nltest /dclist:
- net group "domain admins" /domain
- nltest /domain_trusts
Se ejecutaron algunos comandos de reconocimiento adicionales interesantes:
- Este comando busca en Active Directory (AD) cuentas de usuario con nombres principales de servicio (SPN):
- Este comando escanea todos los equipos del dominio para encontrar dónde el usuario actual tiene acceso de administrador local:
- Este comando realiza un ataque de Kerberoasting para extraer hashes de contraseñas descifrables:
Aproximadamente 16 horas y 54 minutos después de la ejecución inicial de JavaScript y la actividad de reconocimiento, el actor de amenazas se movió lateralmente vía WinRM (Windows Remote Management) hacia el controlador de dominio. En el controlador de dominio, el actor de amenazas creó un usuario sccmad y lo agregó a los grupos de Domain Admins y Administradores locales, luego enumeró los usuarios actualmente conectados en el sistema para verificar que el usuario recién creado existiera, mediante los siguientes comandos:
- net USER sccmad <redacted password> /ADD
- net group \"Domain Admins\" sccmad /ADD /DOMAIN
- net LOCALGROUP administrators sccmad /add
- quser.exe
El actor de amenazas luego aprovechó Impacket para ejecutar remotamente el siguiente comando en el controlador de dominio:
- cmd.exe /Q /c echo C:\Windows\system32\cmd.exe /C vssadmin list shadows /for=C: ^> C:\Windows\Temp\__output > C:\Windows\TEMP\execute.bat & C:\Windows\system32\cmd.exe /Q /c C:\Windows\TEMP\execute.bat & del C:\Windows\TEMP\execute.bat
Impacket envolvió automáticamente este comando en su patrón estándar de ejecución de archivos por lotes, y creó un archivo temporal llamado execute.bat dentro de la carpeta C:\Windows\TEMP\, ejecutó el comando vssadmin para enumerar las instantáneas de Volume Shadow Copy, redirigió la salida y luego eliminó el archivo por lotes para eliminar los rastros. Esto le permitió al actor de amenazas identificar qué instantáneas de respaldo existían en el sistema, generalmente como un paso previo a eliminarlas antes de desplegar el ransomware.
Caso n.º 2
En otro caso, observamos al actor de amenazas ejecutar los siguientes comandos de reconocimiento desde el backdoor Supper implantado, aproximadamente 20 minutos después de la ejecución inicial de JavaScript:
- Este comando busca en AD todas las cuentas de usuario que tengan texto en su campo de descripción, y luego muestra el nombre de usuario y la descripción. Los administradores a veces almacenan información confidencial en los campos de descripción de los usuarios, como contraseñas temporales, propósitos de la cuenta o notas sobre cuentas privilegiadas. Es una forma rápida de encontrar información potencialmente valiosa que pudo haberse documentado de forma descuidada en AD:
- Este comando enumera todas las máquinas con Windows Server en el dominio de AD, mostrando su nombre de equipo, nombre DNS, versión del sistema operativo y la marca de tiempo del último inicio de sesión. Esto ayuda a los actores de amenazas a identificar objetivos de alto valor, como controladores de dominio, servidores de archivos o servidores de aplicaciones. El conteo al final les da el número total de servidores en el entorno, lo que ayuda a evaluar el alcance de la red:
Caso n.º 3
Observamos al actor de amenazas crear el usuario bpadmin y agregarlo al grupo Remote Desktop Users en el endpoint comprometido inicial usando net group "Remote Desktop Users" bpadmin /add. Posteriormente, el actor de amenazas aprovechó sus privilegios existentes de administrador de dominio para realizar un ataque DCSync.
La trama se complica…
@DFIRReport compartió amablemente con nosotros observaciones de su entorno, donde ocurrió la siguiente actividad:
- El archivo ZIP muestra un comportamiento condicional según el método de extracción. Cuando se abre con una herramienta como 7-Zip, deja caer el archivo JavaScript malicioso disfrazado de archivo .txt . Sin embargo, cuando se extrae con la utilidad ZIP predeterminada de Windows, deja el archivo JavaScript directamente en forma ejecutable.
- El actor de amenazas logró movimiento lateral hacia un controlador de dominio en menos de una hora tras la infección inicial de Gootloader, lo cual es considerablemente más rápido que el plazo de 17 horas observado en el Caso #1.
- Una vez obtenido el acceso al controlador de dominio, el actor de amenazas desplegó una DLL proxy maliciosa y estableció persistencia mediante una tarea programada que se ejecutaba con privilegios SYSTEM. El análisis de la DLL reveló shellcode embebido que hacía referencia a un proyecto llamado MEOWBACKCONN.
- Tras establecer la persistencia, el actor de amenazas usó ntdsutil para volcar la base de datos NTDS.dit (T1003.003), y luego la comprimió en un archivo ZIP, probablemente preparado para exfiltración.
- El actor de amenazas realizó actividades de limpieza después de sus operaciones, incluyendo la eliminación de registros de eventos y la eliminación de claves de registro relacionadas con conexiones de cliente de Terminal Server (T1070.001).
Conclusión
Gootloader ha regresado con algunos cambios, especialmente el uso de fuentes WOFF2 personalizadas que realizan sustitución de glifos, transformando caracteres sin sentido en el código fuente en nombres de archivo que parecen legítimos al renderizarse en los navegadores.
La infección opera mediante una asociación criminal bien establecida: Storm-0494 se encarga de las operaciones de Gootloader y el acceso inicial, y luego entrega los entornos comprometidos a Vanilla Tempest para la post-explotación y el despliegue de ransomware. Esta división del trabajo ha demostrado ser efectiva desde 2020, con Vanilla Tempest desplegando consistentemente varias familias de ransomware, en particular Rhysida.
El backdoor SOCKS5 Supper usa una ofuscación tediosa que protege una funcionalidad sencilla: el hammering de API, la construcción de shellcode en tiempo de ejecución y el cifrado personalizado dificultan el análisis, pero las capacidades principales siguen siendo deliberadamente básicas: proxy SOCKS y acceso por shell remoto. Este enfoque de "suficientemente bueno" demuestra que los actores de amenazas no necesitan exploits de vanguardia cuando herramientas básicas bien ofuscadas logran sus objetivos.
¿Qué aprendimos de esto?
Los actores de amenazas se mueven rápido: reconocimiento en 20 minutos, compromiso del controlador de dominio en 17 horas. Las organizaciones tienen una ventana de detección y respuesta extremadamente estrecha antes de que los atacantes establezcan acceso de Domain Admin y comiencen la preparación del ransomware. A pesar de una ofuscación inicial sofisticada, los actores de amenazas siguen patrones repetibles: enumeración de AD (Kerberoasting, escaneo de SPN), escaneo de administradores locales en todo el dominio, movimiento lateral mediante WinRM, creación de cuentas privilegiadas y enumeración de Volume Shadow Copy. Estos comportamientos son detectables con un monitoreo adecuado. La mayoría de las brechas tienen éxito mediante técnicas básicas bien ejecutadas, no días cero. Monitorea la ejecución inusual de PowerShell, los patrones de enumeración de AD, los intentos de escalada de privilegios y el movimiento lateral. Estas actividades "mundanas" son tus primeras señales de alerta. Si bien Gootloader mejora sus capacidades de evasión, los patrones de ataque que siguen se mantienen consistentes.
El mapa de la cadena de infección (Caso #1)
Figura 11: Cadena de infección de Gootloader
Detecciones
Yara
Backdoor Supper
Indicadores de compromiso
|
Elemento |
Descripción |
|
SHA256: cf44aa11a17b3dad61cae715f4ea27c0cbf80732a1a7a1c530a5c9d3d183482a C2s: 103.253.42[.]91 91.236.230[.]134 213.232.236[.]138 146.19.49[.]177 |
TextShell que contiene Supper Backdoor: Failover Dependency Zoxsimio.ulb |
|
Ruta:
Dominios: hxxps://cortinaspraga.com/ hxxp://cookcountyjudges.org/ hxxps://x.fybw.org/ hxxps://jungutah.com/ hxxps://influenceimmo.com/ hxxps://tokyocheapo.com/ hxxps://espressonisten.de/ hxxps://tiresdoc.com/ hxxps://hotporntv.net/ hxxps://yourboxspring.nl/ |
Segundo archivo JavaScript de Gootloader: EMC ControlCenter.js |
|
Ruta: SHA256: b9a61652dffd2ab3ec3b7e95829759fc43665c27e9642d4b2d4d2f7287254034 Dominios: hxxps://filmcrewnepal.com/ hxxps://yoga-penzberg.de/ hxxps://sugarbeecrafts.com/ hxxps://www.worldwealthbuilders.com/ hxxps://lepolice.com/ hxxps://www.lovestu.com/ hxxps://bluehamham.com/ hxxps://vps3nter.ir/ hxxps://whiskymuseum.at/ hxxps://latimp.eu/ |
Segundo archivo JavaScript de Gootloader: Mitigation Strategies.js |
|
Ruta:
Dominios: hxxps://solidegypt.net/ hxxps://wessper.com/ hxxps://www.pathfindertravels.se/tickets/ hxxps://www.smithcoinc.biz/ hxxps://kollabmi.se/ hxxps://xxxmorritas.com/ hxxps://onsk.dk/ hxxps://villasaze.ir/ hxxps://blossomthemesdemo.com/ hxxps://headedforspace.com/ |
Segundo archivo JavaScript de Gootloader: Adaptive Algorithms.js |
|
SHA256: c2326db8acae0cf9c5fc734e01d6f6c1cd78473b27044955c5761ec7fd479964 |
Primer archivo JavaScript de Gootloader: Domestic_Partnership_Agreement_Template.js |
|
SHA256: ad88076fd75d80e963d07f03d7ae35d4e55bd49634baf92743eece19ec901e94 |
Primer archivo JavaScript de Gootloader: Unmarried_Couples_Rights_Checklist.js |
|
Ruta: C:\Users\username\AppData\Local\Oardwior\
C2s: 178.32.224[.]219 37.59.205[.]2 193.104.58[.]64 |
TextShell que contiene Supper Backdoor: Disconnect Package Oardwior.ijp |
|
SHA256: c2b9782c55f75bb1797cb4fbae0290b44d0fcad51bf4f2c11c52ebbe3526d2ac Dominios: hxxps://spirits-station.fr/ hxxps://www.us.registration.fcaministers.com/ hxxps://motoz.com.au/ hxxps://routinelynomadic.com/ hxxps://www.wagenbaugrabs.ch/ hxxps://studentspoint.org/ hxxps://cortinaspraga.com/ hxxps://dailykhabrain.com.pk/ hxxps://myanimals.com/ hxxps://www2.pelisyseries.net/ |
Archivo JavaScript inicial de Gootloader: Missouri_Utility_Easement_Guide_2023.js |
|
Ruta: SHA256: 7557d5fed880ee1e292aba464ffdc12021f9acbe0ee3a2313519ecd7f94ec5c4 Dominios: hxxps://www.claritycontentservices.com/wp/ hxxps://patriotillumination.com/ hxxps://michaelcheney.com/ hxxps://allreleases.ru/ hxxps://cloudy.pk/ hxxps://eliskavaea.cz/ hxxps://r34porn.net/ hxxps://www.wagenbaugrabs.ch/ hxxps://leadoo.com/ hxxps://ostmarketing.com/ |
Archivo JavaScript secundario de Gootloader: Certified Trainer.js |
|
Ruta: SHA256: 5ec9e926d4fb4237cf297d0d920cf0e9a5409f0226ee555bd8c89b97a659f4b0 Dominios: hxxps://egyptelite.com/ hxxps://restaurantchezhenri.ca/ hxxps://www1.zonewebmaster.eu/news/ hxxps://campfosterymca.com/ hxxps://idmpakistan.pk/ hxxps://themasterscraft.com/ hxxps://unica.md/ hxxps://cargoboard.de/ hxxps://www.supremesovietoflove.com/wp/ hxxps://buildacampervan.com/ |
Archivo JavaScript secundario de Gootloader: Environmental Economics.js |
|
SHA256: 87cbe9a5e9da0dba04dbd8046b90dbd8ee531e99fd6b351eae1ae5df5aa67439 Dominios: hxxps://www.minklinkaps.com/ hxxps://aradax.ir/ hxxps://medicit-y.ch/ hxxps://redronic.com/ hxxps://www.ferienhausdehaanmieten.de/ hxxps://gravityforms.ir/ hxxps://apprater.net/ hxxps://fotbalovavidea.cz/ hxxps://usma.ru/ hxxps://thetripschool.com/ |
Archivo JavaScript inicial de Gootloader: HOA_Committee_Meeting_Agenda_Template.js |
Agradecimientos
Muchas gracias a @DFIRReport por su generoso apoyo, análisis y contribución a este blog.