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.
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.
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.
La figura 4 muestra la cadena de ejecución de la variante WIN_DRV de SprySOCKs
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.l 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 |
| 955BFC3DCC867256F9F4 |
KX1B5206BDC |
Win64/SprySOCKS.A | Encrypted SprySOCKS DriverLoader driver. |
| 44DC4A08C5EB0972C8E1 |
bthcam.sys | Win64/Agent.ESB | SprySOCKS DriverLoader driver. |
| AB87B29B6F79487C75CA |
KW1B5206BDC |
Win64/SprySOCKS.A | Encrypted SprySOCKS RawWNPF driver. |
| 6490B8E4AADE25A3EE2D |
X1B5206BDC1 |
Win64/SprySOCKS.A | Encrypted container of the encrypted WIN_DRV variant of SprySOCKS backdoor, encrypted SprySOCKS RawWNPF and SprySOCKS DriverLoader drivers. |
| E7484C24B88A1A2407A8 |
klelam00007 |
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. |
| 621D1952839BE4B0A1B0 |
tpsvcloc.dll | Win64/Agent.CXZ | SprySOCKS loader. |
| 2457EED2AB28E37741F1 |
VSPMsg.dll | Win64/Agent.CXZ | First-stage loader responsible for launching the SprySOCKS loader. |
| D2C706B1EAF662BF0CE1 |
N/A | Win64/SprySOCKS.A | WIN_PLUS variant of the SprySOCKS backdoor. |
| 5F3B87CEF56683D9A9E1 |
N/A | Win64/Agent.CXZ | SprySOCKS loader. |
| C793CA31E3F6628B5C89 |
config.dat | Win64/SprySOCKS.A | Encrypted container of the WIN_PLUS variant of the SprySOCKS backdoor and its loader. |
| 037DB2445F3D72388CB2 |
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. |








