El equipo de investigación de ESET ha identificado dos variantes de Windows hasta ahora no documentadas de SprySOCKS, un backdoor previamente exclusivo de Linux que, según reportes, es utilizado por FishMonger, el grupo que se cree está operado por un contratista chino llamado I‑SOON. Si bien inicialmente descubrimos las muestras de malware en VirusTotal, la telemetría de ESET muestra actividad real entre 2023 y 2024, con varias víctimas en Honduras, Taiwán, Tailandia y Pakistán, apuntando principalmente a organizaciones gubernamentales.

Las variantes de Windows descubiertas están marcadas internamente como WIN_DRV y WIN_PLUS. Ambas incluyen una configuración de C&C (command and control) hardcodeada y soportan comunicación a través de los protocolos TCP, UDP y WebSocket. La funcionalidad core del backdoor en ambas versiones incluye soporte para más de 30 comandos de C&C, abarcando diversas capacidades como recolección de información del sistema, enumeración de procesos, así como gestión de servicios y funciones de file management, como listar, crear, eliminar y transferir archivos.

Además de la funcionalidad core del backdoor, la versión WIN_DRV utiliza kernel drivers para ocultar las conexiones de red, procesos, archivos y claves de registro del malware, y habilita el desvío de tráfico TCP (TCP traffic diversion), lo que permite a los operadores del malware enviar comandos al backdoor a través de un puerto TCP aleatorio en el dispositivo de la víctima sin exponer el puerto real en escucha del backdoor dentro del tráfico de red.

Según la telemetría de ESET, existen indicios limitados de que algunos escenarios de ataque con SprySOCKS podrían involucrar un componente de UEFI bootkit, posiblemente explotando la vulnerabilidad CVE‑2023‑24932.

El análisis presentado en este informe nos lleva a atribuir estas nuevas variantes de Windows a FishMonger con un alto grado de confianza.

Puntos clave de este blogpost:
  • Descubrimos dos variantes de Windows previamente no documentadas del backdoor SprySOCKS de FishMonger.
  • La telemetría de ESET muestra actividad entre 2023 y 2024, apuntando principalmente a organizaciones gubernamentales en Honduras, Taiwán, Tailandia y Pakistán.
  • Ambas variantes de Windows soportan comunicación sobre protocolos TCP, UDP y WebSocket, e implementan más de 30 comandos.
  • La variante WIN_DRV crea un backdoor TCP pasivo y sigiloso, apoyándose en un kernel driver para redirigir el tráfico hacia el puerto TCP oculto del backdoor cuando se detectan datos especialmente diseñados dentro de un paquete TCP recibido.

Perfil de FishMonger

FishMonger –que se cree es operado por un contratista chino llamado I‑SOON (ver nuestro Q4 2023–Q1 2024 APT Activity Report)– es un grupo de ciberespionaje que forma parte del umbrella del Winnti Group y que muy probablemente opera desde China, específicamente desde la ciudad de Chengdu. También es conocido como Earth Lusca, TAG-22, Aquatic Panda o Red Dev 10. Publicamos un análisis de FishMonger a comienzos de 2020, cuando apuntaba fuertemente a universidades en Hong Kong durante las protestas civiles que comenzaron en junio de 2019. El grupo también es conocido por llevar a cabo watering-hole attacks, como reportó Trend Micro. El toolset de FishMonger incluye ShadowPad, Spyder, Cobalt Strike, FunnySwitch, SprySOCKS y el BIOPASS RAT.

Análisis técnico

En esta sección, presentamos un análisis técnico de estas nuevas variantes de Windows del backdoor SprySOCKS de FishMonger.

El archivo que nos llevó a este descubrimiento fue cargado en VirusTotal en abril de 2024 bajo el nombre klelam00007.zip; su contenido se muestra en la Figura 1.

Figure 1. Contents of klelam00007.zip as displayed on VirusTotal
Figura 1. Contenido de klelam00007.zip tal y como se muestra en VirusTotal

Este archivo contiene diversos archivos, incluidos algunos legítimos utilizados para alojar DLL side-loading, y tres archivos cifrados con extensión .dat que resultan sospechosos. Nuestro análisis posterior reveló que estos archivos cifrados contienen una nueva variante de Windows del backdoor SprySOCKS de FishMonger, hasta ahora no documentada, etiquetada como WIN_DRV por sus desarrolladores. Investigaciones adicionales revelaron otra versión de backdoor, denominada WIN_PLUS, en la telemetría de ESET.

Acceso inicial

FishMonger es conocido por apuntar a los servidores expuestos a internet (public-facing servers) de sus víctimas, explotando con frecuencia vulnerabilidades N-day basadas en servidor para obtener acceso inicial. Si bien no pudimos confirmar el método exacto mediante el cual FishMonger comprometió los sistemas de sus víctimas en esta campaña, la presencia de sistemas operativos de servidor en algunos de los dispositivos afectados, junto con el modus operandi típico de FishMonger, sugiere que los atacantes podrían haber ingresado a través de aplicaciones expuestas mal configuradas o sin parchear.

SprySOCKS para Windows

En septiembre de 2023, Trend Micro publicó un informe sobre un nuevo backdoor de Linux de FishMonger al que sus analistas denominaron SprySOCKS. El código de este backdoor se basa en un remote access trojan (RAT) de Windows de código abierto llamado Trochilus, y comparte varias características con el backdoor RedLeaves; sin embargo, fue lo suficientemente extendido y modificado como para ser considerado un nuevo backdoor. En este informe, analizamos dos variantes de Windows de la versión 1.8 de SprySOCKS que aún no habían sido divulgadas:

  • Una, denominada WIN_DRV por sus desarrolladores, utiliza un kernel driver para lograr un mayor nivel de sigilo.
  • La otra, sin el driver, se denomina WIN_PLUS.

Como se muestra en la Figura 2, el tipo y el número de versión del backdoor están harcodeados en el binario.

Figure 2. Version type and number hardcoded in WIN_DRV and WIN_PLUS
Figura 2. Tipo y número de versión harcodeados en las variantes del backdoor SprySOCKS para Windows WIN_DRV (izquierda) y WIN_PLUS (derecha)

