Shai-Hulud, parte 2: Cuando el Worm su propio certificado de seguridad

May 13, 2026
5/13/2026
Lucie Cardiet
Responsable de investigación de ciberamenazas
Shai-Hulud, parte 2: Cuando el Worm su propio certificado de seguridad

Esta mañana, TeamPCP ha publicado worm GitHub el código fuente completo del worm de cadena de suministro Shai-Hulud. Licencia MIT. Dos repositorios. Cuarenta y cuatro bifurcaciones en cuestión de horas, una de las cuales añadió compatibilidad con FreeBSD antes de que la mayoría de los equipos de seguridad hubieran leído siquiera el titular.

¿Está codificado por vibración? Sí. ¿Funciona? Que hablen los resultados. Cambia las teclas y la C2 según sea necesario. Con cariño, el equipo de PCP

El año pasado escribí sobre Shai-Hulud. En esa entrada se describían los mecanismos básicos: cómo el worm en la instalación de paquetes, cambia de entornos de ejecución para evitar ser detectado, recopila credenciales, se filtra a través de repositorios públicos de GitHub y se propaga aprovechando la confianza que la víctima ya tiene en el ecosistema.

Esos mecanismos siguen vigentes. Sin embargo, la campaña de mayo de 2026 contra TanStack y otros más de 170 paquetes introdujo un elemento que no se mencionaba en la publicación original. El worm a hacer que sus paquetes maliciosos parecieran certificados.

Captura de pantalla del repositorio de GitHub publicado por TeamPCP

¿Qué ha cambiado en la campaña de TanStack?

En todos los ataques anteriores de Shai-Hulud, el worm tokens de npm y publicaba paquetes maliciosos bajo la cuenta de la víctima. Los paquetes parecían legítimos porque procedían de un editor conocido. Ahí radicaba el engaño.

La campaña TanStack añadió un paso más. Según un estudio publicado por Wiz, StepSecurity y Snyk, el worm un token OIDC de la memoria del proceso del ejecutor de GitHub Actions. A continuación, utilizaba ese token para obtener un certificado de firma criptográfica de la autoridad de certificación Fulcio de Sigstore. Utilizaba ese certificado para firmar el paquete malicioso.

El resultado: el paquete malicioso incluía un certificado de procedencia SLSA de nivel 3 válido. No era falso. Era legítimo, emitido por Sigstore a nombre de la identidad de GitHub Actions de la víctima.

Las credenciales robadas se filtraron a git-tanstack[.]com, un dominio falso registrado específicamente para la operación, junto con los puntos de acceso de Session Network y un conjunto de repositorios de GitHub con el tema «Dune». Mientras se llevaba a cabo el ataque, TeamPCP dejó el siguiente mensaje en ese dominio:

Mensaje dejado por TeamPCP en su dominio C2 git-tanstack[.]com durante el ataque en directo, en mayo de 2026. Fuente: Wiz.
(El enlace de YouTube lleva al videoclip de «Hello» de Martin Solveig. No es una carga útil.)

Qué son los tokens OIDC y por qué residen en la memoria del ejecutor

OIDC son las siglas de OpenID Connect. En el contexto de GitHub Actions, resuelve un problema concreto relacionado con la gestión de credenciales : los flujos de CI/CD necesitan autenticarse en servicios externos (registros de npm, cloud , Sigstore) sin almacenar claves secretas de larga duración en el repositorio.

La solución es un token de corta duración. Cuando se ejecuta un trabajo, el proveedor OIDC de GitHub emite un token que representa la identidad específica de ese trabajo: este flujo de trabajo, este repositorio, esta confirmación, este actor. El token está disponible para el ejecutor a través de una variable de entorno y un punto de conexión local. Caduca a los pocos minutos de su emisión.

La premisa de seguridad es que el token es temporal y tiene un ámbito limitado. Un atacante que consiga acceder a los secretos almacenados de un desarrollador no podrá reutilizar un token de una tarea anterior, ya que este habrá caducado. Esa premisa es válida en condiciones normales.

