news

CanisterWorm y TeamPCP: el worm de npm que borra clusters de Kubernetes

Elena DuranElena Duran-23 de marzo de 2026-7 min de lectura
Compartir:
Consola de terminal mostrando la propagación del worm CanisterWorm a través de paquetes npm comprometidos

Foto de Unsplash en Unsplash

En resumen

TeamPCP comprometió el paquete npm de Trivy para inyectar CanisterWorm, un worm autopropagable que en 21 días infectó 66+ paquetes npm usando tokens robados. Su C2 funciona sobre la blockchain de Ethereum y su payload de segundo estadio incluye un wiper de Kubernetes con activación automática en infraestructura iraní.

Voy al grano: comprometer Trivy no es comprometer una herramienta marginal. Es comprometer el escáner de vulnerabilidades que corre dentro de los pipelines de CI/CD de miles de organizaciones —con privilegios elevados, acceso a registros de contenedores privados y tokens de autenticación en texto claro. TeamPCP lo eligió por eso exactamente.

CVE oficial pendiente de asignación —la investigación está en curso— pero el vector está documentado: TeamPCP obtuvo las credenciales de publicación npm del proyecto mediante un ataque de phishing dirigido a un maintainer del equipo de Aqua Security. Con esas credenciales, publicaron versiones troyanizadas de @aquasecurity/trivy-node —el wrapper npm de Trivy— con el dropper de CanisterWorm embebido en el hook postinstall. El primer lote de publicaciones maliciosas apareció el 3 de marzo de 2026. Tres semanas sin ese número apareciendo en ningún feed de threat intelligence.

Eso no lo hace un ciberdelincuente ordinario.

Trivy como vector: qué comprometió realmente TeamPCP

Trivy es el escáner de vulnerabilidades de contenedores más utilizado en pipelines de CI/CD, con más de 21 millones de descargas mensuales en npm y presencia documentada en GitHub Actions, GitLab CI y workflows de ArgoCD. Su posición en el pipeline es estratégica: corre con privilegios elevados, tiene acceso a registros de contenedores privados, y genera manifiestos de vulnerabilidades que consumen otras herramientas de la cadena. Un escáner que no puede escanear no cumple su función —y por eso los equipos de seguridad lo instalan con los permisos necesarios para acceder a todo.

TeamPCP no comprometió la aplicación Trivy —el binario oficial y las imágenes Docker de Aqua Security permanecen limpias según los hashes publicados. Comprometieron el paquete npm @aquasecurity/trivy-node, el wrapper JavaScript que utilizan los integradores para invocar Trivy desde pipelines Node.js. Una distinción técnica que la mayoría de los equipos que revisaron su SBOM inicial no verificaron con suficiente granularidad.

Componente Trivy Versiones afectadas Mecanismo de infección
Binario trivy (GitHub Releases) Ninguna N/A — no comprometido
Imagen Docker aquasec/trivy Ninguna N/A — no comprometida
npm @aquasecurity/trivy-node v0.9.4 – v0.9.7 Dropper en hook postinstall

La elección del hook postinstall es deliberada: este lifecycle script de npm se ejecuta automáticamente durante npm install, antes de que el desarrollador interactúe con el paquete. No requiere ejecución explícita del código comprometido. Si tienes el paquete en ese rango de versiones en tu package-lock.json, el dropper ya se ejecutó en cada entorno donde hayas instalado dependencias.

CanisterWorm: el worm que se propaga sin intervención del atacante

Lo que diferencia a CanisterWorm de un supply chain attack convencional es su capacidad de autopropagación autónoma. TeamPCP no publica manualmente en cada paquete infectado —el worm lo hace por ellos.

El mecanismo opera en tres fases tras la infección inicial:

  1. Reconocimiento de tokens: escanea ~/.npmrc, .npmrc local y variables de entorno en busca de tokens npm con permisos de publicación. En entornos de CI/CD, estos tokens suelen estar presentes como variables de entorno para habilitar releases automatizados.
  2. Inventario de paquetes publicables: consulta la API de npm Registry para identificar qué paquetes están asociados a los tokens encontrados y sobre los que el token tiene permisos de escritura.
  3. Autopublicación troyanizada: publica versiones con bump de patch (+0.0.1) de todos los paquetes identificados, incluyendo el dropper de CanisterWorm en el hook postinstall. Un bump de patch en semver estándar activa automáticamente la actualización en cualquier proyecto que use rangos ^x.y.z o ~x.y.z.

En 21 días, 66 paquetes confirmados comprometidos. Npm Security Team tiene bajo análisis más de 80 adicionales sospechosos.

