Se sabe que los ciberdelincuentes se acercan a sus objetivos haciéndose pasar por reclutadores de empresas, tentándoles con falsas ofertas de empleo. Después de todo, ¿qué mejor momento para atacar que cuando la víctima potencial está distraída con la posibilidad de conseguir un trabajo? Desde principios de 2024, los investigadores de ESET han observado una serie de actividades maliciosas alineadas con Corea del Norte, en las que los operadores, haciéndose pasar por cazatalentos envían a sus objetivos proyectos de software que ocultan malware de robo de información. Llamamos a este grupo de actividades DeceptiveDevelopment.
Como parte de un falso proceso de entrevista de trabajo, los operadores de DeceptiveDevelopment piden a sus objetivos que realicen una prueba de codificación, como añadir una función a un proyecto existente, con los archivos necesarios para la tarea normalmente alojados en repositorios privados en GitHub u otras plataformas similares. Por desgracia para el candidato, estos archivos están troyanizados: una vez descargado y ejecutado el proyecto, el ordenador de la víctima se ve comprometido con el malware de primera fase de la operación, BeaverTail.
DeceptiveDevelopment fue descrito públicamente por primera vez por Phylum y Unit 42 en 2023, y ya ha sido parcialmente documentado bajo los nombres Contagious Interview y DEV#POPPER. Hemos llevado a cabo un análisis más detallado de este grupo de actividades y de los métodos de acceso iniciales, la infraestructura de red y el conjunto de herramientas de su operador, incluyendo nuevas versiones de las dos familias de malware utilizadas por DeceptiveDevelopment: InvisibleFerret y la mencionada BeaverTail.
Puntos clave de este blogpost:
- DeceptiveDevelopment se dirige a desarrolladores de software freelance a través de spearphishing en sitios de búsqueda de empleo y freelancing, con el objetivo de robar carteras de criptomonedas e información de inicio de sesión de navegadores y gestores de contraseñas.
- Activa desde al menos noviembre de 2023, esta operación utiliza principalmente dos familias de malware: BeaverTail (infostealer, downloader) e InvisibleFerret (infostealer, RAT).
- Las tácticas, técnicas y procedimientos (TTP) de DeceptiveDevelopment son similares a las de otras operaciones conocidas alineadas con Corea del Norte.
Observamos por primera vez esta campaña de DeceptiveDevelopment a principios de 2024, cuando descubrimos proyectos troyanizados alojados en GitHub con código malicioso oculto al final de largos comentarios, lo que desplazaba el código fuera de la pantalla. Estos proyectos contenían los programas maliciosos BeaverTail e InvisibleFerret. Además de analizar las dos familias de malware, también empezamos a investigar la infraestructura de C&C detrás de la campaña. Desde entonces, hemos seguido la pista de este clúster y sus avances en la estrategia y las herramientas utilizadas en estos ataques en curso. Este blogpost describe las TTP de esta campaña, así como el malware que utiliza.
Perfil de DeceptiveDevelopment
DeceptiveDevelopment es un grupo de actividades alineado con Corea del Norte que actualmente no atribuimos a ningún actor de amenazas conocido. Los operadores detrás de DeceptiveDevelopment se dirigen a desarrolladores de software en Windows, Linux y macOS. Principalmente roban criptomonedas para obtener beneficios económicos, con un posible objetivo secundario de ciberespionaje.
Para acercarse a sus objetivos, estos operadores utilizan perfiles de reclutadores falsos en las redes sociales, al igual que el grupo Lazarus en la Operación DreamJob (como se describe en este blog de WeLiveSecurity). Sin embargo, mientras que la Operación DreamJob iba dirigida a ingenieros de defensa y aeroespaciales, DeceptiveDevelopment se dirige a desarrolladores de software autónomos, a menudo implicados en proyectos de criptomonedas. Para comprometer los ordenadores de sus víctimas, DeceptiveDevelopment les proporciona bases de código troyanizadas que despliegan backdoors como parte de un falso proceso de entrevista de trabajo.
Victimología
Los objetivos principales de esta campaña de DeceptiveDevelopment son desarrolladores de software, principalmente aquellos involucrados en proyectos de criptomoneda y finanzas descentralizadas. Los atacantes no distinguen en función de la ubicación geográfica y su objetivo es comprometer a tantas víctimas como sea posible para aumentar la probabilidad de extraer con éxito fondos e información.
Hemos observado cientos de víctimas diferentes en todo el mundo, utilizando los tres principales sistemas operativos: Windows, Linux y macOS. Entre ellos había desde desarrolladores junior que acababan de empezar su carrera como autónomos hasta profesionales muy experimentados en la materia. Sólo observamos conversaciones atacante-víctima en inglés, pero no podemos afirmar con certeza que los atacantes no utilicen herramientas de traducción para comunicarse con víctimas que no hablen ese idioma. En la figura 1 se muestra un mapa con la distribución global de las víctimas.