El worm funciona en condiciones normales. Ejecuta código dentro de la propia tarea de Actions, en el momento en que el token está activo.

Cómo funciona la extracción en la práctica

El worm el ACTIONS_ID_TOKEN_REQUEST_TOKEN variable de entorno del proceso del ejecutor y la utiliza para solicitar un token OIDC al punto final OIDC de GitHub. A continuación, envía ese token a la CA Fulcio de Sigstore, que emite un certificado X.509 de corta duración vinculado a la identidad de la tarea de GitHub Actions. Con ese certificado y una entrada en el registro de transparencia de Rekor, el worm una firma cosign válida y un certificado de procedencia SLSA para el paquete que está a punto de publicar.

Cada paso es una llamada legítima a la API de un servicio legítimo. El ejecutor tiene permiso para realizarlas todas. Esa es la clave. El código malicioso se ejecuta dentro de un trabajo que ha obtenido esos permisos a través de la configuración de confianza del repositorio, y los utiliza exactamente como estaba previsto.

¿Por qué falla la verificación de la procedencia?

La verificación de la procedencia SLSA está diseñada para responder a una pregunta concreta: ¿se ha compilado este artefacto mediante el sistema de compilación previsto, a partir del código fuente esperado y sin interferencias no autorizadas? El nivel de compilación 3 exige específicamente un entorno de compilación reforzado que impida que el proceso altere su propia procedencia.

La técnica OIDC de Shai-Hulud elude la hipótesis de diseño, pero no el control técnico:

  • El sistema de compilación no se ve afectado.
  • El punto final OIDC no se ha visto comprometido.
  • La CA Fulcio de Sigstore no se ha visto comprometida.

Lo que el certificado no puede reflejar es que el código que se ejecutó dentro del trabajo no era el que el responsable tenía previsto ejecutar. El worm a través de una dependencia instalada anteriormente en el proceso.

Desde el punto de vista de Sigstore, un ejecutor legítimo de GitHub Actions, que opera bajo la identidad de un repositorio legítimo, firmó un artefacto legítimo. La certificación es correcta en lo que respecta a esos hechos. No dice nada sobre cómo llegó allí la carga útil.

El certificado verifica la identidad del firmante. No verifica las intenciones del firmante ni qué otros procesos se estaban ejecutando en el mismo proceso.

Dos problemas de detección, no uno

En la publicación original sobre Shai-Hulud se planteaba esto como un problema en el que «todo parece estar en orden»: las acciones individuales worm —instalar paquetes, ejecutar scripts, publicar en npm— son todas operaciones rutinarias que no generan ninguna malware ni activan ninguna infracción de las políticas. Cada paso parece formar parte del trabajo habitual de desarrollo.

La técnica OIDC pone de manifiesto un segundo problema relacionado: el movimiento en sí mismo no es visible. La extracción del token y la llamada de firma a Sigstore son movimientos laterales a través de la capa de identidad del entramado de confianza de CI/CD. El worm una credencial federada de GitHub, la presenta a Sigstore y recibe un certificado que autoriza la publicación en npm bajo la cadena de procedencia de la víctima. El movimiento atraviesa tres sistemas distintos: el proveedor OIDC de GitHub, la CA de Sigstore y el registro de npm. Cada sistema registra un evento de autenticación limpio.

Son tres registros de auditoría y tres autenticaciones correctas. La entrada del registro que no existe es la que indicaría que el código que realizó esas llamadas no debería estar ahí.

En el marco que utilizo en «Mind Your Attack Gaps», estos se corresponden con dos de las tres brechas de detección fundamentales: «no parece haber ningún problema» (brecha 1) y «el movimiento no es visible» (brecha 3). La mayoría de los ataques a la cadena de suministro activan una de ellas. Esta técnica activa ambas simultáneamente, razón por la cual logró pasar desapercibida en los análisis automatizados de 170 paquetes antes de que ningún proveedor la detectara.

Qué cambia con la apertura del código fuente

