Hola, internet:
¿Recuerdas el ataque de Shai-Hulud que afectó a @AntV ¿el 19 de mayo de 2026? Lo sé, parece que fue hace una eternidad en el mundo de la cadena de suministro. Una cuenta de mantenedor comprometida publicó 639 versiones maliciosas de paquetes @antv en npm en apenas una hora. Nosotros, junto con gran parte de la comunidad de seguridad de npm, despiezamos esa carga útil en cuestión de horas. No tenía nada de novedoso en cuanto a técnica. Fue simplemente otro día en el que te levantas y te encuentras con un ataque a la cadena de suministro. Lo habitual.
Desde entonces, npm ha implementado el análisis de malware en el momento de la publicación. Así que podéis imaginar mi sorpresa al revisar nuestra cola de triaje esta mañana y ver lo que reconocí de inmediato como un bicho gusano. Tenía el mismo hash que la @AntV oleada. La misma carga útil:
e37e3ddeeaaa9e0c4fdbcb829b4895a6521031c80053fc436625b61e6ee5b1a6. Este es exactamente el mismo archivo que npm, nosotros y la mitad de los proveedores de esta lista ya habíamos identificado mediante huella digital hace meses.
Estamos hablando de 111 días de silencio absoluto sobre ese hash. Hasta donde sabemos, es el periodo de latencia hasta la reactivación más largo que hemos visto en una carga útil de Shai-Hulud, y con diferencia. Llámalo como es: un zombi que resurge cuatro meses después de que todo el mundo lo diera por muerto.
Los cuatro paquetes que lo trajeron de vuelta, todos publicados en la misma hora del 7 de septiembre por la misma cuenta de npm:
feishu-docx-mcp@0.3.2bmc-i18n-extract-cli@1.1.1blueai-cli@0.7.0bmc-translate-utils@1.1.1
Las cifras
Recuperamos nuestro historial de detecciones para este hash de archivo exacto en cada versión de paquete que hemos analizado. Así es como se ve realmente la línea temporal:
Nuestros registros muestran 319 versiones de paquetes que contienen este hash; todas y cada una de ellas se detectaron por primera vez el 19 de mayo de 2026, el día de la @AntV oleada, ni un día antes ni un día después. Luego, nada. Cero nuevas coincidencias con este hash entre el 20 de mayo y el 6 de septiembre. A continuación, a partir de hoy (7 de septiembre), aparecieron cuatro versiones de paquetes más en npm con exactamente la misma carga útil. Eso representa un intervalo de 111 días: visto por última vez el 19 de mayo, vuelto a ver el 7 de septiembre.
Cuatro paquetes son una cifra pequeña si se compara con un hecho mayor: una carga útil con un hash conocido, publicado y indexado permaneció intacta y fuera del radar en las cadenas de herramientas de todo el mundo durante más de tres meses para luego ser republicada en un registro que, desde este año, analiza explícitamente cada paquete antes de que salga en directo.
El caso sencillo
En julio, npm desplegó el análisis de malware en el momento de la publicación: cada paquete se retiene entre 5 y 15 minutos mientras un sistema automatizado lo comprueba antes de que se pueda instalar. Según el propio registro de cambios de npm, el objetivo es detectar "el malware que podemos identificar" antes de que llegue al npm install.
Coincidir con el hash de un archivo es una simple consulta, no un problema complejo. No requiere análisis de comportamiento, sandboxing ni deducir la intención de código ofuscado. Además, esta carga útil no era novedosa, ni estaba repackeada ni ligeramente modificada para esquivar la coincidencia de firmas. Eran exactamente los mismos 64 caracteres hexadecimales que figuraban en nuestros archivos desde mayo.
No estamos diciendo que el escáner deba detectarlo todo. Amenazas como los cargadores de varias etapas, la confusión de dependencias y las cargas útiles activadas en tiempo de ejecución son problemas genuinamente difíciles. Sin embargo, la coincidencia exacta del hash con un gusano que protagonizó titulares de seguridad internacionales hace cuatro meses no lo es. Eso es lo mínimo que se supone que debe detectar un análisis en el momento de la publicación, y se ha pasado por alto. Esta muestra específica debería formar parte del corpus de pruebas de cualquiera que realice análisis de la cadena de suministro.
La conclusión
Una carga útil de gusano con un hash público, informes detallados de proveedores y meses de cobertura de detección permaneció latente durante 111 días y luego volvió a entrar en npm sin ningún tipo de fricción, en un registro que ahora se promociona indicando que analiza cada publicación. Esa brecha entre lo que el análisis a nivel de registro dice hacer y lo que demuestra una reactivación con un hash idéntico es el verdadero problema aquí. La comprobación de firmas frente a artefactos maliciosos conocidos es el listón más fácil de superar en esta industria, y es precisamente el listón que más alarma causa ver fallar. Si esto es lo que se cuela en el caso sencillo, vale la pena preguntarse qué habría hecho una carga útil que se hubiera molestado en cambiar un solo byte.
Indicadores de Compromiso
Red:
t[.]m-kosche[.]com(C2, de la oleada original de mayo)
Archivo:
- SHA256:
e37e3ddeeaaa9e0c4fdbcb829b4895a6521031c80053fc436625b61e6ee5b1a6 - A nivel raíz
index.jspayload - ejecución de script preinstall
bun run index.js
Persistencia:
.vscode/tasks.json.claude/settings.json
Comportamiento:
- Llamadas de validación salientes contra el registro de npm utilizando tokens robados
- Descarga del tarball, inyección de payload, incremento de versión y ciclo de republicación
- Creación masiva de repositorios en GitHub con nombres inspirados en Dune y cadenas invertidas de "Shai-Hulud" en las descripciones