TL, DR
Entre 15/06/2026 e 16/06/2026, um único publicador do npm fez um push. Seis pacotes — 26 versões no total. — que executam um script de instalação em cada npm installCada pacote inclui um arquivo README declarando-o como um artefato de pesquisa "benigno" para o programa de recompensas por bugs do HackerOne/GitHub, que "nunca" altera valores de credenciais e "não realiza nenhum tipo de persistência". O código não corresponde à declaração de isenção de responsabilidade. Em ambientes de CI Linux, o gancho de instalação identifica o ambiente e sonda um endpoint de metadados de instância na nuvem; no Windows, ele solicita elevação de privilégios e é executado como administrador. SYSTEMe abre um canal de comando para um host externo. O único indicador a ser procurado agora é o host C2. 173.255.233[.]239Gravidade: AltoEcossistema afetado: npmOs nomes se misturam ao ruído de dependência da integração contínua (metrics-pipeline-d8k2, event-metrics-q3x7, pkg-telemetry-r4f9e três irmãos).
O Ataque: Como Funciona
Todos os pacotes no cluster são construídos da mesma maneira. package.json integra o mesmo comando em dois ciclos de vida. hooks:
{ "scripts": { "preinstall": "node run.js", "postinstall": "node run.js" } } Correndo em ambos pré-instalação e pós-instalação Significa que a carga útil é acionada independentemente de as etapas de instalação posteriores falharem ou não. executar.js em si é um despachante de plataforma de dez linhas:
// Platform dispatcher — runs beaconNN.js on Windows, beacon_linux.js on Linux. // GitHub Bug Bounty authorized research. Contact: nicholas@curran.tech 'use strict'; const { execFileSync } = require('child_process'); const path = require('path'); const node = process.execPath; const script = process.platform === 'win32' ? path.join(__dirname, 'beacon34.js') : path.join(__dirname, 'beacon_linux.js'); try { execFileSync(node, [script], { stdio: 'inherit', timeout: 90000 }); } catch (e) {} O comportamento então se divide por sistema operacional. Todos os seis pacotes contêm as mesmas duas partes — executar.js e os beacons da plataforma — portanto, são droppers intercambiáveis em vez de seis ferramentas distintas. A única variação significativa entre eles é a cadência de publicação: quatro nomes foram lançados uma única vez, enquanto dois foram relançados a cada 30 a 60 minutos durante horas, o que mantém uma versão recém-publicada visível para instaladores e resolvedores, mesmo quando versões mais antigas são removidas.
No Linux (beacon_linux.jsO script cria perfis do ambiente em que está sendo executado. Ele enumera os nomes das variáveis de ambiente e lê arquivos em / proc, verifica para docker.sock, e corre hostname e whoamiEm seguida, ele envia uma solicitação HTTP para o endpoint de metadados da instância de contêiner da AWS. 169.254.170[.]2 — o endereço link-local que uma tarefa do ECS consulta para obter sua própria configuração e credenciais de função de curta duração (IMDS, o serviço de metadados da instância). Os resultados são enviados via POST para o coletor da campanha em 173.255.233[.]239.
No Windows (beacon34.js / beacon18.jsO pacote faz muito mais do que apenas criar um perfil do seu host. O código sinalizado adiciona uma chave de registro em configurações de ms manipulador com um DelegateExecute valor — uma ferramenta conhecida para burlar o controle de conta de usuário que permite que um processo iniciado seja executado com privilégios elevados sem aviso prévio. Ela invoca o PowerShell com -ExecutionPolicy Bypass e Invocar-Expressão, executa no AUTORIDADE NT \ SYSTEM contexto e consulta um host externo em busca de comandos. O canal de comando do Windows é executado sobre um túnel Cloudflare, diameter-coins-limitations-parents.trycloudflare[.]com:443, caindo de volta para 173.255.233 [.] 239: 443, utilizando três pontos de extremidade: /c2/enquete para buscar um comando, /c2/saída para retornar a saída, /c2/fim de fechar.
A novidade aqui: o aviso legal como camuflagem.
O elemento inovador não é o conteúdo em si — o reconhecimento por meio de hooks de instalação e a elevação de privilégios no Windows são ambos bem documentados. A novidade está na história de fachada. Cada pacote contém um arquivo README que se apresenta como um artefato de divulgação responsável:
# @ncurran/sandbox-recon-880538 — authorized npm-sandbox security research Isto é um benigno pacote publicado sob o escopo `@ncurran` do próprio autor como parte de um Participação autorizada no programa de recompensas por bugs HackerOne/GitHub (npm incluído).
Ao instalar, ele inspeciona. seu próprio ambiente de execução … variável de ambiente
apenas nomes de teclas … verifica se é bem conhecido endpoints de metadados na nuvem estão localizadas acessível… Ele relata apenas códigos de status, comprimentos de resposta e hashes — nunca Nenhuma credencial, valor de token ou dados de terceiros. Não realiza nenhuma operação. persistência, ausência de movimento lateral e nenhuma ação destrutiva.
Três afirmações nesse texto são contraditas pelo código fornecido. O arquivo README diz "sem persistência", mas o beacon do Windows grava uma chave de elevação baseada no registro. Diz "nunca nenhuma credencial, valor de token", mas o caminho do Windows executa comandos buscados arbitrários como SISTEMA, que não impõe tal limite ao que é lido ou retornado. Ele até nomeia um pacote — @ncurran/sandbox-recon-880538 — não é esse o arquivo README que acompanha o pacote, indicando que ele é um modelo reutilizado em vez de uma descrição do artefato em questão. Um aviso de consentimento em um pacote que a vítima nunca concordou em instalar não concede consentimento algum. A classificação aqui é maliciosa, independentemente da redação. O aviso também tem um alvo mais discreto: uma etapa de triagem automatizada que lê o texto do pacote em busca de sinais tranquilizadores — “benigno”, “autorizado”, um programa nomeado, um e-mail de contato — pode ser influenciada a emitir um veredicto seguro por um texto que contradiz o conteúdo do pacote. A lição vale tanto para revisores humanos quanto para revisores automatizados: avalie o comportamento durante a instalação, não a autodescrição do README.
Timeline
Todos os pacotes apareceram dentro de um período de 24 horas. Os quatro pacotes de versão única foram os primeiros a serem disponibilizados, seguidos por dois pacotes que foram republicados a cada 30 a 60 minutos.
| Data (UTC) | Evento |
|---|---|
| 2026-06-15 18:32 | Primeiro pacote publicado — npm:pkg-telemetry-r4f9@1.0.0 |
| 2026-06-15 19:50 | npm:runtime-metrics-w7k2@1.0.0 publicado |
| 2026-06-15 20:14 | npm:build-tracker-n5p1@1.0.0 publicado |
| 2026-06-15 20:35 | npm:npm-sandbox-ping-r9t2@1.0.0 publicado |
| 2026-06-15 21:09–22:42 | npm:event-metrics-q3x7 publicado 1.0.0 → 1.0.8 (9 versões) |
| 2026-06-15 23:40 → 2026-06-16 04:40 | npm:metrics-pipeline-d8k2 publicado 1.0.0 → 1.0.10 (11 versões) |
| 2026-06-16 | Cluster identificado e classificado como malicioso; vários arquivos tar já retornam erro 404 no registro (em andamento). |
A campanha é recente e a remoção ainda está em andamento: no momento da análise, algumas versões foram corrigidas no registro e outras não. Considere todas as 26 versões como comprometidas.
Indicadores de compromisso
PACOTES
| Ecossistema | Pacote | versões | Status |
|---|---|---|---|
| npm | metrics-pipeline-d8k2 | 1.0.0 – 1.0.10 | malicioso |
| npm | event-metrics-q3x7 | 1.0.0 – 1.0.8 | malicioso |
| npm | runtime-metrics-w7k2 | 1.0.0 | malicioso |
| npm | build-tracker-n5p1 | 1.0.0 | malicioso |
| npm | npm-sandbox-ping-r9t2 | 1.0.0 | malicioso |
| npm | pkg-telemetry-r4f9 | 1.0.0 | malicioso |
Network
| Formato | Indicador | Notas |
|---|---|---|
| IP | 173.255.233[.]239 | Coletor C2; POST de reconhecimento Linux e fallback para Windows: 443 |
| Domínio | diameter-coins-limitations-parents.trycloudflare[.]com | Canal de comando do Windows sobre um túnel Cloudflare, :443 |
| Caminho URI | /c2/poll, /c2/out, /c2/eof | Comando do Windows poll / output / close |
| IP | 169.254.170[.]2 | O endpoint de metadados da instância do AWS ECS foi sondado a partir do gancho de instalação. |
Comportamentais
| Signal | Descrição |
|---|---|
| Instale hooks | preinstall e postinstall ambos correm node run.js |
| Despacho da plataforma | run.js é executado beacon_linux.js no Linux, beacon34.js / beacon18.js no Windows |
| Reconhecimento Linux | Enumera os nomes das chaves das variáveis de ambiente e lê /proc, Verificações docker.sock, corre hostname / whoami, sondas IMDS |
| Elevação das janelas | ms-settings DelegateExecute Desvio do UAC do registro; PowerShell -ExecutionPolicy Bypass + Invoke-Expression; executa como SYSTEM |
| Disfarçar | O arquivo README afirma que a pesquisa é "benigna", "autorizada" e "sem persistência"; faz referência a um nome de pacote que não é distribuído. |
Atribuição e comportamento observado
Descrevemos a editora apenas pelos seus sinais e não afirmamos a identidade de nenhuma pessoa por trás da conta.
- Catálogo de sinais. Todos os seis pacotes foram publicados pela mesma conta npm. npmresearch8847, com o e-mail indicado npmresearch8847@web-library.net (e-mail e SCM (A verificação está ausente; não verificamos a propriedade). Os arquivos README são publicados sob um @ncurran escopo e forneça um contato de nicholas@curran.tech e executar.js aponta para o repositório github.com/ncurran/npm-sandbox-research`. Os seis pacotes compartilham um mesmo executar.js despachante, um comum beacon_linux.js estágio de reconhecimento e o único hospedeiro coletor 173.255.233[.]239`. O esquema de nomenclatura é consistente: um radical genérico com sonoridade CI (métrica, telemetria, rastreador de compilação, ping de sandbox) mais um pequeno sufixo aleatório.
- Confiança. Os seis pacotes parecem fazer parte de uma única campanha, considerando o despachante, a fase de reconhecimento e o servidor de comando e controle (C2) compartilhados. A descrição de "pesquisa autorizada" parece consistente em todos os seis arquivos README. Não conseguimos confirmar se algum programa de recompensas por bugs autorizou essa atividade, e as afirmações da declaração de isenção de responsabilidade não correspondem ao código distribuído.
- Capacidade observada. O exercício de carga útilcises quatro classes de capacidade: execução de código install-hook em ambos pré-instalação e pós-instalação; reconhecimento do host e do ambiente de CI com saída para um coletor externo; sondagem de acessibilidade de metadados de instâncias na nuvem a partir do contexto de instalação; e, no Windows, escalonamento de privilégios local, execução como SISTEMAe um loop de comandos de busca e execução por meio de um canal externo. O loop de comandos do Windows é uma funcionalidade de controle remoto: ele consulta a documentação em busca de instruções e retorna o resultado.
Impacto, tendências e o que os defensores devem fazer
Impacto
A exposição é maior em ambientes de compilação automatizados. Um `npm install` em CI executa o ciclo de vida. hooks com qualquer identidade que o executor possua; em um executor na nuvem, essa identidade geralmente inclui um endpoint de metadados acessível e uma credencial de função. O endereço que o beacon do Linux sonda, 169.254.170[.]2, é o endpoint de metadados de tarefas do AWS ECS: uma tarefa que consegue acessá-lo geralmente também consegue recuperar as credenciais temporárias de sua função de tarefa do mesmo serviço local. Uma verificação de acessibilidade dentro de um script de instalação é a etapa que precede a obtenção dessas credenciais; portanto, qualquer executor que tenha executado o gancho e conseguido acessar esse endpoint deve ser considerado como tendo tido sua função de tarefa exposta. Em um host de desenvolvimento ou compilação Windows, a carga útil solicita elevação de privilégios e abre um canal de comando, o que amplia a exposição de um único perfil e saída para controle remoto interativo.
Não conseguimos obter dados confiáveis sobre o número de downloads das versões maliciosas antes da sua remoção, portanto não estimamos o número de vítimas. A rápida republicação de dois dos pacotes — onze e nove versões em poucas horas — manteve artefatos recentes disponíveis para instaladores e servidores de busca enquanto as versões mais antigas eram removidas.
Padrões emergentes
Este cluster é um exemplo de como um rótulo pode ser usado como disfarce. “Pesquisa autorizada”, “recompensa por bugs” e “teste em sandbox” são termos cada vez mais associados a pacotes cujos scripts de instalação fazem mais do que simplesmente analisar o perfil de um host. Essa abordagem se aproveita da hesitação do revisor em agir contra algo que se anuncia como autorizado. Ela se combina com uma segunda tática comum: nomes de pacotes projetados para se parecerem com ferramentas internas de CI, de modo a passarem despercebidos em uma rápida olhada na árvore de dependências. A combinação é o que torna o padrão digno de atenção — um nome que soa como infraestrutura, envolto em uma prosa que soa como um teste autorizado, servindo de fachada para um gancho de instalação que escala privilégios em um sistema operacional e verifica credenciais de nuvem em outro. Nem o aviso legal nem o nome genérico alteram o que o código faz durante a instalação, e um processo de triagem que considere qualquer um deles como evidência atenuante chegará a uma conclusão errada.
O que os defensores devem fazer
- Pesquise nos arquivos de bloqueio e nos registros de instalação os seis nomes de pacotes; trate qualquer correspondência como um incidente, não como um aviso.
- Bloquear e alertar sobre o tráfego de saída para 173.255.233[.]239 e para *.trycloudflare[.]com hosts da infraestrutura de construção.
- Procure por solicitações HTTP de tempo de instalação para endereços de metadados de instância (169.254.170.2, 169.254.169.254) originários de gerenciadores de pacotes em CI.
- Alterne as credenciais e os tokens de função na nuvem que estavam acessíveis a partir de um executor que instalou uma versão afetada.
- Auditoria pré-instalação/pós-instalação scripts em seu conjunto de dependênciasUm gancho de ciclo de vida que executa um segundo arquivo de script merece ser lido.
- Em endpoints Windows, procure por novos DelegateExecute valores escritos abaixo do configurações de ms Chave shell-handler — o mecanismo de elevação de privilégios usado por esta carga útil e um sinal confiável independente do nome do pacote.
- Fixar e revisar arquivos de bloqueio e desativar scripts de instalação (npm install --ignore-scripts) em CI onde sua compilação não os exige.
- Considere avisos como "pesquisa autorizada" ou "inofensivos" dentro de um script de instalação como texto não confiável, e não como motivo para permitir a execução do script.
Um pacote que anuncia boas intenções em prosa e faz pedidos. SISTEMA O código deve ser julgado pelo próprio código.