Atribución
Consideramos que DeceptiveDevelopment es un clúster de actividad alineado con Corea del Norte con una confianza alta basada en varios elementos:
- Observamos conexiones entre cuentas de GitHub controladas por los atacantes y cuentas que contienen CV falsos utilizados por trabajadores de TI norcoreanos. Estas personas solicitan trabajo en empresas extranjeras con identidades falsas con el fin de cobrar salarios para ayudar a financiar el régimen. Las conexiones observadas eran seguimientos mutuos entre perfiles de GitHub en los que una parte estaba asociada a DeceptiveDevelopment y la otra contenía CV falsos y otro material relacionado con la actividad de los trabajadores informáticos norcoreanos. Unit42 también observó conexiones similares. Por desgracia, las páginas de GitHub se cerraron antes de que pudiéramos registrar todas las pruebas.
- Las TTP (uso de falsos reclutadores, desafíos laborales troyanizados y software utilizado durante las entrevistas) son similares a otras actividades alineadas con Corea del Norte(Moonstone Sleet y las campañas DreamJob y DangerousPassword de Lazarus).
Además de las conexiones entre los perfiles de GitHub, el malware utilizado en DeceptiveDevelopment es bastante simple. Esto concuerda con los informes de Mandiant, que afirman que el trabajo de los informáticos suele ser de baja calidad.
Mientras vigilábamos la actividad de DeceptiveDevelopment, vimos numerosos casos que mostraban una falta de atención a los detalles por parte de los actores de la amenaza. En algunos de ellos, los autores no eliminaron las notas de desarrollo ni comentaron las direcciones IP locales utilizadas para el desarrollo y las pruebas. También vimos muestras en las que parece que se olvidaron de ofuscar la dirección de C&C después de cambiarla; esto se puede ver en la Figura 2. Además, el malware utiliza herramientas de ofuscación de libre acceso, a veces con enlaces en los comentarios del código.

Análisis técnico
Acceso inicial
Para hacerse pasar por reclutadores, los atacantes copian perfiles de personas existentes o incluso construyen nuevos personajes. A continuación, se dirigen directamente a sus víctimas potenciales en plataformas de búsqueda de empleo y de trabajo autónomo o publican en ellas ofertas de empleo falsas. Al principio, los agresores utilizaban perfiles nuevos y se limitaban a enviar enlaces a proyectos maliciosos de GitHub a través de LinkedIn a sus objetivos. Más tarde, empezaron a utilizar perfiles que parecían establecidos, con muchos seguidores y conexiones, para parecer más fiables, y se extendieron a más sitios web de búsqueda de empleo y alojamiento de código. Mientras que algunos de estos perfiles son creados por los propios atacantes, otros son perfiles potencialmente comprometidos de personas reales en la plataforma, modificados por los atacantes.
Algunas de las plataformas en las que se producen estas interacciones son genéricas de búsqueda de empleo, mientras que otras se centran principalmente en proyectos de criptomoneda y blockchain, por lo que están más en línea con los objetivos de los atacantes. Las plataformas incluyen:
- LinkedIn,
- Upwork,
- Freelancer.com,
- We Work Remotely,
- Moonlight, y
- Crypto Jobs List.
El vector de compromiso más comúnmente observado consiste en que el falso reclutador proporciona a la víctima un proyecto troyanizado bajo el pretexto de un reto de contratación o de ayudar al "reclutador" a solucionar un error a cambio de una recompensa económica.
Las víctimas reciben los archivos del proyecto directamente a través de la transferencia de archivos en el sitio o a través de un enlace a un repositorio como GitHub, GitLab o Bitbucket. Se les pide que descarguen los archivos, añadan funciones o corrijan errores e informen al reclutador. Además, se les pide que creen y ejecuten el proyecto para probarlo, que es donde se produce el compromiso inicial. Los repositorios utilizados suelen ser privados, por lo que primero se pide a la víctima que facilite su ID de cuenta o dirección de correo electrónico para poder acceder a ellos, muy probablemente para ocultar la actividad maliciosa a los investigadores.
A pesar de ello, observamos muchos casos en los que estos repositorios estaban disponibles públicamente, pero nos dimos cuenta de que pertenecían en su mayoría a víctimas que, tras completar sus tareas, los subían a sus propios repositorios. La figura 3 muestra un ejemplo de proyecto troyanizado alojado en GitHub. Hemos informado de todos los códigos maliciosos observados a los servicios afectados.

Los proyectos troyanizados pertenecen a una de estas cuatro categorías:
- retos de contratación,
- proyectos de criptomonedas,
- juegos (normalmente con funcionalidad blockchain), y
- juegos de azar con funciones de blockchain/criptomoneda.
Estos repositorios son a menudo duplicados de proyectos de código abierto o demos existentes, con pocos o ningún cambio aparte de añadir el código malicioso y cambiar el archivo README. Algunos de los nombres de proyectos maliciosos y los nombres de las cuentas controladas por atacantes que los operan (donde pudimos evaluarlos) se enumeran en la Tabla 1.
Tabla 1. Nombres de proyectos observados y autores de repositorios/commits
Project | Author | Project | Author |
Website-Test | Hiring-Main-Support | casino-template-paid | bmstore |
guru-challenge | Chiliz-Guru | casino-demo | casinogamedev |
baseswap_ver_4 | artemreinv | point | freebling-v3 |
metaverse-backend | metaverse-ritech | Blockchain-game | N/A |
lisk-parknetwork | MariaMar1809 | 3DWorld-tectera-beta | N/A |
También observamos que los atacantes se hacían pasar por proyectos y empresas existentes utilizando nombres similares o añadiendo LLC, Ag, o Inc (abreviaturas de tipos de empresas legales) a los nombres, como se ve en la Tabla 2.
Tabla 2. Nombres de proyectos y repositorios/empresas observados Nombres de proyectos observados y autores de repositorios/commits suplantando proyectos legítimos
Project | Author |
Lumanagi-Dex | LUMANAGI-LLC |
DARKROOM-NFT | DarkRoomAg |
DarkRoom | WonderKiln-Inc |
Los atacantes suelen utilizar un truco ingenioso para ocultar su código malicioso: lo colocan en un componente del proyecto que por lo demás es benigno, normalmente dentro de código backend no relacionado con la tarea encomendada al desarrollador, donde lo añaden como una sola línea detrás de un largo comentario. De este modo, se desplaza fuera de la pantalla y permanece oculto a menos que la víctima se desplace hasta él o tenga activada la función de ajuste de palabras de su editor de código. Curiosamente, el propio editor de código de GitHub no permite el ajuste de palabras, por lo que el código malicioso es fácil de pasar por alto incluso cuando se mira el código en el repositorio, como se muestra en la Figura 4.

