- En todo el ecosistema de npm se está propagando una variante de malware destructivo, detectada por el equipo de seguridad de GitLab
- El malware es una forma evolucionada de Shai-Hulud, con una estructura de propagación tipo gusano que infecta automáticamente otros paquetes del desarrollador comprometido
- Tras robar credenciales de GitHub, AWS, GCP y Azure, entre otros, exfiltra datos a repositorios de GitHub controlados por los atacantes
- Incluye un “dead man’s switch” que elimina de inmediato los datos del usuario si se bloquea al mismo tiempo el acceso a GitHub y npm
- GitLab confirmó que sus propios sistemas no fueron infectados y ofrece medidas de detección y respuesta mediante Dependency Scanning y GitLab Duo Chat
Resumen del ataque
- El equipo de Vulnerability Research de GitLab detectó un ataque masivo a la cadena de suministro dentro del ecosistema npm
- Un sistema interno de monitoreo descubrió varios paquetes infectados
- Se confirmó que el malware es una variante de Shai-Hulud
- El malware usa propagación tipo gusano para infectar automáticamente otros paquetes del desarrollador comprometido
- GitLab confirmó que no utilizó paquetes maliciosos en sus propios sistemas y compartió la información con la comunidad de seguridad
Estructura interna del ataque
- Los paquetes maliciosos de npm detectados por el sistema interno de monitoreo realizan las siguientes funciones
- Recopilan credenciales de GitHub, npm, AWS, GCP y Azure
- Envían los datos robados a repositorios de GitHub controlados por los atacantes
- Infectan automáticamente otros paquetes de la víctima
- Ejecutan una carga destructiva si se bloquea el acceso a la infraestructura
- Se han confirmado múltiples paquetes infectados y la investigación sigue en curso
Análisis técnico: cómo avanza el ataque
Vector de infección inicial
- El malware penetra en el sistema mediante un proceso de carga de varias etapas
- Se agrega el script
setup_bun.js al package.json del paquete infectado
- A simple vista, se disfraza como si fuera para instalar el runtime de JavaScript Bun
- En realidad ejecuta
bun_environment.js (10 MB, carga útil ofuscada)
- Está compuesto por un archivo loader pequeño y una carga útil grande y ofuscada para evadir la detección
Recolección de credenciales
- Apenas se ejecuta, recopila tokens y secretos desde diversas fuentes
- Tokens de GitHub (
ghp_, gho_)
- Credenciales de AWS, GCP y Azure
- Tokens de npm (
.npmrc y variables de entorno)
- Usa la herramienta Trufflehog para escanear todo el directorio personal en busca de claves API, contraseñas e historial de Git
Red de exfiltración de datos
- Con los tokens robados de GitHub, crea repositorios públicos con la descripción “Sha1-Hulud: The Second Coming.”
- Esos repositorios cumplen el rol de buzón de entrega de datos
- Instala runners de GitHub Actions para asegurar persistencia
- Si no tiene permisos suficientes, busca otros repositorios con el mismo marcador para reutilizar tokens de otros sistemas
- Así forma una red distribuida de intercambio de tokens
Propagación en la cadena de suministro
- Usa los tokens de npm robados para infectar todos los paquetes de la víctima
- Descarga el paquete original
- Inserta
setup_bun.js como script de preinstall
- Agrega la carga útil
bun_environment.js
- Incrementa el número de versión
- Vuelve a publicar el paquete infectado en npm
Dead man’s switch
- El malware monitorea de forma continua el acceso a GitHub (exfiltración de datos) y npm (propagación)
- Si ambos canales quedan bloqueados, ejecuta de inmediato la destrucción de datos
- Windows: elimina archivos del usuario y sobrescribe sectores del disco
- Unix: sobrescribe archivos con el comando
shred y luego los elimina
- Si se eliminan masivamente repositorios de GitHub o se revocan en masa tokens de npm, existe el riesgo de que los sistemas infectados borren datos al mismo tiempo
Indicadores de compromiso (IoC)
- Principales indicadores de detección
- Archivo:
bun_environment.js (script malicioso de post-install)
- Directorios:
.truffler-cache/, .truffler-cache/extract/
- Procesos:
del /F /Q /S "%USERPROFILE%*", shred -uvz -n 1, cipher /W:%USERPROFILE%
- Comandos:
curl -fsSL https://bun.sh/install | bash, powershell -c "irm bun.sh/install.ps1|iex"
Soporte de detección y respuesta de GitLab
- Los usuarios de GitLab Ultimate pueden verificar de inmediato su nivel de exposición con funciones de seguridad integradas
- Si Dependency Scanning está activado, detecta automáticamente paquetes infectados dentro de
package-lock.json o yarn.lock
- Muestra una alerta cuando una merge request incluye paquetes infectados
- También permite detección rápida basada en consultas mediante integración con GitLab Duo Chat
- Ejemplo: “¿Hay dependencias afectadas por la campaña Shai-Hulud v2?”
- El Security Analyst Agent consulta los datos de vulnerabilidades del proyecto y responde al instante
- Para equipos que administran múltiples repositorios, se recomienda combinar detección automatizada basada en CI/CD con respuesta rápida basada en agentes
Perspectivas a futuro
- Este ataque se evalúa como una nueva forma de ataque a la cadena de suministro que usa la destrucción de datos de las víctimas para proteger la infraestructura del atacante
- GitLab está colaborando con la comunidad para desarrollar estrategias de recuperación seguras y sigue monitoreando variantes con sistemas automáticos de detección
- El objetivo es prevenir daños secundarios causados por el dead man’s switch mediante el intercambio temprano de información
1 comentarios
Opiniones de Hacker News
Hace como un mes necesité hacer una tarea fastidiosa y busqué un paquete de NPM
Ejecuté
brew install npmy se vino una cascada de dependencias; me detuve un momento a pensar en los riesgos y beneficios, y al final di marcha atrás conbrew uninstall npmEn su lugar lo resolví con un viejo pipeline de utilidades Unix y awk, y viéndolo ahora, fue la mejor decisión
NPM es una herramienta creada para resolver problemas de compatibilidad de navegadores, así que en un entorno sin navegador introduce complejidad innecesaria
Si ejecutas directamente en tu sistema principal código de ecosistemas con muchas dependencias, como Node o Python, te expones a ataques a la cadena de suministro
Por eso yo ni siquiera instalo intérpretes de Python o JS en mi sistema base
Al final lo dejé, pero ahora parece que sí era lo correcto
Alguien dijo que “si GitHub elimina en masa repositorios maliciosos, miles de sistemas podrían destruir datos de usuarios al mismo tiempo”,
suena como una toma de rehenes, y por eso salió la broma de “dispárenle al rehén”
Yo también fui víctima de este ataque de npm
Me impactó enterarme de que GitHub CLI guarda tokens OAuth en texto plano en el directorio HOME
Si el atacante accedía, podía hacer casi cualquier cosa con mi cuenta
En macOS se guarda de forma segura en el llavero del sistema: discusión relacionada
Chrome usa protecciones del sistema operativo, pero Firefox todavía no
Al final, la solución de fondo es el control de acceso basado en sandbox
Pero no existe una solución consistente entre plataformas, y ni siquiera en MacOS hay una forma perfecta
Se creó el directorio
~/.dev-envy mi laptop se convirtió en un runner de GitHubTal vez el sistema de archivos de solo lectura de Bluefin Linux ayudó a limitar el daño
Todos culpan solo a npm, pero GitHub también tiene responsabilidad
No detectó con rapidez los repositorios maliciosos, y el problema de los repositorios con malware ya es grave
Si se hubiera enviado en secreto a un servidor externo, habría sido mucho peor
Hacen falta herramientas y prácticas a nivel comunidad
Si aparecen regulaciones comerciales o restricciones en los flujos de build, eso podría llevar a problemas grandes
Me preguntaba por qué solo NPM parece ser objetivo de ataques
Python o Java también son muy populares, pero últimamente han estado más tranquilos
y la cultura de dependencias con rangos de versión hace que la infección se propague rápido
En Java es más común fijar versiones específicas, así que esto pasa menos
Por eso un solo paquete arrastra decenas de subdependencias
y como hay muchos desarrolladores con poca experiencia, la seguridad suele ser más débil
Otros ecosistemas actualizan después de validar, pero en JS hacen upgrade de inmediato
Durante la instalación puede ejecutar scripts libremente, y ni la JVM ni Python funcionan así
Si agregas esto a
.npmrcpuedes reducir el vector de ataque
Artículo relacionado
y también queda la duda de si desactivarlo puede romper dependencias
Lo que más preocupa en este ataque es el robo de credenciales
Si instalaste un paquete infectado, puede que se hayan filtrado variables de entorno o tokens de
.npmrcHay que rotar de inmediato los tokens y las API keys
La rotación periódica no es una respuesta posterior a una intrusión, sino una medida preventiva
Las credenciales no deberían guardarse en variables de entorno ni en archivos; hay que usar llaves de seguridad o archivos cifrados
Es como incrustar transacciones maliciosas en un libro mayor distribuido
El problema es que muchos servicios todavía dejan el almacenamiento en texto plano como valor predeterminado
Me pregunto por qué, con estos ataques repitiéndose, no funcionan los sistemas de detección basados en IA
Microsoft habla tanto de IA, pero parece que no la usa realmente en la seguridad de GitHub
Igual que cuando todo intento bloqueado por un firewall se clasificaba como ataque, el término ya perdió fuerza
Internamente eso lo soporta SonaType IQ Server
De hecho, el proyecto curl ha sufrido spam de reportes de seguridad generados por IA
Me pregunto si todavía hay alguna razón para seguir permitiendo scripts postinstall
Quizá sería mejor preguntarle al usuario si quiere ejecutarlos
y en los servidores de CI se necesita instalación no interactiva, así que en la práctica parece difícil
El artículo fue muy perspicaz, pero me decepcionó que al final terminara como promoción de funciones de seguridad de GitLab