La gran mayoría de los artefactos y funcionalidades presentes en la versión Linux del backdoor SprySOCKS presentada en el informe de Trend Micro también se encuentran en las nuevas variantes de Windows descritas en este informe. Entre ellas se incluyen:

  • el mismo formato de mensajes C&C,
  • comandos C&C muy similares (además de algunos adicionales),
  • las mismas claves y algoritmos de cifrado, y
  • el uso de la misma librería de red enlazada de forma estática (statically linked networking library, HP-Socket).

Para ambas nuevas variantes de SprySOCKS, la funcionalidad core del backdoor relacionada con la comunicación con el C&C y los comandos disponibles es muy similar. Las diferencias más notables se observan en la forma en que se carga el backdoor final, en las mejoras de sigilo (stealthiness), y en los nombres y rutas de los componentes utilizados.

En las siguientes subsecciones, primero analizamos los componentes involucrados en la cadena de ejecución (execution chain) de cada variante de SprySOCKS, y luego describimos el componente del backdoor, que es prácticamente el mismo en ambas variantes.

Componentes de WIN_DRV

En un archivo cargado en VirusTotal, descubrimos la versión WIN_DRV de SprySOCKS, que incluye una configuración de C&C vacía. Como resultado, esta versión no contacta activamente direcciones remotas; sin embargo, sigue siendo capaz de iniciar un servidor TCP en un puerto aleatorio en el dispositivo de la víctima, actuando así como un backdoor pasivo. Curiosamente, los atacantes no necesitan conocer el número de puerto TCP de este servidor, ya que, como se explica más adelante, el driver RawWNPF utilizado por la versión WIN_DRV permite el desvío silencioso (silent diversion) del tráfico TCP recibido en cualquier puerto abierto directamente hacia el backdoor (más detalles en la sección del driver RawWNPF).

Como se muestra en la Figura 1, el archivo que contiene la versión WIN_DRV de SprySOCKS incluye varios archivos:

  • klelam00007.bat: un script batch responsable de la persistencia del backdoor y que, como se muestra en la Figura 3, este:

copia todos los archivos del directorio de trabajo actual al directorio %SystemRoot%\Fonts (para funcionar correctamente, el archivo batch debe desplegarse en el mismo directorio que el resto de los archivos del archivo comprimido),

crea una tarea programada denominada ApphostRagistreationVerifier, configurada para ejecutar ApphostRagistreationVerifier.exe (un ejecutable legítimo, correctamente firmado, renombrado por los atacantes para imitar el AppHostRegistrationVerifier.exe firmado por Microsoft) con privilegios NT AUTHORITY\SYSTEM en cada inicio del sistema. Los atacantes utilizan la conocida técnica DLL side-loading, aprovechando la forma en que Windows carga las DLL, para cargar su propia DLL maliciosa (en este caso, tpsvcloc.dll) mediante una aplicación legítima firmada. Más específicamente, en en este caso utilizan la técnica de malware sideloading via DLL satélite de MFC (nótese la cadena «loc» en el nombre del archivo tpsvcloc.dll ),

  • ApphostRagistreationVerifier.exe: un ejecutable legítimo y firmado del servicio de creación de impresoras AutoConnect de ThinPrint (SHA-1: FFC3AA7909D4E72C360D65A1F45260DFFE5C99B7) que carga la librería tpsvc.dll,
  • tpsvc.dll: una librería legítima y firmada que carga la librería tpsvcloc.dll,
  • tpsvcloc.dll: el loader del backdoor SprySOCKS,
  • X1B5206BDC1743DD.dat: un contenedor cifrado que incluye el backdoor SprySOCKS y copias de los siguientes dos archivos,
  • KX1B5206BDC1743DD.dat: DriverLoader, un kernel driver cifrado reponsable de cargar otro kernel driver desde KW1B5206BDC1743FP.dat, y
  • KW1B5206BDC1743FP.dat – RawWNPF, un kernel driver responsable de ocultar los archivos y la actividad de red del backdoor.
Figure 3. klelam00007.bat setting up persistence for the SprySOCKS backdoor
Figura 3. klelam00007.bat configurando la persistencia para el backdoor SprySOCKS (se han añadido saltos de línea para facilitar la lectura)

La figura 4 muestra la cadena de ejecución de la variante WIN_DRV de SprySOCKs

Figure 4. Execution chain of the SprySOCKS WIN_DRV variant
Figura 4. Cadena de ejecución de la variante SprySOCKS WIN_DRV

Las siguientes tres subsecciones proporcionan análisis técnicos de los componentes mencionados anteriormente: el loader de SprySOCKS, el driver DriverLoader y el driver RawWNPF.

SprySOCKS loader

El loader comienza con verificaciones iniciales para detectar la presencia de un entorno virtual y algunos productos de seguridad. Busca librerías específicas (en particular: snxhk.dll, SxWrapper.dll, SxIn.dll, SXIn64.dll y SbieDll.dll) dentro del proceso del loader, y finaliza su ejecución si encuentra alguna de ellas.

Como siguiente paso, verifica si la persistencia fue configurada correctamente por el script klelam00007.bat, mostrado en la Figura 3. Para ello, comprueba si la imagen actual del loader fue cargada desde el directorio %SystemRoot%\Fonts\ e intenta acceder a los archivos %SystemRoot%\Fonts\X1B5206BDC1743DD.dat, %SystemRoot%\Fonts\tpsvc.dll y %SystemRoot%\Fonts\tpsvcloc.dll. Si detecta que alguno de estos archivos no se encuentra en la ubicación esperada, configura la persistencia por sí mismo mediante:

  • la copoa de X1B5206BDC1743DD.dat, tpsvc.dll, tpsvcloc.dll y ApphostRagistreationVerifier.exe desde el directorio de trabajo actual al directorio %SystemRoot%\Fonts\,
  • el registro de la aplicación %SystemRoot%\Fonts\ApphostRagistreationVerifier.exe como debugger para vds.exe (un servicio de disco virtual que puede ejecutarse automáticamente al iniciar el sistema) escribiendo la ruta de la aplicación en el valor del registro HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\vds.exe\debugger, y
  • la creación del archivo affair-build.bat en el directorio %SystemRoot%\Fonts\ y su posterior ejecución mediante cmd.exe. Este script, que se muestra en la Figura 5, borra los rastros de este proceso eliminando los archivos del directorio de despliegue y ejecutando de nuevo el malware (ahora desde %SystemRoot%\Fonts\) reiniciando el servicio vds.