Hasta hoy, la técnica de extracción OIDC se atribuía a un solo grupo. Todos los incidentes relacionados con ella se remontaban a TeamPCP. Los análisis forenses realizados por Wiz, Ox Security y ReversingLabs permitían detectar sus indicadores específicos: los dominios C2, los nombres de los archivos de carga útil y los patrones de exfiltración hacia repositorios relacionados con Session Network y Dune.

La publicación en código abierto rompe ese modelo de contención. Cualquier actor que cree una bifurcación del repositorio obtiene la capacidad de extraer datos OIDC. Los indicadores específicos variarán en cada variante. La técnica sigue siendo la misma.

La bifurcación de FreeBSD, añadida pocas horas después de que los repositorios entraran en funcionamiento, ilustra el ritmo. El worm se ejecuta en plataformas en las que el original nunca se probó. PyPI es un ecosistema objetivo confirmado de la campaña de mayo de 2026. RubyGems y Maven son los siguientes candidatos obvios. Las 401 versiones de paquetes maliciosos publicadas en 170 paquetes en un intervalo de cinco horas el 11 de mayo establecieron una referencia. Los actores derivados que utilicen este kit de herramientas no serán más lentos.

Publicación en la cuenta de TeamPCP en X : «Este es el año de la cadena de suministro. Vais a estar muy ocupados durante mucho tiempo». — 31 de marzo de 2026

Cómo funciona la detección

El análisis de artefactos no puede detectar esto. La certificación es válida. La firma es válida. El paquete funciona correctamente. Los usuarios que verifiquen la procedencia SLSA antes de la instalación obtendrán un resultado satisfactorio.

Las señales son de tipo conductual y aparecen antes de que se publique el paquete malicioso. Que un ejecutor de CI solicite un token OIDC y llame al punto final Fulcio de Sigstore no es algo inusual en sí mismo. Sin embargo, que un ejecutor haga eso y, además, establezca conexiones salientes con un host desconocido durante la misma ejecución del trabajo es una secuencia que merece la pena examinar. Una publicación de paquete que se produzca tras una actividad de red anómala en la misma sesión del ejecutor es la cadena que hay que detectar.

La publicación original enumeraba estas señales de comportamiento: un token de GitHub que creaba repositorios en un volumen inesperado, un ejecutor de CI que leía cloud más allá del alcance de su tarea declarada y una cloud que llamaba a servicios que nunca había utilizado. Las nuevas incorporaciones son una solicitud OIDC, una llamada a la API de Sigstore y una publicación en npm dentro de la misma tarea, que también generó conexiones salientes desconocidas.

Cada acción es legítima. La combinación, en cambio, no lo es.

¿Por qué es importante aquí el contexto en los distintos entornos?

Vectra AI supervisa los patrones de comportamiento en los sistemas de identidad, las redes y cloud . En los incidentes de la cadena de suministro, las señales relevantes rara vez se encuentran en un único registro. Se encuentran en la correlación: ¿qué hizo este proceso antes de publicarse? ¿Qué hosts externos aparecieron en el tráfico de red de este trabajo que no estaban presentes en las últimas cincuenta ejecuciones? ¿A qué llamó esta cloud que no había llamado antes?

El problema de detección que plantea Shai-Hulud no es un problema de firma. Es un problema de contexto. El contexto se encuentra repartido en tres registros de auditoría y un rastro de red. Cuando se correlacionan, la huella de comportamiento worm se hace visible antes de que el paquete malicioso llegue a cualquier destinatario posterior.

--

El patrón general, en el que las credenciales de identidad federada se desplazan lateralmente a través de la estructura de confianza de CI/CD para autenticarse en los servicios posteriores, es lo que denomino la brecha «el movimiento no es visible» (Brecha 3) en el libro electrónico Mind Your Attack Gaps. El capítulo 3 analiza en detalle el patrón de movimiento entre entornos, tomando como caso de estudio principal la ola de la cadena de suministro de OAuth. La técnica OIDC de Shai-Hulud presenta el mismo problema estructural dentro del canal de compilación que en la capa SaaS.

--

Fuentes primarias:

Preguntas frecuentes