1 puntos por GN⁺ 5 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Un desarrollador en Canadá recibió un ataque para inducir la instalación de una puerta trasera disfrazado de entrevista con un VC falso, y el flujo del ataque estaba tan adaptado al trabajo de desarrolladores que se sospecha que apuntaba al gestor de paquetes de crates.io
  • El repositorio señuelo parecía una app en TypeScript llamada “Ticket Harbor”, pero ocultaba código malicioso en la ruta de ejecución de TypeScript usando patch-package y typescript+5.9.2.patch
  • El stub inyectado descifra ofuscación con base64 y XOR, se ejecuta con new Function(...) y, tras pasar por chunks ocultos en operators/3.png y un stub en WASM, lanza una carga útil de segunda etapa de 1.68 MB en un proceso de Node separado
  • La carga final, “PinpinRAT”, genera un par de claves RSA-2048 y una clave de sesión AES-256-CBC, y permite recolectar huellas del host, subir y bajar archivos, ejecutar procesos, manipular el sistema de archivos, hacer consultas DNS y autodesinstalarse
  • Si ejecutaste el repositorio, debes desconectarlo de la red de inmediato y cambiar tus credenciales desde otro dispositivo, asumiendo que también pudieron robarse cookies y secretos protegidos por contraseña

Ataque dirigido a desarrolladores que empezó con una entrevista falsa

  • El atacante se acercó haciéndose pasar por una persona que decía pertenecer a “Lua Ventures”
    • Lua Ventures se presentaba como un VC de DeFi con base en Singapur, pero en realidad ya había dejado de operar
    • El nombre de la persona no se publica porque puede confundirse con homónimos reales
  • El correo parecía creíble e incluía un enlace a un perfil de LinkedIn normal, aunque genérico
  • Mencionó a Lyrasing y Roadpay como firmas de inversión que buscaban asesoría
    • Ambas empresas tenían una presencia web básica, por lo que parecían compañías en etapa temprana más que algo obviamente falso
    • También queda un snapshot de archive.org del sitio de Roadpay
  • Tras intercambiar correos, incluso llegaron a una llamada por Google Meet
    • La persona en la llamada era un hombre con acento alemán y dijo que iba en movimiento
    • La llamada en sí no tuvo nada claramente extraño

El disparador de ejecución, disfrazado de “prueba técnica”

  • Después de la llamada, el atacante propuso una “prueba” y envió un repositorio
  • El repositorio estaba presentado como una app de venta de boletos de ferry llamada “Ticket Harbor”
  • El task.txt incluido contenía una lista de tareas aburrida pero verosímil, y al final incluía instrucciones para ejecutar el proyecto
    • Indicaba correr typecheck del repositorio, la suite de pruebas y comandos de build relacionados con desktop/server
  • Esa instrucción era el verdadero disparador de la infección
    • En el momento en que se ejecutaba TypeScript o se importaba typescript.js, como con npm run typecheck, build o dev, podía activarse la carga útil