Figure 5. affair-build.bat executed by the SprySOCKS loader
Figura 5. affair-build.bat ejecutado por el loader SprySOCKS

Cuando la persistencia está establecida, el loader continúa cargando los payloads desde un contenedor cifrado ubicado en %SystemRoot%\Fonts\X1B5206BDC1743DD.dat. El algoritmo y la clave de descifrado son: AES de 128 bits en modo ECB con la clave hardcodeada uXQLESMXGaRMs6BL.

Esto produce shellcode generado por la herramienta de código abierto  DllToShellCode. Antes de ejecutar el shellcode, extrae el resto de los payloads cifrados del contenedor en archivos separados:

  • %SystemRoot%\Fonts\KX1B5206BDC1743DD.dat
  • %SystemRoot%\Fonts\KW1B5206BDC1743FP.dat

Una vez completado, el loader crea (spawns) un nuevo proceso svchost.exe utilizando CreateProcessAsUserW con un token obtenido de spoolsv.exe, e inyecta el shellcode del backdoor en el proceso utilizando la técnica de process doppelgänging. Durante el proceso de inyección, el shellcode se escribe en un archivo temporal, utilizando el prefijo TH en su nombre, dentro del directorio %TEMP %.

Como último paso, el loader procede a descifrar y ejecutar DriverLoader, un kernel driver oculto dentro del archivo previamente desplegado KX1B5206BDC1743DD.dat. DriverLoader primero se descifra, y luego su contenido se guarda en C:\Windows\System32\drivers\fsdiskbit.sys. . Para ejecutarlo, el loader instala este driver como un minifilter driver creando manualmente una nueva clave de servicio en el registro llamada msidiskserver con un valor ImagePath que apunta al driver desplegado (como se muestra en la Figura 6) e invoca la función de la API de Windows NtLoadDrive con  la clave de registro como parámetro para cargarlo. Si no se detectan errores, el loader elimina tanto la clave de registro msidiskserver como el archivo fsdiskbit.sys. Después de esto, el loader finaliza y termina su ejecución.

Figure 6. Service registry key created by the SprySOCKS WIN_DRV loader
Figura 6. Clave de registro de servicio creada por el loader SprySOCKS WIN_DRV
DriverLoader driver

Antes de abordar la funcionalidad de DriverLoader, una aclaración importante: con el lanzamiento de Windows Vista, Microsoft introdujo la driver signature enforcement (DSE), una característica que garantiza que solo los componentes en kernel mode correctamente firmados puedan ejecutarse en el kernel de Windows. Esto implica que, para ejecutar el driver fsdiskbit.sys (DriverLoader), los atacantes necesitan firmarlo con un certificado confiable.

Para hacer que el driver funcione al menos en algunos sistemas desactualizados o mal configurados, los atacantes utilizaron un certificado filtrado (leaked certificate) disponible en GitHub en el repositorio del proyecto PastDSE, y firmaron el driver fsdiskbit.sys con ese certificado. La información sobre el certificado utilizado se puede ver en la Figura 7.

Figure 7. DriverLoader’s code-signing certificate
Figura 7. Certificado de firma de código de DriverLoader

Ahora, en cuanto a la funcionalidad. El propósito de este componente es bastante directo: cargar otro driver, esta vez únicamente en memoria (in-memory). Primero, lee y descifra el contenido del archivo C:\Windows\Fonts\KW1B5206BDC1743FP.dat, previamente creado por el loader. Utiliza el mismo algoritmo y clave que el loader: AES de 128 bits en modo ECB con la clave  uXQLESMXGaRMs6BL.

Los datos descifrados contienen un binario PE nativo (descrito en la sección del driver RawWNPF), que luego es mapeado manualmente (manually mapped) y se ejecuta su punto de entrada.

El binario de DriverLoader contiene la siguiente ruta PDB embebida:

C:\Users\xdd\Desktop\今天\2023-4-11\2023‑04‑10__注册表驱动加载功能__集成到内测3中-未完成\DriverMemoryLoadDriver\x64\Release\DriverMemoryLoadDriver.pdb

Las partes en chino simplificado se traducen automáticamente como:

  • 今天: Hoy
  • 注册表驱动加载功能__集成到内测3中-未完成: Registry driver loading function__is integrated into internal beta 3-not completed

Como se puede observar en la ruta de símbolos, este componente parece haber estado en desarrollo al menos desde abril de 2023, lo que coincide con el timestamp de compilación de DriverLoader. De forma similar, las cadenas en la ruta sugieren que el proyecto del cual forma parte este driver probablemente aún estaba en desarrollo al momento de su compilación.

Drivers RawWNPF

El driver RawWNPF es el componente que hace que la variante WIN_DRV del backdoor SprySOCKS sea significativamente más sigilosa en comparación con la variante WIN_PLUS. Permite ocultar la actividad maliciosa del backdoor en el sistema comprometido, y puede configurarse invocando códigos de control de E/S personalizados del driver (custom I/O control codes, IOCTLs).

El driver crea un dispositivo llamado \Device\RawWNPF; la lista de IOCTLs disponibles, junto con descripciones breves, se muestra en la Tabla 1.

Tabla 1. Lista de IOCTL gestionados por el driver RawWNPF

IOCTL Description
0x220200 Configure the driver to hide active network connections to and from the specified local TCP port.
0x220300 Unhide the network connections configured with 0x220200.
0x220340 Insert an entry into the hidden connections list.
0x220344 Remove an entry from the hidden connections list.
0x220348 Wipe the whole hidden connections list.
0x22034C Read the hidden connections list.
0x220350 Insert a process with a specified PID into the hidden processes list.
0x220354 Remove a process with a specified PID from the hidden processes list.
0x220358 Wipe the whole hidden processes list.
0x22035C Read the hidden processes list.
0x222000 Initialize the driver’s main functions (hiding network connections, hiding processes, hiding malware components, network filters, persistence protection). After this initialization, other IOCTLs can be used to configure what exactly should be hidden.
0x222004 Returns two hardcoded DWORD values: 1 and 2. This possibly could be the driver’s version.
0x222008 Delete the driver’s binary (if it exists).

