Como resultado de la compromisión del proceso de formación de lanzamientos en base a GitHub Actions en el proyecto TanStack, un atacante logró publicar 84 versiones maliciosas en el repositorio NPM, abarcando 42 paquetes NPM del ecosistema de TanStack. Algunos de los paquetes comprometidos tenían más de 10 millones de descargas por semana.
El acceso a la publicación de lanzamientos fue obtenido debido a una configuración incorrecta del pull_request_target "Pwn Request" en GitHub Actions (la especificación de la máscara en la configuración llevó a activar pull_request_target para pull requests en forks externos), la contaminación de la caché de GitHub Actions a través de un fork y la posibilidad de extraer el token OIDC de la memoria del proceso runner activo (Runner.Worker) mediante la lectura del contenido /proc//mem.
Los paquetes NPM con cambios maliciosos fueron publicados el 11 de mayo entre las 22:20 y las 22:26 (MSK), fueron detectados 20 minutos después y bloqueados una hora y media más tarde. Para cada uno de los paquetes NPM afectados se lanzaron dos versiones maliciosas, en las que se integró el código para activar el gusano mini-shai-hulud, que buscaba tokens y credenciales en el entorno actual. Si se encontraba un token de conexión al directorio NPM, el gusano publicaba automáticamente nuevos lanzamientos maliciosos para los paquetes en desarrollo en el entorno actual, afectando el árbol de dependencias. De esta manera, más de 400 paquetes NPM que utilizaban paquetes de TanStack como dependencias fueron comprometidos.
El gusano estaba alojado en el archivo router_init.js y se activaba al instalar el paquete comprometido manualmente por un desarrollador o de manera automatizada en un entorno de integración continua mediante los comandos "npm install", "pnpm install" o "yarn install". Tras su activación, el gusano buscaba tokens en el sistema para NPM (~/.npmrc), AWS, GCP, Azure, HashiCorp y KubernetesK8s, así como claves SSH privadas. La información encontrada se enviaba a los atacantes a través de un mensajero descentralizado P2P llamado getsession.org.
El gusano estaba programado para realizar acciones destructivas en caso de que se revocara el token NPM interceptado; en el sistema se configuraba una ejecución periódica del script ~/.local/bin/gh-token-monitor.sh, que cada 60 segundos verificaba la actividad del token mediante una llamada a api.github.com/user y, en caso de revocación del token, ejecutaba el comando "rm -rf ~/".
Fuente: opennet.ru
