Mini Shai-Hulud compromete pacotes npm e PyPI em ataque à cadeia de suprimentos

Mini Shai-Hulud compromete pacotes npm e PyPI em ataque à cadeia de suprimentos

Campanha atribuída ao TeamPCP inseriu stealers em pacotes de TanStack, Mistral AI, Guardrails AI, UiPath e outros projetos, com exfiltração de credenciais, persistência em IDEs e abuso de identidades de CI/CD.

ComponentePacotes npm e PyPI associados a TanStack, UiPath, Mistral AI, OpenSearch, Guardrails AI, DraftLab e outros mantenedores, incluindo 42 pacotes e 84 versões no ecossistema TanStack.
VetorPublicação de pacotes adulterados por fluxos de CI/CD e identidades de publicação confiável, com execução por preinstall, prepare, dependência opcional hospedada no GitHub, Bun, Node.js ou execução em importação Python.
ImpactoRoubo de credenciais de nuvem, carteiras de criptomoedas, ferramentas de IA, aplicativos de mensagens, GitHub, sistemas de CI e segredos de repositório; exfiltração para filev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com, GitHub API e infraestrutura remota.
PrioridadeIsolar máquinas de desenvolvedores e runners afetados antes de revogar tokens, preservar imagem forense, remover pacotes comprometidos, rotacionar credenciais e revisar fluxos GitHub Actions com OIDC e pull_request_target.
VersõesO comprometimento TanStack foi associado ao identificador CVE-2026-45321, com severidade crítica e pontuação CVSS 9.6; a onda total afetou mais de 170 pacotes em npm e PyPI.
ArtefatosArquivo JavaScript ofuscado router_init.js, execução de node setup.mjs, artefato Python https://git-tanstack.com/transformers.pyz, persistência em Claude Code e Visual Studio Code, serviço gh-token-monitor e workflows maliciosos do GitHub Actions.
IoCsfilev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com, 83.142.209[.]194, repositórios contendo Shai-Hulud: Here We Go Again e commits atribuídos a claude@users.noreply.github.com.
Resumo técnico

A campanha Mini Shai-Hulud ampliou um comprometimento de cadeia de suprimentos para pacotes distribuídos por npm e PyPI, atingindo projetos ligados a TanStack, Mistral AI, Guardrails AI, UiPath, OpenSearch, DraftLab e outros mantenedores. O operador associado à atividade, identificado como TeamPCP, não se limitou a publicar versões adulteradas: a cadeia observada combina código malicioso em pacotes, abuso de fluxos de publicação, roubo de tokens, propagação entre pacotes do mesmo mantenedor e exfiltração redundante de credenciais. A superfície de risco é alta porque a instalação ou importação de um pacote comprometido ocorre dentro de estáções de desenvolvimento, pipelines e runners com acesso a segredos operacionais, credenciais de nuvem e permissões de publicação.

Nos pacotes npm, o payload foi distribuído por um arquivo JavaScript ofuscado, router_init.js, criado para perfilar o ambiente de execução e iniciar um stealer abrangente. O código procura credenciais associadas a provedores de nuvem, carteiras de criptomoedas, ferramentas de IA, aplicativos de mensagens, GitHub Actions e outros sistemas de CI. A exfiltração principal usa o domínio filev2.getsession[.]org, associado a infraestrutura do Session Protocol, o que dificulta bloqueios genéricos em ambientes corporativos porque o domínio pode parecer vinculado a um serviço legítimo de mensageria privada. Quando essa rota não funciona, o malware grava dados cifrados em repositórios controlados pelo atacante via GitHub GraphQL API, usando tokens GitHub roubados e o autor claude@users.noreply.github.com.

O caso TanStack recebeu o identificador CVE-2026-45321, com CVSS 9.6, e envolveu 42 pacotes e 84 versões no ecossistema do projeto. A onda completa ultrapassou 170 pacotes nos registros npm e PyPI, com mais de 518 milhões de downloads acumulados, e resultou na criação de pelo menos 400 repositórios contendo credenciais furtadas e a string Shai-Hulud: Here We Go Again. O dado operacional mais importante para defesa é que alguns artefatos carregam sinais de publicação aparentemente legítima, inclusive atestações SLSA Build Level 3 em pacotes maliciosos, o que reduz a utilidade de validações que confiam apenas na presença de proveniência sem avaliar o comportamento do build e a origem exata do fluxo que emitiu o token de publicação.

Fluxo técnico

A campanha usa mais de um caminho de execução. Em ondas anteriores, o comprometimento dependia de hooks preinstall para acionar a infecção durante a instalação do pacote. No agrupamento TanStack, a estratégia mudou: o pacote npm inclui um JavaScript malicioso dentro do tarball e declara uma dependência opcional que aponta para um pacote hospedado no GitHub. Essa dependência contém um hook prepare que executa o payload JavaScript com o runtime Bun. Já nos pacotes da Mistral AI, a técnica observada substitui o conteúdo de package.json por um hook preinstall que chama node setup.mjs; esse script baixa Bun e executa o mesmo malware JavaScript. Essa diferença exige hunting tanto em scripts de ciclo de vida quanto em dependências opcionais e artefatos incluídos diretamente no pacote publicado.