La efectividad del mecanismo depende de un patrón operacional común: tokens npm con permisos de publicación en CI/CD, sin MFA, con alcance demasiado amplio. Según el análisis de Socket Security publicado en enero de 2026, el 23% de los paquetes npm con más de 100.000 descargas semanales tienen tokens de publicación en CI/CD sin scoping granular por paquete.

El C2 en blockchain: por qué el firewall no ayuda aquí

El canal de comando y control es donde CanisterWorm presenta su innovación más problemática para los defensores.

Las instrucciones no llegan por IP ni dominio convencional. TeamPCP codifica los comandos en el campo input data de transacciones a una wallet fija en la blockchain de Ethereum. El módulo C2 del worm monitoriza esa wallet a través de nodos RPC públicos —Infura, Alchemy, QuickNode— cada 15 minutos. Cuando TeamPCP quiere activar el wiper, exfiltrar datos o actualizar el payload, construye una transacción con el comando en hexadecimal. Coste por instrucción: menos de $0.01 en gas fees.

Las implicaciones defensivas son concretas:

  • Bloqueo por IP inviable: los nodos RPC de Infura y Alchemy sirven tráfico legítimo para miles de aplicaciones Web3, SDKs de desarrollo y herramientas internas. Bloquearlos rompe workflows legítimos en la mayoría de organizaciones.
  • Tráfico HTTPS indistinguible: las peticiones a los nodos RPC son HTTPS estándar, con el mismo User-Agent que cualquier otra llamada a una API externa. No hay firma de red que bloquear sin falsos positivos masivos.
  • Inmutabilidad del C2: a diferencia de dominios que pueden ser secuestrados o expirar, la wallet de Ethereum es permanente e inmutable. TeamPCP puede estar inactivo durante meses y retomar el control en cualquier momento sin registrar ningún nuevo dominio.

Mi perspectiva técnica se basa en los análisis publicados por Socket Security y ReversingLabs hasta el 22 de marzo de 2026; no he tenido acceso al análisis forense completo de Aqua Security, que estaba pendiente de publicación en el cierre de este artículo.

El wiper de Kubernetes y la firma iraní

El payload de segundo estadio escala la amenaza de supply chain attack a ataque destructivo con motivación geopolítica.

Cuando TeamPCP activa el módulo wiper a través del canal blockchain, CanisterWorm ejecuta una secuencia de destrucción contra el cluster Kubernetes del entorno comprometido: kubectl delete namespace --all, seguido de escritura de datos basura directamente en etcd si el puerto está accesible desde el pod, y eliminación de todos los PersistentVolumeClaims antes de que puedan liberarse de forma controlada.

Borrado completo del cluster host.

El análisis forense de CrowdStrike Threat Intelligence sobre tres incidentes confirmados reveló una anomalía: el módulo wiper incluye una verificación de activación automática independiente del C2. Si el locale del sistema operativo es fa_IR (persa/Farsi) o si la IP de salida corresponde a rangos asignados a proveedores de telecomunicaciones iraníes —Irancell, ASIS, Pishgaman, entre otros—, el módulo wiper se activa sin esperar instrucción explícita del canal blockchain.

Esto convierte a CanisterWorm en una herramienta de doble función: espionaje y exfiltración de datos en el resto del mundo, con activación destructiva automática en infraestructura iraní. Un patrón consistente con actores de amenaza con motivación geopolítica —aunque la atribución pública definitiva a un estado específico no estaba confirmada en el momento de publicar este artículo.

Para entender cómo un único vector de acceso a infraestructura de seguridad puede comprometer una red completa, el análisis de CVE-2026-20131 en Cisco FMC describe un patrón de escalada con similitudes estructurales.

Acciones inmediatas sin ambigüedad

La respuesta no tiene opciones intermedias:

  1. Audita dependencias ahora: verifica si @aquasecurity/trivy-node en versiones v0.9.4–v0.9.7 aparece directa o transitivamente en package-lock.json o yarn.lock. La versión segura mínima es v0.9.8.
  2. Revoca todos los tokens npm expuestos: cualquier token npm presente en .npmrc o como variable de entorno en entornos donde se haya ejecutado el paquete comprometido debe tratarse como comprometido. Genera tokens nuevos con scoping por paquete y permisos mínimos.
  3. Audita el historial de publicaciones de tus paquetes: si encuentras bumps de patch no autorizados entre el 3 y el 22 de marzo de 2026, el paquete está infectado. Contacta con npm Security Team y publica una versión de rollback.
  4. Revisa acceso saliente a nodos RPC Ethereum desde tus pipelines CI/CD: si no los usas legítimamente, bloquea las IPs de Infura y Alchemy en los security groups de tus runners. No elimina el riesgo en instalaciones ya comprometidas, pero interrumpe la comunicación activa con el C2.
  5. Activa MFA y scoping granular en todos los tokens npm de publicación: es inaceptable que en 2026 tokens de paquetes con millones de descargas semanales estén protegidos solo por contraseña.

