
Esta semana me encontré con una noticia que me dejó helado. Un desarrollador de Rust, conocido como grack, publicó el análisis de un ataque que casi le funciona: una entrevista de trabajo falsa diseñada para instalar un troyano de acceso remoto en su máquina. La wea es tan sofisticada que da miedo.
La trampa perfecta
El ataque comenzó con un correo de «D█████ S████» que decÃa ser de Lua Ventures, un fondo de inversión de Singapur. IncluÃa un perfil de LinkedIn que parecÃa legÃtimo, mencionaba dos startups ficticias (Lyrasing y Roadpay) con sitios web básicos pero creÃbles, y hasta una llamada telefónica con un hombre de acento alemán. Todo muy profesional, nada que levantara sospechas inmediatas.
Después de la llamada llegó el gancho: una «prueba técnica» que consistÃa en clonar un repositorio de TypeScript llamado «Ticket Harbor» y ejecutar typecheck, tests y builds. Suena como cualquier proceso de entrevista remota, ¿cierto? Pero ahà estaba la trampa.
El payload oculto
Afortunadamente, grack notó algo raro: las instrucciones parecÃan más un examen de TypeScript que un análisis de arquitectura. Ese detalle, aparentemente menor, le salvó el pescuezo. Al revisar el código con cuidado, descubrió que el repositorio contenÃa cuatro hooks postinstall que ejecutaban patch-package. Uno de ellos además corrÃa git update-index --skip-worktree para ocultar los archivos de parche del git status.
El parche malicioso typescript+5.9.2.patch inyectaba un stub autoejecutable al inicio de typescript.js y _tsc.js. Este stub decodificaba un blob base64, lo desencriptaba con XOR (clave 73) y lo ejecutaba con new Function(). Es decir, la primera vez que corrieras npm run typecheck, build o dev, el troyano se activaba.
Después venÃa lo peor: el stub leÃa un chunk oculto dentro de operators/3.png (sÃ, una imagen PNG), ejecutaba un módulo WASM embebido y lanzaba un proceso Node silencioso y detached con un payload de 1.68 MB ofuscado en tres capas. Para colmo, se autolimpiaba: el parche se reescribÃa para borrar sus propias lÃneas, y el directorio temporal se autodestruÃa.
PinpinRAT: un RAT de nivel profesional
El payload resultó ser un troyano de acceso remoto completo, bautizado PinpinRAT por sus strings internos. No es un simple robador de credenciales: es un RAT con cifrado RSA-2048 y AES-256-CBC, que exfiltra fingerprint completo del host (IPs, username, hostname, SO, arquitectura, PID, argv, versión de Node) y soporta comandos para leer archivos, escribir archivos, ejecutar procesos, navegar el filesystem y hasta hacer DNS tunneling.
Lo que más me preocupa es que la imagen con el payload pasó 0 de 70 motores antivirus en VirusTotal. Cero. Nada. Esto demuestra que la seguridad basada en firmas está quedando obsoleta frente a ataques personalizados y ofuscados.
Mi opinión
Como ingeniero de sistemas que ha pasado por decenas de procesos de selección, esto me hace reflexionar. La lÃnea entre una entrevista legÃtima y una trampa puede ser increÃblemente delgada. El atacante invirtió tiempo real: creó perfiles falsos, sitios web, una llamada telefónica. No es el tÃpico phishing de «haz clic acá». Es ingenierÃa social de alto nivel.
Mi consejo: si te piden clonar un repo y ejecutar scripts como parte de una entrevista, revÃsalo en una máquina virtual o sandbox. Nunca en tu entorno de trabajo real. Y si algo se siente raro, aunque sea una pizca, confÃa en tu instinto. A grack le salvó notar que las instrucciones no calzaban con el rol que postulaba.
El C2 del ataque está en 89.124.107.161:80. Si ves eso en tus logs, desconecta todo y rota credenciales desde otra máquina. Sin dramatizar, pero sin subestimar la amenaza.
La pega de seguridad nunca termina, po.
Fuente de inspiración: Anatomy of a Failed (Nation-State?) Attack