O comprometimento do TanStack foi rastreado para uma cadeia envolvendo GitHub Actions com pull_request_target, envenenamento de cache do GitHub Actions e extração em memória de um token OIDC do processo do runner. O atacante preparou o payload em um fork por meio de um commit órfão, inseriu o conteúdo em tarballs npm publicados e sequestrou o fluxo legítimo TanStack/router para publicar versões comprometidas com proveniência válida. A publicação não exigiu roubo direto de tokens npm nem comprometimento do workflow de publicação em si; a falha operacional ficou na capacidade de código controlado pelo atacante executar em um contexto com confiança suficiente para trocar a identidade OIDC por um token curto de publicação. Em configurações nas quais a relação de confiança do publicador OIDC é definida no nível do repositório, sem amarração rigorosa a ramo protegido e arquivo de workflow específico, uma execução inesperada ainda pode receber autoridade para publicar.

O worm também possui lógica de propagação. Ele procura tokens npm publicáveis com bypass_2fa definido como verdadeiro, enumera pacotes mantidos pela mesma conta e tenta trocar um token OIDC do GitHub por tokens de publicação por pacote, evitando autenticação tradicional. Essa técnica desloca o risco do segredo estático para a identidade transitória da pipeline: mesmo sem um token npm persistente exposto, uma execução maliciosa dentro de um workflow confiável pode receber credenciais temporárias suficientes para empacotar e distribuir código. Em paralelo, o malware instala persistência em Claude Code e Microsoft Visual Studio Code para reexecutar o stealer a cada inicialização das IDEs, cria o serviço gh-token-monitor para monitorar e reenviar tokens GitHub e injeta dois workflows GitHub Actions que serializam segredos de repositório em JSON e enviam os dados para api.masscan[.]cloud.

Nos pacotes PyPI, a família apresenta diferenças relevantes. O pacote guardrails-ai@0.10.1 foi destacado porque o código malicioso executa na importação, sem depender somente de instalação. Em sistemas Linux, ele baixa https://git-tanstack.com/transformers.pyz, grava o arquivo em /tmp/transformers.pyz e o executa com python3, sem verificação de integridade. Na análise do pacote malicioso mistralai em PyPI, o código baixa um stealer a partir de 83.142.209[.]194, inclui lógica para evitar ambientes em idioma russo e possui um ramo destrutivo georrestrito com chance de executar rm -rf / quando o sistema parece estar em Israel ou no Irã. Essa função destrutiva transforma parte da campanha em risco de indisponibilidade, não apenas de vazamento.

Superfície afetada

A superfície exposta inclui estáções de desenvolvedores, ambientes de build, runners de CI/CD, caches do GitHub Actions, repositórios com segredos, pacotes publicados por mantenedores impactados e ambientes que instalam dependências de forma automática. Projetos que consomem versões comprometidas podem executar o payload durante npm install, durante hooks de preparação de dependências, durante importação Python ou em rotinas de build que resolvem dependências sem pinagem estrita. A exposição aumenta quando pipelines possuem variáveis sensíveis, tokens GitHub com escopo amplo, credenciais de provedores de nuvem, chaves de publicação, acesso a registros de pacotes e permissões para acionar novos workflows.

A campanha também afeta controles de confiança de software. Pacotes publicados pelo próprio workflow legítimo do projeto podem carregar metadados de proveniência válidos e, ainda assim, conter conteúdo malicioso se o fluxo que emitiu a identidade OIDC foi induzido a executar código adversário. Por isso, lockfiles, hashes de artefatos, SBOMs, atestações SLSA e políticas de trusted publishing precisam ser avaliados em conjunto com escopo do workflow, ramo permitido, origem do evento, conteúdo do tarball e comportamento em instalação. Ambientes que tratam proveniência como aprovação automática ficam vulneráveis quando o problema está na execução que gerou a proveniência, e não apenas no canal de publicação.

  • Pacotes TanStack afetados por CVE-2026-45321, com 42 pacotes e 84 versões publicados de forma comprometida.
  • Pacotes npm com router_init.js, dependência opcional hospedada no GitHub, hook prepare, Bun ou preinstall chamando node setup.mjs.
  • Pacotes PyPI associados a Mistral AI e Guardrails AI, incluindo execução em importação no caso de guardrails-ai@0.10.1.
  • Runners GitHub Actions com uso de pull_request_target, cache compartilhado e confiança OIDC não restringida a ramo protegido e arquivo de workflow específico.
  • Estáções com Claude Code ou Visual Studio Code, nas quais a persistência do stealer pode sobreviver a reinicializações e novas sessões de desenvolvimento.
Hunting e telemetria