Mi veredicto es claro: CanisterWorm es el supply chain attack más sofisticado contra el ecosistema npm desde el incidente de event-stream en 2018. La combinación de autopropagación semver, C2 en blockchain e indicadores geopolíticos en el payload lo coloca en una categoría que exige una respuesta de seguridad completa, no solo una actualización de dependencias. Las organizaciones con pipelines Node.js y Kubernetes en producción deben auditar esto esta semana.

¿Te ha sido útil?

Preguntas Frecuentes

¿Qué versiones de @aquasecurity/trivy-node están comprometidas?

Las versiones comprometidas son v0.9.4, v0.9.5, v0.9.6 y v0.9.7 del paquete npm @aquasecurity/trivy-node. La versión v0.9.8, publicada por Aqua Security el 22 de marzo de 2026, está limpia y es la versión mínima segura. El binario oficial de Trivy y las imágenes Docker de aquasec/trivy no están comprometidos.

¿Cómo sé si mis tokens npm fueron robados por CanisterWorm?

Revisa el historial de publicaciones de todos los paquetes npm asociados a tus tokens —tanto en npm Registry como en tus pipelines CI/CD. Si encuentras versiones publicadas entre el 3 y el 22 de marzo de 2026 que no reconoces (generalmente bumps de patch +0.0.1 no autorizados), el token correspondiente fue comprometido. Revoca inmediatamente todos los tokens npm de cualquier entorno donde hayas instalado las versiones afectadas de trivy-node.

¿El binario oficial de Trivy o las imágenes Docker están comprometidos?

No. TeamPCP comprometió exclusivamente el paquete npm @aquasecurity/trivy-node (el wrapper JavaScript), no la aplicación Trivy ni sus imágenes Docker. Los hashes de los binarios oficiales de GitHub Releases y las imágenes aquasec/trivy en Docker Hub han sido verificados por Aqua Security y no están afectados. Solo el paquete npm en las versiones v0.9.4–v0.9.7 está comprometido.

¿Por qué el C2 en blockchain es más difícil de bloquear que un C2 convencional?

Un C2 convencional usa dominios o IPs que pueden ser bloqueados a nivel DNS o firewall. El C2 de CanisterWorm usa el campo input data de transacciones en la blockchain de Ethereum, que el worm consulta a través de nodos RPC públicos como Infura o Alchemy. Bloquear estos nodos es impractical porque sirven tráfico legítimo para miles de aplicaciones. Además, la wallet de Ethereum es permanente e inmutable, por lo que el C2 no puede ser eliminado aunque TeamPCP pierda acceso a sus sistemas.

¿Qué hace exactamente el wiper de Kubernetes de CanisterWorm?

El wiper ejecuta kubectl delete namespace --all para eliminar todos los namespaces y sus recursos, intenta corromper etcd directamente si el puerto está accesible desde el pod comprometido, y elimina todos los PersistentVolumeClaims antes de que puedan liberarse de forma limpia. El resultado es la destrucción completa del cluster. El módulo se activa por comando C2 en la mayoría de los casos, pero en entornos con locale fa_IR o IPs de telecomunicaciones iraníes se activa automáticamente sin esperar instrucción.

Fuentes y Referencias (6)

Las fuentes utilizadas para elaborar este artículo

  1. 1

    CanisterWorm: Self-Spreading npm Supply Chain Attack via Blockchain C2

    Socket Security Blog22 mar 2026
  2. 2

    Trivy npm Wrapper Compromise: TeamPCP Supply Chain Attack Analysis

    ReversingLabs Research21 mar 2026
  3. 3

    CanisterWorm Threat Actor Profile: TeamPCP Kubernetes Wiper

    CrowdStrike Threat Intelligence22 mar 2026

Todas las fuentes fueron verificadas en la fecha de publicación del artículo.

Elena Duran
Escrito por

Elena Duran

Periodista tech veterana especializada en el sector enterprise. No se anda con rodeos.

#trivy#canisterworm#supply chain attack#npm#blockchain c2#kubernetes#wiper#teampcp#ciberseguridad#open source

Artículos Relacionados