Ocultacmiento de procesos específicos

El driver RawWNPF puede configurarse para ocultar procesos en base a sus process IDs, y la lista de procesos ocultos puede gestionarse invocando los IOCTLs del driver 0x220358, 0x22035C, 0x220354 y 0x220350. Para ocultar un proceso, el driver intercepta (hooks) la ejecución de la system call NtQuerySystemInformation y modifica su salida cuando se consulta información sobre los procesos en ejecución (es decir, cuando se pasa SystemProcessInformation en el parámetro SystemInformationClass ). Si alguno de los procesos recuperados por esta función API coincide con un proceso presente en la lista de procesos ocultos del driver, este lo elimina de la salida de la función. La forma en que el kernel driver implementa el hook sobre la system call NtQuerySystemInformation parece estar fuertemente basada en código fuente del proyecto InfinityHookPro.

Ocultamiento de la actividad de red

El driver puede configurarse para ocultar conexiones activas específicas (con una IP, puerto o combinación de ambos definidos) de modo que no aparezcan en la salida de herramientas comunes de administración de red como netstat.exe. Esto se logra mediante una técnica bien conocida (por ejemplo, [1], [2], [3], …), en la que los atacantes interceptan (hook) la IoCompletionRoutine para el IOCTL 0x12001B dentro de la función DeviceIoControl del driver de kernel de Windows nsiproxy.sys. El código dentro del handler para el IOCTL 0x12001B en nsiproxy es responsable de recuperar la lista de conexiones activas, y al interceptar su IoCompletionRoutine , los atacantes pueden recorrer la lista obtenida, verificar la presencia de puertos, direcciones o ambos, y ocultar la conexión específica cuando se encuentra una coincidencia. La Figura 8 muestra la función de hook responsable de ocultar las conexiones de red.

Figure 8. Hex-Rays decompilation of nsiproxy’s IoCompletionRoutine hook
Figura 8. Descompilación de Hex-Rays del hook IoCompletionRoutine de nsiproxy responsable de ocultar las conexiones de red

Además de ocultar las conexiones de red activas, el driver incluye una funcionalidad interesante que le permite desviar paquetes TCP recibidos en cualquier puerto TCP abierto hacia un puerto TCP específico configurado mediante el IOCTL 0x220200  (que en realidad corresponde al puerto del servidor TCP del backdoor SprySOCKS), pero solo en el caso de que los datos TCP recibidos contengan información especialmente diseñada (specially crafted data).Para lograr esto, el driver registra sus propios objetos de filtrado de paquetes utilizando funciones de la API de Windows Filtering Platform (WFP), analiza manualmente el contenido de los paquetes IPv4 transferidos (tanto tráfico entrante como saliente es inspeccionado), y procede a desviar el tráfico si detecta estos datos especialmente diseñados dentro de un paquete TCP recibido.El propósito de esta funcionalidad parece ser principalmente la capacidad de comunicarse con el backdoor malicioso sin necesidad de incluir una dirección de C&C dentro del binario. Además, aunque este tráfico desviado puede ser inspeccionado con herramientas como Wireshark, el puerto real (al que el tráfico es redirigido) no se revela; por lo tanto, puede resultar difícil investigar el destino real de este tráfico malicioso.

Los filtros de paquetes instalados, junto con su información identificatoria, se enumeran en la Tabla 2.

Tabla 2. Objetos de filtrado WFP registrados por el driver RawWNPF

Filter layer name Filter object name and GUID Filter object callout name and GUID
Inbound IP Packet v4 Layer Delivery Optimization (TCP-In)
{E980088D-BE44-4057-8E5C-C7FDF8968795}
COInbound
{DE0D7F67-94ED-4DDB-8215-9C028B54661B}
Outbound IP Packer v4 Layer Delivery Optimization (TCP-Out)
{33F76397-DBCB-445E-8EC3-AA51ED302D15}
COOutbound
{8280DDF3-7489‑4402-B9D8-96B50912346B}
ALE Connect v4 Layer Delivery Optimization (TCP-In)
{5746AF70-2917‑4861-97E6-D5E4DD569F2D}
COAuthConnect
{A33E1AA8-9B0F-44A3-B24A-AEB04CA54C3B}
ALE Listen v4 Layer Delivery Optimization (TCP-In)
{7CB4DFB4-0D20-402D-A49D-BA9660D026E6}
COAuthListen
{40045FAF-6BAE-4B48-9119‑31B48FFEA629}
ALE Receive/Accept v4 Layer Delivery Optimization (TCP-In)
{2C1AB6EF-0B65-4634‑8666-BCB2CF9C72E9}
COAuthAccept
{DDFE5189‑389F-437F-9B92-59495ED2181A}
ALE ResourceAssignment v4 Layer Delivery Optimization (TCP-In)
{B4AE248F-98D5-446F-88EB-14CF605AE722}
COAuthResAssignment
{FE570356-A1A9-413C-94CC-BD6C448E9969}

Ocultamiento de los archivos del backdoor

El driver oculta/protege los archivos del backdoor SprySOCKS registrándose como un minifilter driver e instalando los siguientes callbacks:

  • pre-operation callback que se activa en cada solicitud de E/S IRP_MJ_CREATE  y se encarga de devolver STATUS_NO_SUCH_FILE ante cualquier intento de crear o abrir un archivo o directorio que forme parte de la lista de archivos ocultos/protegidos del driver,
  • pre-operation callback que se activa en cada solicitud de E/S IRP_MJ_DIRECTORY_CONTROL y se encarga de filtrar las solicitudes no relacionadas con la enumeración de directorios, de modo que solo aquellas vinculadas a esta tarea sean pasadas al post-operation callback,
  • post-operation callback que se activa en solicitudes E/S IRP_MJ_DIRECTORY_CONTROL  que pasaron los controles del pre-operation callback. Este callback es responsable de eliminar las entradas correspondientes a archivos ocultos/protegidos de cualquier intento de listado de directorios.