Otro vector de compromiso que observamos consistía en que el falso reclutador invitaba a la víctima a una entrevista de trabajo utilizando una plataforma de conferencias en línea y proporcionaba un enlace a un sitio web desde el que se podía descargar el software de conferencias necesario. El sitio web suele ser un clon del sitio web de una plataforma de conferencias existente, como se ve en la Figura 5, y el software descargado contiene la primera fase del malware.
![Figure 5. Malicious website at mirotalk[.]net, a copy of the legitimate MiroTalk site (sfu.mirotalk.com), serving malware disguised as conferencing software via a click of the Join Room button. Figure 5. Malicious website at mirotalk[.]net](https://web-assets.esetstatic.com/wls/2025/02-25/deceptivedevelopment/figure-5.png)
Conjunto de herramientas
DeceptiveDevelopment utiliza principalmente dos familias de malware como parte de sus actividades, distribuidas en dos etapas. La primera etapa, BeaverTail, tiene una variante JavaScript y otra nativa (escrita en C++ utilizando la plataforma Qt), y se entrega a la víctima disfrazada como parte de un proyecto en el que se le pide que trabaje, un reto de contratación, o dentro de un software de conferencia remota troyanizado como MiroTalk o FreeConference.
BeaverTail actúa como un simple ladrón de inicios de sesión, extrayendo las bases de datos del navegador que contienen los inicios de sesión guardados, y como un descargador para la segunda etapa, InvisibleFerret. Se trata de un malware modular basado en Python que incluye spyware y componentes de backdoor, y que también es capaz de descargar el software legítimo de gestión y monitorización remota AnyDesk para actividades posteriores al ataque. La Figura 6 muestra la cadena de compromiso completa desde el compromiso inicial, pasando por la exfiltración de datos, hasta el despliegue de AnyDesk.

Tanto BeaverTail como InvisibleFerret han sido documentados previamente por Unit 42, Group-IB y Objective-See. Zscaler también publicó una investigación paralela, cuyos resultados podemos confirmar de forma independiente. Nuestro análisis contiene detalles que no se habían comunicado públicamente con anterioridad y presenta una visión global de la actividad maliciosa.
BeaverTail
BeaverTail es el nombre del malware infostealer y downloader utilizado por DeceptiveDevelopment. Existen dos versiones diferentes: una escrita en JavaScript y colocada directamente en los proyectos troyanizados con una simple ofuscación, y versiones nativas, construidas utilizando la plataforma Qt, que se disfrazan de software de conferencias y fueron descritas inicialmente por Objective-See. Ambas versiones presentan grandes similitudes en sus funcionalidades.
Este malware se dirige a sistemas Windows, Linux y macOS, con el objetivo de recopilar información de inicio de sesión guardada y datos de carteras de criptomonedas.
Comienza por obtener la dirección IP y el puerto del C&C. Aunque las direcciones IP varían, los puertos utilizados suelen ser el 1224 o el 1244, lo que hace que la actividad maliciosa en la red sea fácilmente identificable. En la versión JavaScript, la dirección IP y el puerto se ofuscan mediante codificación base64, se dividen en tres partes y se intercambian para evitar la descodificación automática. Otras cadenas también se codifican con base64, a menudo con un carácter ficticio añadido a la cadena resultante para frustrar los intentos de descodificación. La versión nativa tiene la IP, el puerto y otras cadenas almacenadas en texto plano. El código JavaScript ofuscado puede verse en la Figura 7, y el código desofuscado en la Figura 8.


A continuación, BeaverTail busca las extensiones instaladas en los navegadores Google Chrome, Microsoft Edge, Opera y Brave y comprueba si alguna de ellas coincide con nombres de extensiones de una lista codificada de Chrome Web Store o Microsoft Edge Add-ons, que se muestra a continuación. El navegador que aparece entre paréntesis es la fuente de la extensión; ten en cuenta que tanto Opera como Brave también utilizan extensiones de Chrome Web Store, ya que están basados en Chromium.
- nkbihfbeogaeaoehlefnkodbefgpgknn - MetaMask (Chrome)
- ejbalbakoplchlghecdalmeeeajnimhm - MetaMask (Edge)
- fhbohimaelbohpjbbldcngcnapndodjp - Cartera con cadena BNB (Cromo)
- hnfanknocfeofbddgcijnmhnfnkdnaad - Monedero Coinbase (Chrome)
- ibnejdfjmmkpcnlpebklmnkoeoihofec - TronLink (Cromo)
- bfnaelmomeimhlpmgjnjophhpkkoljpa - Phantom (Cromo)
- fnjhmkhhmkbjkkabndcnnogagogbneec - Ronin Wallet (Cromo)
- aeachknmefphepccionboohckonoeemg - Monedero Coin98 (Cromo)
- hifafgmccdpekplomjjkcfgodnhcellj - Crypto.com Wallet (Cromo)
Si se encuentran, se recogen y exfiltran todos los archivos .ldb y .log de los directorios de las extensiones.
Aparte de estos archivos, el malware también tiene como objetivo un archivo que contiene las claves Solana almacenadas en el directorio personal del usuario en .config/solana/id.json. A continuación, BeaverTail busca la información de inicio de sesión guardada en /Library/Keychains/login.keychain (para macOS) o /.local/share/keyrings/ (para Linux). Si existen, las bases de datos de inicio de sesión de Firefox key3.db, key4.db y logins.json de /.mozilla/firefox/ también se filtran durante este tiempo.
Cada muestra de BeaverTail contiene un ID de víctima utilizado para la identificación. Estos ID se utilizan a lo largo de toda la cadena de compromiso como identificadores en todas las descargas y cargas. Sospechamos que estos ID son únicos para cada víctima y se utilizan para conectar la información robada con el perfil público de la víctima.
Los datos recopilados junto con el nombre de host del ordenador y la marca de tiempo actual se cargan en el punto final de la API /uploads del servidor de C&C. A continuación, se descarga un entorno Python independiente en un archivo llamado p2.zip, alojado en el servidor de C&C, para permitir la ejecución de la siguiente etapa. Por último, la siguiente etapa se descarga desde el servidor de C&C (punto final de la API /client/<campaign_ID>) al directorio personal del usuario con el nombre .npl y se ejecuta utilizando el entorno Python descargado.
En agosto de 2024, observamos una nueva versión de JavaScript BeaverTail, en la que el código colocado en el proyecto troyanizado actuaba únicamente como cargador y descargaba y ejecutaba el código de la carga útil real desde un servidor remoto . Esta versión también utilizaba una técnica de ofuscación diferente y añadía cuatro nuevas extensiones de monederos de criptomonedas a la lista de objetivos:
- jblndlipeogpafnldhgmapagcccfchpi - Monedero Kaia (Chrome)
- acmacodkjbdgmoleebolmdjonilkdbch - Monedero Rabby (Chrome)
- dlcobpjiigpikoobohmabehhmhfoodbb - Argent X - Starknet Wallet (Cromo)
- aholpfdialjgjfhomihkjbmgjidlcdno - Exodus Web3 Wallet (Cromo)
Al investigar el sitio web ipcheck[.]cloud, observamos que la página de inicio es una réplica del sitio web malicioso mirotalk[.]net, que sirve malware nativo BeaverTail disfrazado de software de conferencia remota, lo que indica una conexión directa entre el nuevo JavaScript y las versiones nativas de BeaverTail.
InvisibleFerret
InvisibleFerret es un malware Python modular con capacidades para el robo de información y el control remoto de atacantes. Consta de cuatro módulos: principal (el archivo .npl ), carga útil(pay), navegador(bow) y AnyDesk(adc). El malware no dispone de ningún mecanismo de persistencia aparte del cliente AnyDesk desplegado al final de la cadena de compromiso. Tras obtener persistencia a través de AnyDesk, los atacantes pueden ejecutar InvisibleFerret a voluntad.
Curiosamente, la mayor parte de su funcionalidad de backdoor requiere un operador (o comportamiento de script) en el otro lado enviando comandos, decidiendo qué datos exfiltrar y cómo propagar el ataque. En todas las versiones de InvisibleFerret que hemos observado, los componentes del backdoor se activan por orden del operador. La única funcionalidad que no ejecuta el operador es la huella inicial, que se realiza automáticamente.
Módulo principal
El módulo principal, originalmente llamado main, es el archivo .npl que BeaverTail descargó del servidor C&C y guardó en el directorio home. Es responsable de descargar y ejecutar los módulos individuales de carga útil. Todos los módulos contienen una carga útil cifrada mediante XOR y codificada en base64, precedida por cuatro bytes que representan la clave XOR, seguida de código para descifrarla y ejecutarla mediante exec, como se ve en la Figura 9. Cada módulo contiene también la variable sType, que contiene el ID de la víctima actual. Este ID es una copia del ID especificado en la solicitud de descarga. Cuando se realiza una solicitud para descargar el archivo de script, la API del servidor de C&C coloca el ID dado como valor sType en el archivo de script final.

Este módulo contiene una dirección de C&C codificada con base64 y dividida en dos mitades que han sido intercambiadas para dificultar la decodificación. En la mayoría de los casos que observamos, esta dirección era idéntica a la utilizada en la muestra anterior de BeaverTail. El módulo principal descarga el módulo payload de /payload/<campaign_ID> a .n2/pay en el directorio home del usuario y lo ejecuta. Después, si se ejecuta en macOS (determinado por la comprobación de si una llamada a la función platform.system devuelve Darwin), sale. En otros sistemas operativos también descarga el módulo del navegador de /brow/<campaign_ID> a .n2/bow en el directorio personal del usuario y lo ejecuta en una instancia de Python independiente.
Módulo payload
El módulo de payload consta de dos partes: una recoge información y la otra sirve como backdoor. La primera parte contiene una URL de C&C hardcodeada, normalmente similar a las utilizadas anteriormente, y recoge lo siguiente
- el UUID del usuario,
- Tipo de SO,
- Nombre del PC,
- nombre de usuario,
- versión del sistema (release),
- dirección IP local y
- dirección IP pública e información de geolocalización (nombre de la región, país, ciudad, código postal, ISP, latitud y longitud) extraída de http://ip-api.com/json.
Esta información, ilustrada en la Figura 10, se carga en el punto final de la API /keys mediante HTTP POST.

La segunda parte actúa como un backdoor TCP, y una shell inversa TCP, aceptando comandos remotos del servidor C&C y comunicándose a través de una conexión socket. Normalmente utiliza el puerto 1245, pero también hemos observado los puertos 80, 2245, 3001 y 5000. Cabe destacar que la dirección IP de C&C codificada en esta parte era diferente a veces de las anteriores, probablemente para separar la actividad de red final más sospechosa del despliegue inicial.
El segundo payload comprueba si se está ejecutando bajo Windows - si es así, habilita un keylogger implementado usando pyWinHook y un ladrón de portapapeles usando pyperclip, mostrados en la Figura 11. Estos recogen y almacenan cualquier pulsación de tecla. Éstos recogen y almacenan cualquier pulsación de tecla y cambio en el portapapeles en un buffer global y se ejecutan en un hilo dedicado mientras se ejecuta el script.

Después, ejecuta la funcionalidad de backdoor, que consta de ocho comandos, descritos en la Tabla 3.
Tabla 3. Comandos implementados en Comandos implementados en InvisibleFerret
ID | Command | Function | Description |
1 | ssh_cmd | Removes the compromise | · Only supports the delete argument. · Terminates operation and removes the compromise. |
2 | ssh_obj | Executes shell commands | · Executes the given argument[s] using the system shell via Python’s subprocess module and returns any output generated by the command. |
3 | ssh_clip | Exfiltrates keylogger and clipboard stealer data | · Sends the contents of the keylogger and clipboard stealer buffer to the C&C server and clears the buffer. · On operating systems other than Windows, an empty response is sent, as the keylogging functionality is not enabled. |
4 | ssh_run | Installs the browser module | · Downloads the browser module to .n2/bow in the user’s home directory and executes it in a new Python instance (with the CREATE_NO_WINDOW and CREATE_NEW_PROCESS_GROUP flags set on Windows) · Replies to the server with the OS name and get browse. |
5 | ssh_upload | Exfiltrates files or directories, using FTP | · Uploads files to a given FTP server with server address and credentials specified in arguments. · Has six subcommands: · sdira, sdir, sfile, sfinda, sfindr, and sfind. · sdira – uploads everything in a directory specified in args, skipping directories matching the first five elements in the ex_dirs array (listed below). Sends >> upload all start: followed by the directory name to the server when the upload starts, ‑counts: followed by the number of files selected for upload when directory traversal finishes, and uploaded success once everything is uploaded. · sdir – similar to sdira, but exfiltrates only files smaller than 104,857,600 bytes (100 MB) with extensions not excluded by ex_files and directories not excluded by ex_dirs. The initial message to the server is >> upload start: followed by the directory name. · sfile – similar to sdir, but exfiltrates only a single file. If the extension is .zip, .rar, .pdf, or is in the ex_files list (in this case not being used to exclude files for upload, but from encryption), it gets directly uploaded. Otherwise the file is encrypted using XOR with the hardcoded key G01d*8@( before uploading. · sfinda – searches the given directory and all its subdirectories (excluding those in the ex_dirs list) for files matching a provided pattern, and uploads those not matching items in the ex_files list. When starting, sends >> ufind start: followed by the starting directory to the server, followed by ufind success after it finishes. · sfindr – similar to sfinda, but without the recursive search. Searches only the specified directory. · sfind – similar to sfinda, but starts the search in the current directory. |
6 | ssh_kill | Terminates the Chrome and Brave browsers | · Termination is done via the taskkill command on Windows or killall on other systems, as shown in Figure 12. · Replies to the server with Chrome & Browser are terminated. |
7 | ssh_any | Installs the AnyDesk module | · This works identically to the ssh_run command, downloading the AnyDesk module to and executing it from the .n2 folder in the user’s home directory. · Replies to the server with the OS name and get anydesk. |
8 | ssh_env | Uploads data from the user’s home directory and mounted drives, using FTP | · Sends --- uenv start to the server. · Establishes an FTP connection using the server address and credentials provided in the arguments. · On Windows, uploads the directory structure and contents of the Documents and Downloads folders, as well as the contents of drives D to I. · On other systems, uploads the entirety of the user’s home directory and the /Volumes directory containing all mounted drives. · Only uploads files smaller than 20,971,520 bytes (20 MB) and excludes directories matching the ex_dir list and files matching the ex_files, ex_files1, and ex_files2 lists described in Figure 13. · Finishes by sending --- uenv success to the server. |

Cada comando se nombra con el prefijo ssh_ y se le asigna un valor numérico que se utilizará cuando se comunique con el servidor. Por cada comando recibido, se crea un nuevo hilo para ejecutarlo y el cliente comienza inmediatamente a escuchar el siguiente comando. Las respuestas a los comandos se envían de forma asíncrona a medida que los comandos terminan de ejecutarse. La comunicación bidireccional se realiza a través de sockets, en formato JSON, con dos campos
- command - que denota el ID numérico del comando.
- args - que contiene cualquier dato adicional enviado entre el servidor y el cliente.
El script también contiene listas de nombres de archivos y directorios excluidos (como la caché y los directorios temporales de proyectos y repositorios de software) que deben omitirse al exfiltrar datos, y una lista de patrones de nombres interesantes para exfiltrar (archivos de entorno y configuración; documentos, hojas de cálculo y otros archivos que contengan las palabras secret, wallet, private, password, etc.)
Módulo del navegador
El módulo de proa es responsable de robar los datos de inicio de sesión, los datos de autorrelleno y la información de pago guardada por los navegadores web. Los navegadores objetivo son Chrome, Brave, Opera, Yandex, y Edge, todos basados en Chromium, con múltiples versiones listadas para cada uno de los tres principales sistemas operativos (Windows, Linux, macOS) como se muestra en la Figura 13.

Busca en las carpetas de almacenamiento local del navegador (un ejemplo se muestra en la Figura 14) y copia las bases de datos que contienen la información de inicio de sesión y de pago en la carpeta %Temp% en Windows o en la carpeta /tmp en otros sistemas, en dos archivos:
- LoginData.db que contiene la información de inicio de sesión de los usuarios, y
- webdata.db que contiene la información de pago guardada (tarjetas de crédito).

Dado que las contraseñas y los números de tarjetas de crédito guardados se almacenan en un formato cifrado mediante AES, es necesario descifrarlos antes de la exfiltración. Las claves de cifrado utilizadas para ello se obtienen en función del sistema operativo utilizado. En Windows, se extraen del archivo de Local State del navegador, en Linux se obtienen a través del paquete secretstorage, y en macOS se obtienen a través de la security utility, como se ilustra en la Figura 15.

La información recopilada (ver Figura 16) se envía entonces al servidor C&C a través de una petición HTTP POST al endpoint API /keys.

Módulo AnyDesk
El módulo adc es el único mecanismo de persistencia encontrado en esta cadena de compromiso, configurando el acceso AnyDesk al ordenador de la víctima utilizando un archivo de configuración que contiene credenciales de inicio de sesión codificadas.
En Windows, comprueba si el archivo C:/Program Files (x86)/AnyDesk/AnyDesk.exe existe. Si no existe, descarga anydesk.exe desde el servidor de C&C(http://<C&C_IP>:<C&C_port>/anydesk.exe) al directorio personal del usuario.
A continuación, intenta configurar AnyDesk para el acceso del atacante introduciendo valores hash de contraseña, sal de contraseña y sal de token codificados en los archivos de configuración. Si los archivos de configuración no existen o no contienen un determinado valor de sal de contraseña especificado por el atacante, el módulo intenta modificarlos para añadir la información de inicio de sesión codificada. Si esto falla, crea un script PowerShell en el directorio personal del usuario llamado conf.ps1, que contiene código para modificar los archivos de configuración (mostrado en la Figura 17) e intenta ejecutarlo.

Una vez completadas estas acciones, el proceso AnyDesk se cierra y se inicia de nuevo para cargar la nueva configuración. Por último, el módulo adc intenta borrarse llamando a la función os.remove.
Actualización de InvisibleFerret
Más tarde descubrimos una versión actualizada de InvisibleFerret con cambios importantes, utilizada al menos desde agosto de 2024. Ya no está separado en módulos individuales, sino que existe como un único archivo de script de gran tamaño (pero aún conserva los comandos de backdoor para instalar selectivamente los módulos de navegador y AnyDesk). También hay ligeras modificaciones de código para una mayor compatibilidad con macOS, por ejemplo recogiendo el nombre de usuario junto con el nombre de host del ordenador.
Otra modificación que observamos es la adición de un identificador llamado gType, además de sType. Actúa como un identificador secundario de víctima/campaña además de sType cuando se descargan módulos del servidor de C&C (por ejemplo, <C&C_IP>:<port>/<module>/<sType>/<gType>). No hemos visto que se utilice para etiquetar los datos exfiltrados.
Esta nueva versión de InvisibleFerret también ha implementado un comando backdoor adicional, ssh_zcp, capaz de filtrar datos de extensiones de navegador y gestores de contraseñas a través de Telegram y FTP.
Con el nuevo comando, InvisibleFerret primero busca y, si está presente, recopila datos de 88 extensiones de navegador para los navegadores Chrome, Brave y Edge y luego los coloca en una carpeta de almacenamiento en el directorio temporal del sistema. La lista completa de extensiones se puede encontrar en el Apéndice y el código para recoger los datos se muestra en la Figura 18.

Aparte de los datos de las extensiones, el comando también puede extraer información de los monederos de criptomonedas Atomic y Exodus en todos los sistemas, además de 1Password, Electrum, WinAuth, Proxifier4 y Dashlane en Windows. Esto se ilustra en la Figura 19.

A continuación, los datos se archivan y se suben a un chat de Telegram utilizando la API de Telegram con un token de bot, así como a un servidor FTP. Una vez realizada la subida, InvisibleFerret elimina tanto la carpeta de almacenamiento como el archivo.
Módulo de robo de portapapeles
En diciembre de 2024 descubrimos otra versión de InvisibleFerret, que contenía un módulo adicional llamado mlip, descargado desde el endpoint de C&C /mclip/<campaign_ID> a .n2/mlip. Este módulo contiene la funcionalidad de keylogging y robo de portapapeles que fue separada del resto del módulo de carga útil.
Como muestra de un avance en las capacidades técnicas de los operadores, la funcionalidad de keylogging y robo de portapapeles de este módulo se ha limitado únicamente a dos procesos, chrome.exe y brave.exe, mientras que las versiones anteriores de InvisibleFerret registraban todas las pulsaciones de teclas. Los datos recopilados se cargan en un nuevo punto final de la API, /api/clip.
Infraestructura de red
La infraestructura de red de DeceptiveDevelopment se compone de servidores dedicados alojados por proveedores de alojamiento comerciales, siendo los tres proveedores más utilizados RouterHosting (ahora conocido como Cloudzy), Stark Industries Solutions y Pier7ASN. La API del servidor está escrita en Node.js y consta de nueve puntos finales, enumerados en la Tabla 4.
Tabla 4. Puntos finales de la API de C&C de DeceptiveDevelopment
API endpoint | Description |
/pdown | Downloading the Python environment. |
/uploads | BeaverTail data upload. |
/client/<campaign_ID> | InvisibleFerret loader. |
/payload/<campaign_ID> | InvisibleFerret payload module. |
/brow/<campaign_ID> | InvisibleFerret browser module. |
/adc/<campaign_ID> | InvisibleFerret AnyDesk module. |
/mclip/<campaign_ID> | InvisibleFerret keylogger module. |
/keys | InvisibleFerret data upload. |
/api/clip | InvisibleFerret keylogger module data upload. |
La mayor parte de la comunicación de C&C que observamos se realizaba a través de los puertos 1224 o 1244 (ocasionalmente 80 o 3000) para la comunicación de C&C a través de HTTP, y 1245 (ocasionalmente 80, 2245, 3001, 5000, o 5001) para la comunicación de C&C de backdoor a través de sockets TCP. Todas las comunicaciones del cliente al servidor de C&C, excepto la descarga del entorno Python, contienen el ID de campaña. Para las descargas de InvisibleFerret, el ID se añade al final de la URL en la solicitud GET. Para la exfiltración de datos, el ID se envía como parte de la solicitud POST en el campo de tipo. Esto es útil para identificar el tráfico de red y determinar a qué muestra y campaña específica pertenece.
Los ID de campaña( valores sType y gType ) que hemos observado son alfanuméricos y no parecen tener ninguna relación directa con la campaña. Antes de la introducción de gType, algunos de los valores sType eran cadenas base64 que contenían variantes de la palabra team y números, como 5Team9 y 7tEaM;. Tras la introducción de gType, la mayoría de los valores observados para ambos valores eran puramente numéricos, sin el uso de base64.
Conclusión
El clúster DeceptiveDevelopment se suma a la ya amplia colección de esquemas de obtención de dinero empleados por actores alineados con Corea del Norte y se ajusta a una tendencia en curso de cambio de enfoque del dinero tradicional a las criptomonedas. Durante nuestra investigación, observamos cómo se pasaba de herramientas y técnicas primitivas a malware más avanzado y capaz, así como a técnicas más pulidas para atraer a las víctimas y desplegar el malware. Cualquier plataforma de búsqueda de empleo y de trabajo autónomo en línea puede correr el riesgo de ser objeto de abuso para la distribución de malware por parte de falsos reclutadores. Seguimos observando una actividad significativa relacionada con esta campaña y esperamos que DeceptiveDevelopment continúe innovando y buscando más formas de atacar a los usuarios de criptomonedas.
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 APT y fuentes de datos. Para cualquier consulta sobre este servicio, visite la página de ESET Threat Intelligence.
IoCs
Puede encontrar una lista completa de indicadores de compromiso (IoCs) y muestras en nuestro repositorio GitHub.
Archivos
SHA-1 | Filename | Detection | Description |
48E75D6E2BDB2B00ECBF |
FCCCall.exe | Win64/DeceptiveDevelopment.A | Trojanized conferencing app – native BeaverTail. |
EC8B6A0A7A7407CA3CD1 |
pay.py | Python/DeceptiveDevelopment.B | InvisibleFerret payload module. |
3F8EF8649E6B9162CFB0 |
bow.py | Python/DeceptiveDevelopment.C | InvisibleFerret browser module. |
F6517B68F8317504FDCD |
pay_u2GgOA8.py | Python/DeceptiveDevelopment.B | InvisibleFerret new payload module. |
01C0D61BFB4C8269CA56 |
setupTest.js | JS/Spy.DeceptiveDevelopment.A | BeaverTail. |
2E3E1B95E22E4A8F4C75 |
tailwind.config |
JS/Spy.DeceptiveDevelopment.A | BeaverTail. |
7C8724B75BF7A9B8F27F |
conf.ps1 | PowerShell/DeceptiveDevelopment.A | AnyDesk configuration PowerShell script. |
5F5D3A86437082FA512B |
adc.py | Python/DeceptiveDevelopment.A | InvisibleFerret AnyDesk module. |
7C5B2CAFAEABBCEB9765 |
bow.py | Python/DeceptiveDevelopment.A | InvisibleFerret browser module. |
BA1A54F4FFA42765232B |
pay.py | Python/DeceptiveDevelopment.A | InvisibleFerret payload module. |
6F049D8A0723DF10144C |
.npl | Python/DeceptiveDevelopment.A | InvisibleFerret loader module. |
8FECA3F5143D15437025 |
admin.model.js | JS/Spy.DeceptiveDevelopment.A | BeaverTail. |
380BD7EDA453487CF115 |
run.js | JS/Spy.DeceptiveDevelopment.A | BeaverTail. |
Red
IP | Domain | Hosting provider | First seen | Details |
95.164.17[.]24 | N/A | STARK INDUSTRIES SOLUTIONS LTD | 2024‑06‑06 | BeaverTail/InvisibleFerret C&C and staging server. |
185.235.241[.]208 | N/A | STARK INDUSTRIES SOLUTIONS LTD | 2021‑04‑12 | BeaverTail/InvisibleFerret C&C and staging server. |
147.124.214[.]129 | N/A | Majestic Hosting Solutions, LLC | 2024‑03‑22 | BeaverTail/InvisibleFerret C&C and staging server. |
23.106.253[.]194 | N/A | LEASEWEB SINGAPORE PTE. LTD. | 2024‑05‑28 | BeaverTail/InvisibleFerret C&C and staging server. |
147.124.214[.]237 | N/A | Majestic Hosting Solutions, LLC | 2023‑01‑28 | BeaverTail/InvisibleFerret C&C and staging server. |
67.203.7[.]171 | N/A | Amaze Internet Services | 2024‑02‑14 | BeaverTail/InvisibleFerret C&C and staging server. |
45.61.131[.]218 | N/A | RouterHosting LLC | 2024‑01‑22 | BeaverTail/InvisibleFerret C&C and staging server. |
135.125.248[.]56 | N/A | OVH SAS | 2023‑06‑30 | BeaverTail/InvisibleFerret C&C and staging server. |
Técnicas ATT&CK de MITRE
Esta tabla se ha elaborado utilizando la versión 16 del marco MITRE ATT&CK.
Tactic | ID | Name | Description |
Resource Development | T1583.003 | Acquire Infrastructure: Virtual Private Server | The attackers rent out infrastructure for C&C and staging servers. |
T1587.001 | Develop Capabilities: Malware | The attackers develop the BeaverTail and InvisibleFerret malware. | |
T1585.001 | Establish Accounts: Social Media Accounts | The attackers create fake social media accounts, pretending to be recruiters. | |
T1608.001 | Stage Capabilities: Upload Malware | InvisibleFerret modules are uploaded to staging servers, from where they are downloaded to victimized systems. | |
Initial Access | T1566.003 | Phishing: Spearphishing via Service | Spearphishing via job-hunting and freelancing platforms. |
Execution | T1059.006 | Command-Line Interface: Python | InvisibleFerret is written in Python. |
T1059.007 | Command-Line Interface: JavaScript/JScript | BeaverTail has a variant written in JavaScript. | |
T1204.002 | User Execution: Malicious File | Initial compromise is triggered by the victim executing a trojanized project containing the BeaverTail malware. | |
T1059.003 | Command-Line Interface: Windows Command Shell | InvisibleFerret’s remote shell functionality allows access to the Windows Command Shell. | |
Persistence | T1133 | External Remote Services | Persistence is achieved by installing and configuring the AnyDesk remote access tool. |
Defense Evasion | T1140 | Deobfuscate/Decode Files or Information | The JavaScript variant of BeaverTail uses code obfuscation. C&C server addresses and other configuration data are also encrypted/encoded. |
T1564.001 | Hide Artifacts: Hidden Files and Directories | InvisibleFerret files are dropped to disk with the hidden attribute. | |
T1564.003 | Hide Artifacts: Hidden Window | InvisibleFerret creates new processes with their windows hidden. | |
T1027.013 | Obfuscated Files or Information: Encrypted/Encoded File | InvisibleFerret payloads are encrypted and have to be decrypted before execution. | |
Credential Access | T1555.001 | Credentials from Password Stores: Keychain | Keychain data is exfiltrated by both BeaverTail and InvisibleFerret. |
T1555.003 | Credentials from Password Stores: Credentials from Web Browsers | Credentials stored in web browsers are exfiltrated by InvisibleFerret. | |
T1552.001 | Unsecured Credentials: Credentials In Files | Plaintext credentials/keys in certain files are exfiltrated by both BeaverTail and InvisibleFerret. | |
Discovery | T1010 | Application Window Discovery | The InvisibleFerret keylogger collects the name of the currently active window. |
T1217 | Browser Bookmark Discovery | Credentials and other data stored by browsers are exfiltrated by InvisibleFerret. | |
T1083 | File and Directory Discovery | The InvisibleFerret backdoor can browse the filesystem and exfiltrate files. | |
T1082 | System Information Discovery | System information is collected by both BeaverTail and InvisibleFerret. | |
T1614 | System Location Discovery | InvisibleFerret geolocates the campaign by querying the IP address location. | |
T1016 | System Network Configuration Discovery | InvisibleFerret collects network information, such as private and public IP addresses. | |
T1124 | System Time Discovery | InvisibleFerret collects the system time. | |
Lateral Movement | T1021.001 | Remote Services: Remote Desktop Protocol | AnyDesk is used by InvisibleFerret to achieve persistence and allow remote attacker access. |
Collection | T1056.001 | Input Capture: Keylogging | InvisibleFerret contains keylogger functionality. |
T1560.002 | Archive Collected Data: Archive via Library | Data exfiltrated using InvisibleFerret can be archived using the py7zr and pyzipper Python packages. | |
T1119 | Automated Collection | Both BeaverTail and InvisibleFerret exfiltrate some data automatically. | |
T1005 | Data from Local System | Both BeaverTail and InvisibleFerret exfiltrate data from the local system. | |
T1025 | Data from Removable Media | InvisibleFerret scans removable media for files to exfiltrate. | |
T1074.001 | Data Staged: Local Data Staging | InvisibleFerret copies browser databases to the temp folder prior to credential extraction. When exfiltrating via a ZIP/7z archive, the file is created locally before being uploaded. | |
T1115 | Clipboard Data | InvisibleFerret contains clipboard stealer functionality. | |
Command and Control | T1071.001 | Standard Application Layer Protocol: Web Protocols | C&C communication is done over HTTP. |
T1071.002 | Standard Application Layer Protocol: File Transfer Protocols | Files are exfiltrated over FTP by InvisibleFerret. | |
T1571 | Non-Standard Port | Nonstandard ports 1224, 1244, and 1245 are used by BeaverTail and InvisibleFerret. | |
T1219 | Remote Access Tools | InvisibleFerret can install AnyDesk as a persistence mechanism. | |
T1095 | Non-Application Layer Protocol | TCP is used for command and control communication. | |
Exfiltration | T1030 | Data Transfer Size Limits | In some cases, InvisibleFerret exfiltrates only files below a certain file size. |
T1041 | Exfiltration Over Command and Control Channel | Some data is exfiltrated to the C&C server over HTTP. | |
T1567.004 | Exfiltration Over Web Service: Exfiltration Over Webhook | Exfiltrating ZIP/7z files can be done over a Telegram webhook (InvisibleFerret’s ssh_zcp command). | |
Impact | T1657 | Financial Theft | This campaign’s goal is cryptocurrency theft and InvisibleFerret has also been seen exfiltrating saved credit card information. |
Apéndice
ArgentX Aurox Backpack Binance Bitget Blade Block Braavos ByBit Casper Cirus Coin98 CoinBase Compass-Sei Core-Crypto Cosmostation Crypto.com Dashalane Enkrypt Eternl Exodus Fewcha-Move Fluent Frontier GoogleAuth Hashpack HAVAH HBAR Initia Keplr |
Koala LastPass LeapCosmos Leather Libonomy MagicEden Manta Martian Math MetaMask MetaMask-Edge MOBOX Moso MyTon Nami OKX OneKey OpenMask Orange OrdPay OsmWallet Paragon PetraAptos Phantom Pontem Rabby Rainbow Ramper Rise Ronin |
Safepal Sender SenSui Shell Solflare Stargazer Station Sub-Polkadot Sui Suiet Suku Taho Talisman Termux Tomo Ton Tonkeeper TronLink Trust Twetch UniSat Virgo Wigwam Wombat XDEFI Xverse Zapit Zerion |