Cadena de ejecución oculta en un parche de TypeScript

  • La primera señal de alerta fue que el repositorio parecía una prueba de TypeScript
    • Lo pedido se parecía más a una tarea de contratación en TypeScript que a un análisis de arquitectura
    • Al revisar rápido el repositorio con Claude, aparecieron indicios extraños relacionados con patch-package
  • El directorio patches/ tenía una cantidad inusual de archivos
    • Algunos parches parecían legítimos y actuaban como ruido para ocultar la carga real
    • Por ejemplo, incluía sumchecker+3.0.1.patch, @electron+get+2.0.3.patch y extract-zip+2.0.1.patch
  • El código malicioso principal estaba en typescript+5.9.2.patch
    • Insertaba un stub de ejecución inmediata al inicio de typescript.js y _tsc.js
    • El stub decodificaba una cadena en base64, aplicaba XOR con la clave 73 a cada byte y luego la ejecutaba con new Function(...)
    • A la función de ejecución se le pasaban require, Buffer, WebAssembly, process y __dirname
  • La cadena de ejecución pasaba por varias etapas
    • Cuatro hooks de postinstall ejecutaban patch-package
    • Uno de ellos aplicaba git update-index --skip-worktree al archivo del parche para ocultarlo de git status
    • El loader leía un chunk oculto agregado al final del archivo operators/3.png
    • Ejecutaba un pequeño stub WASM dentro de un chunk personalizado wAsm
    • Lanzaba una carga útil ofuscada de segunda etapa de 1.68 MB en un proceso de Node aparte y silencioso
  • El código del ataque estaba diseñado para dejar menos rastros después de ejecutarse
    • Ocultaba el parche con git skip-worktree
    • El dropper eliminaba del archivo de parche las líneas que había insertado después de la primera ejecución
    • El directorio temporal de la segunda etapa se autodestruía durante la ejecución

Capacidades de PinpinRAT

  • La carga final recibe el nombre de “PinpinRAT”
    • El nombre viene de cadenas internas, aunque no se puede descartar que se conozca con otro nombre
    • No se encontraron otras referencias en línea
  • La carga estaba envuelta en varias capas de ofuscación
    • obfuscator.io
    • dos capas adicionales de base64
  • Al iniciarse, el RAT recolecta y exfiltra huellas del host
    • dirección IP principal y lista completa de IPs
    • nombre de usuario de os.userInfo().username
    • hostname
    • tipo, release, plataforma y arquitectura del sistema operativo
    • PID del proceso y todo process.argv
    • versión de Node
  • También incluye una estructura de cifrado
    • genera localmente un par de claves RSA-2048
    • genera una clave de sesión AES-256 aleatoria aes_psk
    • el tráfico posterior se cifra con AES-256-CBC y lleva una etiqueta de integridad HMAC-SHA256
  • Los comandos soportados ofrecen funciones al nivel de un troyano de acceso remoto
    • env: convierte process.env a una cadena JSON y la envía
    • upload: lee y exfiltra una ruta de archivo arbitraria
    • download: escribe bytes provistos por el atacante en una ruta con permiso de escritura
    • spawn: ejecuta un proceso arbitrario, con expansión opcional de shell
    • ls, cd, pwd, cp, mv: manipulación común del sistema de archivos
    • dns: resuelve nombres arbitrarios usando el resolver indicado
    • dismantle: autodesinstalación

Indicadores de compromiso y respuesta inmediata

  • La imagen que contenía la carga no era detectada por ningún motor AV en VirusTotal
  • Si se ejecutó, el sistema debe aislarse de la red de inmediato
  • Las credenciales deben cambiarse desde otro dispositivo
    • también debe asumirse que cookies y secretos protegidos por contraseña quedaron comprometidos
  • Los indicadores de compromiso relacionados con PinpinRAT son los siguientes
    • C2: 89.124.107.161:80
    • tarea programada en Windows: PinpinWrappedJs
    • camuflaje de proceso en macOS: com.apple.WebKit.Networking
    • variables de entorno: NODT_PAYLOAD_PATH, NODT_PAYLOAD_ARGS
    • guard del chunk PNG: WASMPACK (wAsm)
    • PINPIN_NO_AUTOSTART=1: detiene la persistencia
    • cronjob con mutex.js: puede existir solo si el RAT tuvo privilegios suficientes, y podría no estar en macOS
    • cadenas ancla en typescript.js: 12ff4b51, ticket-harbor-tsc-shim-anchor
    • typescript+5.9.2.patch con la carga incluida
    • directorios de artefactos:
      • macOS: ~/Library/Caches/runtime-cache/.cache-<randomhex>/
      • Linux: /tmp/.cache-<randomhex>/
      • Windows: %TEMP%\\.cache-<randomhex>\\
      • dentro se encuentran payload.js y mutex.js