La siguiente lista hardcodeada de nombres de archivo está protegida por el driver:

  • \SystemRoot\Fonts\tpsvc.dll
  • \SystemRoot\Fonts\tpsvcloc.dll
  • \SystemRoot\Fonts\ApphostRagistreationVerifier.exe
  • \SystemRoot\Fonts\X1B5206BDC1743DD.dat
  • \SystemRoot\Fonts\KX1B5206BDC1743DD.dat
  • \SystemRoot\Fonts\KW1B5206BDC1743FP.dat
Protección de la persistencia

El driver invoca CmRegisterCallbackEx para instalar una rutina RegistryCallback responsable de ocultar la clave de registro utilizada para la persistencia del loader de SprySOCKS: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\vds.exe. Como resultado, cualquier intento de abrir o enumerar esta clave es filtrado por el driver.

Componentes de WIN_PLUS

En la versión WIN_PLUS de SprySOCKS, primero descubrimos el contenedor cifrado malicioso en nuestra telemetría, con la primera detección fechada en julio de 2024 en el dispositivo de una víctima en Pakistán. Este contenía el backdoor SprySOCKS y el loader de SprySOCKS.

La configuración C&C estaba presente y se muestra en la Figura 9.

Figure 9. C&C configuration from the WIN_PLUS version of SprySOCKS
Figura 9. Configuración C&C de la versión WIN_PLUS de SprySOCKS

El contenedor cifrado se encontraba en la siguiente ruta del sistema comprometido:

C:\Windows\System32\spool\drivers\color\config.dat

Una vez descifrado, el contenedor contiene el loader de SprySOCKS y el propio backdoor SprySOCKS. Un análisis posterior del backdoor contenido en este archivo mostró que, en este caso, parecía existir un componente adicional responsable de cargar el loader de SprySOCKS desde el contenedor cifrado. Este componente —referido como first-stage loader en este análisis— debe instalarse como un print processor bajo la siguiente clave de registro:

HKLM\SYSTEM\ControlSet001\Control\Print\Environments\Windows x64\Print Processors\VSPMsg

Curiosamente, al buscar en nuestra telemetría cualquier elemento relacionado con la cadena VSPMsg, descubrimos un archivo desplegado en dos dispositivos de víctimas en Honduras en la ruta C:\Windows\System32\spool\prtprocs\x64\VSPMsg.dll. Este archivo resultó ser el first-stage loader responsable de ejecutar el loader de SprySOCKS desde el archivo config.dat mencionado anteriormente.

En la figura 10 se ilustra un diagrama de ejecución de la variante SprySOCKS WIN_PLUS.

Figure 10. SprySOCKS WIN_PLUS variant execution scheme
Figura 10. Esquema de ejecución de la varianteSprySOCKS WIN_PLUS
Loader de primera etapa

Este loader comienza verificando si fue ejecutado por spoolsv.exe y finaliza su ejecución en caso contrario; esto oculta su comportamiento frente a sandboxes automatizadas de análisis de malware, ya que está diseñado para ejecutarse como un print processor. Luego continúa descifrando el loader de SprySOCKS desde el contenedor cifradoC:\Windows\System32\spool\drivers\‌color\config.dat. Primero descifra el loader con AES de 128 bits en modo ECB utilizando la clave hardcodeada uXQLESMXGaRMs6BL, y posteriormente lo inyecta en un nuevo proceso svchost.exe mediante la técnica de process doppelgänging. Mientras tanto, el loader de SprySOCKS se escribe en un archivo temporal, con un nombre que comienza con el prefijo TH, dentro del directorio %TEMP %.

La muestra exporta dos funciones:

  • GetErrorMessageModule
  • SetErrorMessageModule

Mientras que la función SetErrorMessageModule no realiza ninguna acción, la función GetErrorMessageModule está diseñada para establecer la persistencia del propio loader. Al ejecutarse, registra el loader como un print processor creando la clave de registro HKLM\SYSTEM\ControlSet001\Control\Print\Environments\Windows x64\Print Processors\VSPMsg, estableciendo el valor de registro Driver en VSPMsg.dll y copiando el archivo C:\ProgramData\Microsoft Event\PFs\VSPMsg.dll, que está codificado de forma fija, al directorio C:\Windows\System32\spool\prtprocs\x64\. A continuación, copia el contenedor cifrado de C:\ProgramData\Microsoft Event\PFs\config.dat a C:\Windows\System32\spool\drivers\color\config.dat y, una vez hecho esto, genera y coloca el script por lotes affair-build.bat en el directorio C:\Windows\System32\spool\drivers\color\ y lo ejecuta. Como se muestra en la Figura 11, el propósito de este script es cubrir los rastros del loader eliminando los archivos del directorio original de despliegue y desencadenando la la ejecución del print processor recién instalado al reiniciar el servicio de print spooler.

Figure 11. affair-build.bat batch script used by the first-stage SprySOCKS WIN_PLUS loader
Figura 11. Script por lotes affair-build.bat utilizado por el loader SprySOCKS WIN_PLUS de primera etapa
SprySOCKS loader

Este loader comienza creando un mutex con el nombre hardcodeado fqwhi2d1qaz2, y luego procede a cargar el backdoor SprySOCKS desde el contenedor cifrado ubicado en C:\Windows\System32\spool\drivers\color\‌config.dat. Descifra el backdoor utilizando AES de 128 bits en modo ECB con la clave hardcodeada uXQLESMXGaRMs6BL , y posteriormente lo inyecta en un nuevo proceso svchost.exe mediante la técnica de process doppelgänging. Mientras tanto, el loader de SprySOCKS se escribe en un archivo temporal con un nombre que comienza con el prefijo TH, dentro del directorio %TEMP %

Backdoor SprySOCKS

