În urma compromiterii procesului de formare a versiunilor pe baza GitHub Actions, atacatorii au reușit să publice în repository-ul NPM 84 de versiuni dăunătoare, acoperind 42 de pachete NPM din stiva TanStack. Unele dintre pachetele compromise aveau peste 10 milioane de descărcări pe săptămână.
Accesul la publicarea versiunilor a fost obținut din cauza configurării incorecte a pull_request_target 'Pwn Request' în GitHub Actions (specificarea unei măști în setări a dus la rularea pull_request_target pentru cereri de pull din fork-uri externe), contaminării cache-ului GitHub Actions prin fork și posibilității extragerii token-ului OIDC din memoria procesului runner (Runner.Worker) citind conținutul /proc//mem.
Pachetele NPM cu modificări dăunătoare au fost publicate pe 11 mai între 22:20 și 22:26 (MSK), observate după 20 de minute și blocate după o oră și jumătate. Fiecare dintre pachetele NPM afectate a primit câte două versiuni dăunătoare, în care a fost integrat un cod pentru activarea worm-ului mini-shai-hulud, care căuta token-uri și acreditive în mediul curent. Dacă descoperit un token de conectare la directory-ul NPM, worm-ul publica automat noi versiuni dăunătoare pentru pachetele dezvoltate în mediul curent, afectând arborii de dependențe. În acest mod, au fost compromise peste 400 de pachete NPM care utilizau pachete TanStack ca dependențe.
Worm-ul era plasat în fișierul router_init.js și era activat la instalarea manuală a pachetului afectat de către dezvoltator sau automat în mediu de integrare continuă prin comenzile 'npm install', 'pnpm install' sau 'yarn install'. După activare, worm-ul căuta în sistem token-uri pentru NPM (~/.npmrc), AWS, GCP, Azure, HashiCorp și KubernetesK8s, precum și chei SSH private. Datele găsite erau trimise atacatorilor prin intermediul mesagerului P2P descentralizat getsession.org.
Worm-ul era proiectat să efectueze acțiuni distructive în cazul retragerii unui token NPM interceptat — în sistem se configura o execuție periodică a scriptului ~/.local/bin/gh-token-monitor.sh, care verifica activitatea token-ului la fiecare 60 de secunde prin apelarea api.github.com/user și, în cazul retragerii token-ului, executa comanda 'rm -rf ~/'.
Sursa: opennet.ro
