Olá, mundo da internet,
Lembra-se do ataque Shai-Hulud que afetou o @AntV a 19 de maio de 2026? Eu sei, parece que já foi há uma eternidade no mundo da cadeia de abastecimento. Uma conta de mantenedor comprometida publicou 639 versões maliciosas de pacotes @antv no npm numa única hora. Nós, juntamente com a maior parte da comunidade de segurança do npm, desmantelámos essa carga útil em poucas horas. Não havia nada de novo em termos de técnicas. Foi apenas mais um dia a acordar com um ataque à cadeia de abastecimento. O funcionamento habitual.
Desde então, o npm introduziu a análise de 'malware' no momento da publicação. Portanto, pode imaginar a minha surpresa quando estava a analisar a nossa fila de triagem esta manhã e vi o que reconheci imediatamente como um 'worm'. Tinha o mesmo 'hash' do @AntV ataque. A mesma carga útil:
e37e3ddeeaaa9e0c4fdbcb829b4895a6521031c80053fc436625b61e6ee5b1a6. Este é exatamente o mesmo ficheiro que o npm, nós e metade dos fornecedores desta lista já tinham identificado por impressões digitais há meses.
Isto representa 111 dias de silêncio absoluto sobre esse 'hash'. Tanto quanto conseguimos apurar, este é o maior intervalo entre a inatividade e a reativação que já vimos numa carga útil Shai-Hulud, e nem sequer se equipara a outros. Pode chamar-lhe o que é: um 'zombie', que ressurge quatro meses depois de todos assumirem que estava morto.
Os quatro pacotes que o trouxeram de volta, todos publicados na mesma hora, a 7 de setembro, pela mesma conta do npm:
feishu-docx-mcp@0.3.2bmc-i18n-extract-cli@1.1.1blueai-cli@0.7.0bmc-translate-utils@1.1.1
Os números
Analisámos o nosso histórico de deteção para este hash exato de ficheiro em todas as versões de pacotes que examinámos. Eis qual é realmente a cronologia:
Os nossos registos mostram 319 versões de pacotes com este hash, todas e cada uma delas detetadas pela primeira vez a 19 de maio de 2026, o dia da @AntV vaga e nem um dia antes ou depois. Depois, nada. Zero novas ocorrências deste hash entre 20 de maio e 6 de setembro. A seguir, a começar hoje (7 de setembro), mais quatro versões de pacotes foram lançadas no npm com exatamente a mesma payload. Isto representa um intervalo de 111 dias: visto pela última vez a 19 de maio, visto novamente a 7 de setembro.
Quatro pacotes são um número reduzido associado a um facto maior: uma payload com um hash conhecido, publicado e indexado permaneceu intocada na cadeia de ferramentas de ninguém durante mais de três meses e foi depois republicada num registo que, desde este ano, analisa explicitamente cada pacote antes de este ficar ativo.
O caso mais simples
Em julho, o npm implementou a análise de malware no momento da publicação: cada pacote fica retido durante 5 a 15 minutos enquanto um sistema automatizado o verifica antes de poder ser instalado. De acordo com o próprio registo de alterações do npm, o objetivo é detetar "o malware que conseguimos detetar" antes de chegar ao npm install.
Uma correspondência de hash de ficheiro é uma consulta, não um problema complexo. Não requer nenhuma análise de comportamento, sandboxing ou raciocínio sobre a intenção de código ofuscado. E esta payload não era inovadora, nem reempacotada, nem sequer ligeiramente modificada para iludir a correspondência de assinaturas. Tratava-se dos mesmos 64 caracteres hexadecimais que constavam nos registos desde maio.
Não estamos a dizer que o motor de análise deve detetar tudo. Casos como carregadores de múltiplos estágios, confusão de dependências e payloads acionadas em runtime são genuinamente difíceis de resolver. No entanto, uma correspondência exata de hash com um worm que gerou notícias internacionais de segurança há quatro meses não o é. Esse é o nível mínimo do que a análise no momento da publicação deve detetar, e isso falhou. Esta amostra específica deveria fazer parte do corpus de testes de qualquer entidade que faça análise da cadeia de fornecimento.
A principal conclusão
Uma payload de um worm com um hash público, extensos artigos de fornecedores e meses de cobertura de deteção permaneceu dormente durante 111 dias e, em seguida, regressou sem entraves ao npm, num registo que agora se promove com base na análise de todas as publicações. Esse fosso entre o que a análise ao nível do registo afirma fazer e o que uma reativação com o mesmo hash demonstra que efetivamente detetou é a verdadeira questão aqui. A correspondência de assinaturas contra artefactos maliciosos conhecidos é o obstáculo mais fácil de ultrapassar nesta indústria, e é o obstáculo cuja falha mais nos deve alarmar a todos. Se é isto que passa no caso mais simples, vale a pena perguntar o que faria uma payload que se desse ao trabalho de alterar um único byte.
Indicadores de Comprometimento
Rede:
t[.]m-kosche[.]com(C2, da vaga original de maio)
Ficheiro:
- SHA256:
e37e3ddeeaaa9e0c4fdbcb829b4895a6521031c80053fc436625b61e6ee5b1a6 - Ao nível da raiz
index.jspayload - script preinstall em execução
bun run index.js
Persistência:
.vscode/tasks.json.claude/settings.json
Comportamental:
- Chamadas de validação de saída contra o registo npm utilizando tokens roubados
- Ciclo de transferência de tarball, injeção de payload, incremento de versão e republicação
- Criação em massa de repositórios do GitHub com nomes temáticos de Dune e strings "Shai-Hulud" invertidas nas descrições