Finalmente, pasamos al análisis del backdoor SprySOCKS en sí. En ambas variantes, WIN_DRV y WIN_PLUS, la funcionalidad del backdoor es casi idéntica, y las diferencias se limitan a las rutas de archivos específicas utilizadas, las claves de registro empleadas y, como ya se mencionó, la versión WIN_PLUS  no utiliza el driver RawWNPF para lograr un mayor nivel de sigilo.

Ambas variantes analizadas en este informe son DLLs con el nombre original PrcsServer.dll que exportan una función llamada Stop. Al inicio crean un mutex llamado prcs-server-run y luego proceden a inicializar la funcionalidad principal del backdoor, que incluye la inicialización y ejecución de los canales de comunicación con el C&C (basados en la configuración hardcodeada) y la activación del keylogger. Además, la versión WIN_DRV del backdoor inicializa el driver RawWNPF invocando su IOCTL 0x222000 , y luego oculta su propio proceso invocando el IOCTL 0x220350 .

El keylogging se activa únicamente si existe un archivo INI en %appdata%\Microsoft\Vault\lgf.dat que contenga una sección config con una propiedad llamada key establecida en 1. Si se cumplen estas condiciones, ambas variantes crean un mutex llamado Global\{DCAA7ED8-521B-4EAB-BE21-65254CF59239} y registran periódicamente datos del portapapeles junto con el título de la ventana activa y las pulsaciones de teclado en el archivo%appdata%\Microsoft\Vault\lg.dat. Los datos de este archivo se cifran utilizando un cifrado XOR de un solo byte con la clave 0x44.

Comunicación C&C

El backdoor soporta tres protocolos para comunicarse con el C&C — TCP, UDP y WebSocket — y puede actuar tanto como cliente como servidor. La funcionalidad de red se basa en gran medida en el framework HP-Socket, y algunas funciones criptográficas fueron implementadas utilizando la librería Crypto++.

La configuración del C&C está embebida en el backdoor y puede incluir:

  • hasta tres direcciones IP con sus respectivos puertos, cada una especificando una dirección de C&C y su puerto para uno de los canales de comunicación (TCP, UDP o WebSocket), y
  • hasta tres números de puerto que indican en qué puertos debe escuchar el backdoor para nuevas conexiones (uno para servidor TCP, uno para servidor UDP y uno para servidor WebSocket).

En la figura 9 se muestra un ejemplo de configuración de la versión WIN_PLUS, que contiene:

  • La dirección y el puerto C&C para el canal de comunicación TCP: 207.148.78[.]36:443.
  • La dirección y el puerto C&C para el canal de comunicación UDP: 207.148.78[.]36:53.
  • La dirección y el puerto C&C para el canal de comunicación WebSocket: 207.148.78[.]36:80.
  • El puerto de escucha del servidor TCP del backdoor: 53781.

Antes de iniciar cualquier conexión o servidor, la versión WIN_DRV de SprySOCKS oculta las conexiones hacia/desde las direcciones o puertos definidos en la configuración invocando los IOCTLs 0x220340 y 0x220200del driver RawWNPF. Como resultado, estas conexiones no aparecen en la salida de herramientas como netstat.exe, aunque estén activas. Además, ambas versiones del backdoor ejecutan la utilidad netsh.exe dos veces:

netsh.exe netsh advfirewall firewall delete rule name="Core Networking - Packet Too Big(ICMPv6 - In)"

netsh advfirewall firewall add rule name="Core Networking - Packet Too Big(ICMPv6 - In)" dir=in action=allow protocol=tcp localport=53781

El primer comando elimina una regla específica del firewall, y el segundo agrega una nueva regla con el mismo nombre, permitiendo todo el tráfico TCP entrante dirigido al puerto del servidor TCP del backdoor definido en la configuración.

Si la configuración de C&C está vacía (como en el caso de la versión  WIN_DRV  detectada en VirusTotal), el backdoor inicia un servidor TCP que escucha en un puerto aleatorio en el sistema comprometido y oculta este puerto invocando el IOCTL 0x220200 del driver RawWNPF. Esta invocación no solo evita que el servidor TCP aparezca en herramientas de monitoreo estándar, sino que también activa la funcionalidad de desvío de TCP proporcionada por el driver. Esta característica permite a los atacantes enviar comandos al backdoor sin conocer el puerto real en el que está escuchando, simplemente enviando datos TCP especialmente diseñados a cualquier puerto TCP abierto en la máquina víctima.

Para el canal de comunicación TCP, el protocolo C&C parece ser el mismo que en la versión Linux analizada en el informe de Trend Micro. Antes de enviar los datos reales, se envía un encabezado de 12 bytes que contiene el CRC de 32 bits del resto del encabezado, un valor mágico DWORD 0xACACBCBC y un DWORD que especifica el tamaño de los datos que siguen al encabezado.

Para los canales UDP y WebSocket, los valores mágicos difieren, al igual que el formato y tamaño del encabezado de los mensajes. En el canal UDP, el valor mágico es 0xACACBFBC  y se encuentra en el offset 0x1C dentro de un encabezado de 36 bytes, seguido de un DWORD que indica el tamaño de los datos. En el canal WebSocket, el valor mágico 0x1BDCCBAA  se utiliza como MaskingKey dentro del encabezado WebSocket. La Figura 12 muestra una captura de tráfico de red con los valores mágicos para cada canal de comunicación.

Figure 12. SprySOCKS network-traffic capture showing the magic values
Figura 12. Captura de tráfico de red de SprySOCKS que muestra los valores mágicos utilizados en los canales de comunicación C&C TCP, UDP y WebSocket (de arriba abajo, respectivamente)

A continuación del encabezado (header) se encuentra, nuevamente, un CRC de 32 bits, seguido del valor WORD 0x0003 (probablemente indicando el método de cifrado), y luego datos cifrados con AES de 128 bits en modo ECB (utilizando la clave hardcodeada QFTHEYjzX3RBOMgZ) que han sido codificados en base64.

En la Figura 13 se muestra un ejemplo de un mensaje C&C antes y después de la decodificación y el descifrado.

Figure 13. Example SprySOCKS C&C message
Figura 13. Ejemplo de un mensaje C&C de SprySOCKS tal y como se ve en Wireshark (izquierda) y su contenido tras la decodificación y el descifrado (derecha)