Señales de alerta que solo se vieron después

  • En los mensajes había expresiones que, mirándolas con cuidado, parecían rastros de LLM
  • El perfil de LinkedIn parecía normal a primera vista, pero la lista de títulos y credenciales era rara y no mostraba actividad real
  • Los enlaces a redes sociales del sitio sí tenían historial real, pero el nombre se cambió en noviembre de 2025
    • Las publicaciones eran poco específicas y se parecían más a elogios vagos sobre empresas
  • Los sitios web de las compañías eran vistosos, pero casi no tenían presencia real
  • El atacante no envió una invitación formal de calendario; solo compartió la hora y el Google Meet
    • Durante la llamada la cámara estuvo siempre apagada y dijo que estaba en movimiento
  • Aparecían juntos un VC basado en Singapur, actividad en horario CEST, contacto a un desarrollador canadiense y un dominio .cc orientado a clientes de EE. UU.
    • Era más difícil verificar la credibilidad de una organización lejana
  • Ninguna señal individual era definitiva, pero el patrón era uno en el que varias luces amarillas acumuladas terminaban pareciendo una roja

Autoría y alcance del ataque

  • No se puede atribuir con certeza quién estuvo detrás
  • El ataque apuntaba a desarrolladores e incluía una identidad falsa, una historia de cobertura convincente, varios sitios falsos, paciencia en la coordinación y trampas sofisticadas con git
  • Encaja con el flujo de “estafa de entrevista falsa” usado por varios actores en 2026
  • En la comunidad de Rust en Reddit también se mencionó un caso de objetivo similar
  • El método estaba tan acoplado al flujo de trabajo de desarrolladores que, si hubiera estado armado como una trampa build.rs en un repositorio de Rust, probablemente habría funcionado

1 comentarios

 
GN⁺ 5 시간 전
Comentarios en Lobste.rs
  • Resulta confuso que el título especule que podría tratarse de un actor respaldado por un Estado. Aquí no parece haber nada que necesariamente requiera ese nivel de preparación o complejidad
    Se puede imaginar esa posibilidad, pero no parece más plausible que otros escenarios

    • Supongo que es porque este tipo de estafa sofisticada requiere muchos recursos, así que es bastante rara. Cuando ves una estafa sofisticada, es fácil sentir que podría ser obra de un Estado
      Aun así, casi con seguridad no parece ser un actor respaldado por un Estado. Este tipo de ataque ya no es tan difícil
  • Es realmente una coincidencia que este ataque se parezca al caso hipotético que describí en una entrada de mi blog hace una semana: the hypothetical I describe in my blog post from a week ago
    Solo elegí uno de varios ataques plausibles como ejemplo de algo que podría engañar incluso a expertos con buen dominio técnico. Sí había visto aumentar varias estafas sofisticadas dirigidas a personas, pero no sabía que ya estuviera en marcha una tendencia de estafas de entrevistas. Por eso, enterarme de este ataque me dio escalofríos

  • La semana pasada recibí una propuesta de entrevista exactamente del mismo tipo de D____ S_____ de Lua Ventures. La ignoré como casi todo el spam de reclutadores, y menos mal que lo hice

    • Me pregunto si era alguien del entorno de Rust. Varias figuras importantes de la comunidad Rust fueron objetivo de Lua, así que me gustaría saber si esto se limita a Rust o si es algo más amplio
  • Me parece que hubo un envío sobre esto hace unos días o hace unas semanas

  • Lo sorprendente es eso de que “parecía un correo real”. Me habría parecido sospechoso desde la segunda frase, porque se veía demasiado como texto generado por un LLM

    • A mí no me pareció tan obvio. Más bien me sonó al estilo LinkedIn. Eso también a veces suena como si lo hubiera escrito un LLM, pero el olor es tan parecido que no sé si realmente tengo la capacidad de distinguirlos