A investigação deve começar por inventário de dependências, lockfiles e caches de pacote. Em npm, compare versões instaladas e resolvidas contra listas internas de pacotes afetados, procure scripts preinstall, prepare e dependências opcionais incomuns, e extraia tarballs para localizar router_init.js ou JavaScript ofuscado não esperado. Em PyPI, busque artefatos que executem código durante importação, downloads remotos para transformers.pyz, gravações em /tmp/transformers.pyz e chamadas a python3 originadas por módulos de dependência. A ausência de erro de instalação não reduz o risco, porque o payload foi projetado para operar dentro de fluxos legítimos e exfiltrar silenciosamente dados do ambiente.

Na camada de rede, monitore conexões para filev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com e 83.142.209[.]194. Também é necessário inspecionar uso incomum da GitHub GraphQL API, criação de repositórios por contas de desenvolvedores, commits com autor claude@users.noreply.github.com, repositórios contendo Shai-Hulud: Here We Go Again e workflows adicionados sem revisão humana. Em endpoints, colete evidências de serviços persistentes com nome gh-token-monitor, alterações em diretórios de configuração do Claude Code e VS Code, scripts shell que consultam api.github.com/user a cada 60 segundos e tokens npm com descrição IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner..

A telemetria de CI/CD precisa responder a perguntas específicas: qual evento acionou o workflow, qual ramo ou commit foi usado, se o commit era órfão, quais caches foram restaurados, quais permissões OIDC foram concedidas, qual identidade solicitou token de publicação e qual pacote foi publicado em seguida. Eventos pull_request_target merecem atenção especial quando executam código derivado de forks, restauram cache controlável por contribuidor externo ou rodam etapas com permissão de escrita. Para repositórios com trusted publishing, valide se o provedor npm ou PyPI exige repositório, ramo protegido e caminho exato do workflow, e se há publicações recentes feitas por execuções não esperadas.

  • Requisições DNS ou HTTP para filev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com e 83.142.209[.]194.
  • Presença de router_init.js, setup.mjs, /tmp/transformers.pyz, Bun baixado por scripts de pacote ou execução de python3 iniciada por importação de dependência.
  • Criação de workflows GitHub Actions que leem segredos, serializam variáveis em JSON ou enviam conteúdo para servidor externo.
  • Uso anômalo da GitHub GraphQL API com tokens de desenvolvedor, criação de repositórios inesperados e commits atribuídos a claude@users.noreply.github.com.
  • Tokens npm com bypass_2fa verdadeiro, tokens GitHub recém-criados, descrições ameaçadoras em tokens e chamadas periódicas a api.github.com/user.
Mitigação

A resposta deve evitar revogação precipitada quando houver indicação do token com mecanismo destrutivo. O malware instala um dead man's switch que verifica periodicamente se um token npm criado por ele continua válido; caso o desenvolvedor revogue esse token diretamente pelo painel npm, o script pode executar rm -rf ~/ na máquina infectada. A primeira ação defensiva é desconectar o host da rede, preservar memória e disco quando possível, coletar artefatos de persistência, identificar processos em execução e somente depois revogar tokens a partir de um ambiente limpo. Para hosts com indício do ramo destrutivo em PyPI, trate o caso como incidente com risco de destruição local e priorize contenção física ou lógica antes de qualquer interação com credenciais.

Depois da contenção, remova versões comprometidas de caches internos, registros espelhados, imagens de build e ambientes de desenvolvimento. Recrie lockfiles a partir de versões verificadas, invalide caches do GitHub Actions associados ao período de comprometimento e reconstrua artefatos de produção que tenham consumido dependências afetadas. Rotacione tokens GitHub, npm, PyPI, credenciais de nuvem, chaves de carteiras, tokens de mensagens e segredos de CI que estiveram disponíveis em hosts, runners ou workflows expostos. A rotação deve considerar segredos lidos indiretamente por workflows injetados, não apenas arquivos presentes no endpoint.

Na prevenção, restrinja trusted publishing por repositório, ramo protegido e arquivo exato de workflow, reduza permissões padrão de GITHUB_TOKEN, exija revisão para alterações em workflows, desabilite ou limite pull_request_target quando etapas executarem conteúdo de fork e isole caches usados por contribuições externas. Workflows de publicação devem separar build, teste e publicação em contextos com permissões distintas; etapas que resolvem dependências de fork não devem ter acesso a OIDC capaz de emitir token de publicação. Em endpoints de desenvolvimento, monitore alterações em configurações de IDE, bloqueie execução automática de scripts de pacote quando o fluxo permitir e aplique allowlists de registros e domínios de download para builds reproduzíveis.

  • Isolar hosts e runners suspeitos antes de revogar tokens npm quando houver indício do token com descrição IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner..
  • Coletar imagem, memória, histórico de shell, processos, serviços, tarefas persistentes e alterações em Claude Code e Visual Studio Code.
  • Remover pacotes afetados de caches locais, proxies de dependência, imagens de CI e ambientes de build; reconstruir a partir de versões verificadas.
  • Rotacionar tokens GitHub, npm, PyPI, credenciais de nuvem, segredos de repositório e chaves expostas a pipelines ou estáções comprometidas.
  • Restringir OIDC e trusted publishing a ramo protegido e workflow específico, revisar uso de pull_request_target e invalidar caches do GitHub Actions do período afetado.

Postar um comentário

0 Comentários