El valor __msgid  dentro del mensaje de C&C descifrado se utiliza para especificar un comando, identificado por un message ID, que debe ser ejecutado por el backdoor. La lista de message IDs soportados por el backdoor, junto con su descripción, puede encontrarse en la Tabla 3.Cabe destacar que no hemos analizado todos estos comandos en profundidad; por lo tanto, algunas descripciones son solo una visión general aproximada de la parte del código o funcionalidad con la que se relaciona cada message ID.

Tabla 3. Comandos C&C de SprySOCKS; las descripciones marcadas con * son valoraciones preliminares

Message ID Description
0x09 Collect client (victim) system information, including: computer name, OS version, network adapter information, information about memory, CPU information, current privileges, system language and version, current time, and the backdoor version (1.8) and version type (WIN_DRV or WIN_PLUS).
0x0A Start an interactive console.
0x0B Write into the interactive console.
0x0D Stop the interactive console.
0x0E Specify an additional communication channel (do not start the channel). Likely to specify an additional backup C&C.
0x0F Send C&C message to a different target.*
0x11 Enumerate all processes.
0x12 Enumerate modules of a process specified by a PID.
0x13 Terminate a process specified by a PID.
0x14 Close all connections.
0x16 Get current communication channel information.
0x17 Specify additional communication channels (TCP, UDP, or WebSocket) and start them.
0x19 Uninstall the backdoor and exit.
0x1E Enumerate all services.
0x1F Configure StartType for a specified service.
0x20 Start services with a specified name.
0x21 Invoke the ControlService function with a specified dwControl parameter.
0x22 Delete a specified service from the service manager. This does not stop the service if it’s running.
0x23 Initialize SOCKS proxy.
0x24 Terminate SOCKS proxy.*
0x25 Send data through SOCKS proxy.
0x26 SOCKS proxy-related command.*
0x2A Upload a specified file.*
0x2B File-transfer-related helper command.*
0x2C Download a specified file.*
0x2D File-transfer-related helper command.*
0x3C Enumerate free disk space.
0x3D List files in the specified directory.
0x3E Delete a specified file.
0x3F Create a specified directory.
0x40 Rename a specified file.
0x41 Execute an existing file.
0x42 Copy a specified file.
0x43 List files from the Recent Windows directories for the logged-in user:
%APPDATA%\Microsoft\Windows\Recent\
%APPDATA%\Microsoft\Office\Recent\

 

Infraestructura de red

En esta campaña se ha identificado una única dirección C&C: 207.148.78[.]36, hardodeada en la configuración (mostrada en la Figura 9) de la variante WIN_PLUS del backdoor SprySOCKS.

Puertos de la configuración que debería utilizar el backdoor para comunicarse con el C&C:

  • TCP: 443
  • UDP: 53
  • WebSocket: 80

Tal y como se menciona en el informe de Trend Micro, la dirección IP 207.148.75[.]122, del mismo rango de IP 207.148.64.0/20 que el C&C anterior, fue utilizada por los operadores de FishMonger como servidor de entrega de SprySOCKS en junio de 2023. Este rango de IP pertenece al proveedor de alojamiento en la nube Vultr.

Conclusión

El descubrimiento de una variante para Windows de SprySOCKS, previamente conocida como un backdoor exclusivo de Linux, representa una expansión significativa de las capacidades multiplataforma de FishMonger. Nuestro análisis muestra que el port a Windows conserva gran parte de la arquitectura core de su contraparte en Linux —incluyendo el protocolo de C&C, el cifrado utilizado y la lógica general de manejo de comandos— mientras incorpora mecanismos nativos de Windows donde es necesario y mejora el nivel de sigilo del backdoor mediante el uso de kernel drivers. Considerando los indicios limitados sobre la posible participación de un UEFI bootkit, recomendamos monitorear de cerca las actividades de este grupo.

Para cualquier consulta sobre nuestra investigación publicada en WeLiveSecurity, póngase en contacto con nosotros en threatintel@eset.com.
ESET Research ofrece informes privados de inteligencia sobre APT y fuentes de datos. Para cualquier consulta sobre este servicio, visite la página de ESET Threat Intelligence.

IoCs

Archivos

SHA‑1 Filename Detection Description
955BFC3DCC867256F9F46A606DEB0779FA3416D8 KX1B5206BDC1743DD.dat Win64/SprySOCKS.A Encrypted SprySOCKS DriverLoader driver.
44DC4A08C5EB0972C8E18B0E01284E06F09006BB bthcam.sys Win64/Agent.ESB SprySOCKS DriverLoader driver.
AB87B29B6F79487C75CA08D102E79001E536F083 KW1B5206BDC1743FP.dat Win64/SprySOCKS.A Encrypted SprySOCKS RawWNPF driver.
6490B8E4AADE25A3EE2DA9A47F312DB2122470BC X1B5206BDC1743DD.dat Win64/SprySOCKS.A Encrypted container of the encrypted WIN_DRV variant of SprySOCKS backdoor, encrypted SprySOCKS RawWNPF and SprySOCKS DriverLoader drivers.
E7484C24B88A1A2407A8F09D734F9A993670285B klelam00007.zip Win64/Agent.CXZ
Win64/SprySOCKS.A
BAT/Runner.KS
ZIP archive from VirusTotal containing the WIN_DRV variant of SprySOCKS, along with all the backdoor's components; clean binaries used for side-loading are included.
621D1952839BE4B0A1B0E66E87BCE5062CA368ED tpsvcloc.dll Win64/Agent.CXZ SprySOCKS loader.
2457EED2AB28E37741F10914EF929DAD2C8079D4 VSPMsg.dll Win64/Agent.CXZ First-stage loader responsible for launching the SprySOCKS loader.
D2C706B1EAF662BF0CE124B5032F73ED84BDA24A N/A Win64/SprySOCKS.A WIN_PLUS variant of the SprySOCKS backdoor.
5F3B87CEF56683D9A9E19186E0FD0D8019B559C4 N/A Win64/Agent.CXZ SprySOCKS loader.
C793CA31E3F6628B5C8986146953BF66232E9A30 config.dat Win64/SprySOCKS.A Encrypted container of the WIN_PLUS variant of the SprySOCKS backdoor and its loader.
037DB2445F3D72388CB2CF8510563148E5A184BE N/A BAT/Runner.KS Batch script that persists the WIN_DRV variant of SprySOCKS.

Red

IP Domain Hosting provider First seen Details
207.148.78[.]36 N/A IRT‑CHOOPALLC‑AP N/A C&C IP hardcoded in the SprySOCKS backdoor (WIN_PLUS variant).

Técnicas MITRE ATT&CK

Esta tabla se ha elaborado utilizando la versión 19 del marco MITRE ATT&CK.

Tactic ID Name Description
Reconnaissance T1592.004 Gather Victim Host Information: Client Configurations SprySOCKS can collect information about the compromised device, including: computer name, OS version, information about memory and CPU, current privileges, system language and version, current time, and more.
T1590.005 Gather Victim Network Information: IP Addresses SprySOCKS can collect information about the compromised device, including information about network interfaces and assigned IP addresses.
Resource Development T1587.001 Develop Capabilities: Malware FishMonger has developed custom malware for its operations, including the SprySOCKS backdoor.
Execution T1059.003 Command and Scripting Interpreter: Windows Command Shell SprySOCKS can launch an interactive cmd.exe command shell, which allows the attackers to execute commands remotely on the compromised machine.
T1053.005 Scheduled Task/Job: Scheduled Task SprySOCKS uses a scheduled task to execute its loader on system start.
T1569.002 System Services: Service Execution SprySOCKS abuses system services for both one-time and persistent execution.
T1106 Native API FishMonger has used Windows APIs to execute code within a victim’s system.
Persistence T1547.012 Boot or Logon Autostart Execution: Print Processors To achieve persistence, FishMonger installs its malicious loader as a print processor.
Privilege Escalation T1546.012 Event Triggered Execution: Image File Execution Options Injection SprySOCKS can install itself as a debugger for the Virtual Disk Service by modifying HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\vds.exe\debugger.
Stealth T1205.002 Traffic Signaling: Socket Filters SprySOCKS uses the RawWNPF kernel driver to install packet filters capable of redirecting any inbound TCP traffic to the configured local port if a special magic value is detected in the packet.
T1134.002 Access Token Manipulation: Create Process with Token FishMonger uses CreateProcessAsUser to execute a new process with a token obtained from the print spooler service.
T1622 Debugger Evasion SprySOCK’s RawWNPF driver uses the KdDisableDebugger function to disable the kernel debugger, if active.
T1140 Deobfuscate/Decode Files or Information SprySOCKS loader decrypts the SprySOCKS backdoor from an encrypted file. Additionally, most of the strings in the SprySOCKS components are encrypted.
T1070.004 Indicator Removal: File Deletion The SprySOCKS loader removes original files from the deployment directory after copying them and setting up persistence.
T1070.009 Indicator Removal: Clear Persistence SprySOCKS loader removes a service registry value associated with the previously installed malicious minifilter driver after executing the driver.
T1027.007 Obfuscated Files or Information: Dynamic API Resolution SprySOCKS components use dynamic API resolution.
T1027.013 Obfuscated Files or Information: Encrypted/Encoded File SprySOCKS components are stored in an AES-encrypted file on the victim’s drive.
T1055.013 Process Injection: Process Doppelgänging The SprySOCKS loader uses process doppelgänging to inject the backdoor into the svchost.exe process.
T1014 Rootkit FishMonger uses the RawWNPF kernel driver, which serves as a rootkit responsible for hiding the SprySOCKS malicious activity.
T1497 Virtualization/Sandbox Evasion SprySOCKS uses several anti-emulation techniques to prevent automated analysis by emulators or sandboxes.
T1574.002 Hijack Execution Flow: DLL Side-Loading FishMonger uses DLL side-loading to execute the SprySOCKS backdoor.
Defense Impairment T1562.004 Disable or Modify System Firewall SprySOCKS adds a firewall rule allowing any inbound traffic sent to the backdoor’s listening port.
Discovery T1010 Application Window Discovery SprySOCKS retrieves the active foreground window name as a part of its keylogging functionality.
T1083 File and Directory Discovery SprySOCKS can obtain file and directory listings from the compromised system.
T1518.001 Software Discovery: Security Software Discovery SprySOCKS components check for the presence of security and sandboxing product libraries (snxhk.dll, SxWrapper.dll, SxIn.dll, SXIn64.dll, SbieDll.dll, and cmdvrt32.dll) in their own processes.
T1082 System Information Discovery SprySOCKS can collect information about the compromised device, including: computer name, OS version, information about memory and CPU, current privileges, system language and version, current time, and more.
T1614.001 System Location Discovery: System Language Discovery SprySOCKS can collect information about the compromised device, including system language.
T1007 System Service Discovery SprySOCKS can enumerate all services on the system.
T1124 System Time Discovery SprySOCKS can collect information about the compromised device, including current system time.
Collection T1056.001 Input Capture: Keylogging SprySOCKS implements a keylogger.
T1115 Clipboard Data SprySOCKS logs clipboard data, along with the captured keystrokes, as a part of its keylogging functionality.
Command and Control T1132.001 Data Encoding: Standard Encoding SprySOCKS uses base64 encoding in its custom C&C communication protocol.
T1573.001 Encrypted Channel: Symmetric Cryptography SprySOCKS encrypts data sent to, and decrypts data received from, the C&C with 128-bit AES.
T1008 Fallback Channels In addition to the TCP communication channel, SprySOCKS can contact its C&C using UDP and WebSocket channels.
T1665 Hide Infrastructure SprySOCKS’s RawWNPF driver hides the backdoor’s active connections from being enumerated when using network tools such as netstat.exe.
T1571 Non-Standard Port SprySOCKS uses nonstandard ports to communicate with the C&C.
T1095 Non-Application Layer Protocol SprySOCKS uses nonstandard protocols to communicate with the C&C.
Exfiltration T1041 Exfiltration Over C2 Channel SprySOCKS can upload various files from the compromised system to the C&C.