Por dentro da fraude na cadeia de suprimentos da Axios: um RAT para governar todos.

A Elastic Security Labs analisa uma vulnerabilidade na cadeia de suprimentos do pacote npm axios, que fornece um RAT (Trusted Access Technology) multiplataforma unificado.

Inside the Axios supply chain compromise - one RAT to rule them all

A Elastic Security Labs divulgou as regras iniciais de triagem e detecção para a vulnerabilidade na cadeia de suprimentos da Axios. Esta é uma análise detalhada do RAT e das cargas úteis.

Introdução

A Elastic Security Labs identificou uma vulnerabilidade na cadeia de suprimentos do pacote npm axios, um dos pacotes mais utilizados no ecossistema JavaScript, com aproximadamente 100 milhões de downloads semanais. O atacante comprometeu uma conta de mantenedor e publicou versões com backdoor que distribuíam um Trojan de Acesso Remoto multiplataforma para sistemas macOS, Windows e Linux por meio de um gancho malicioso de pós-instalação.

Principais conclusões

  • Uma conta de mantenedor do npm comprometida (jasonsaayman) foi usada para publicar duas versões maliciosas do cliente HTTP Axios, amplamente utilizado — 1.14.1 (marcada como "latest") e 0.30.4 (marcada como "legacy") — o que significa que um comando padrão `npm install axios` resultava em um pacote com backdoor.
  • O JavaScript malicioso implementa implantes de estágio 2 específicos para cada plataforma: macOS, Windows e Linux.
  • Todas as três cargas úteis de estágio 2 são implementações da mesma RAT — protocolo C2 idêntico, conjunto de comandos, cadência de beacons e user-agent falsificado, escritas em PowerShell (Windows), C++ (macOS) e Python (Linux).
  • O dropper realiza uma limpeza antiforense excluindo-se a si mesmo e substituindo seu arquivo package.json por uma cópia limpa, apagando assim os vestígios do gatilho pós-instalação. node_modules

Preâmbulo

Em 30 de março de 2026, a Elastic Security Labs detectou uma violação da cadeia de suprimentos que tinha como alvo o pacote npm axios por meio de monitoramento automatizado da cadeia de suprimentos. O atacante obteve o controle da conta npm pertencente a jasonsaayman, um dos principais mantenedores do projeto, e publicou duas versões com backdoor em um intervalo de 39 minutos.

O pacote axios é uma das bibliotecas de clientes HTTP mais utilizadas no ecossistema JavaScript. No momento da descoberta, tanto as tags de distribuição mais recentes quanto as antigas apontavam para versões comprometidas, garantindo que a maioria das novas instalações obtivesse uma versão com backdoor.

As versões maliciosas introduziram uma única nova dependência: plain-crypto-js, um pacote criado especificamente para esse fim, cujo gancho de pós-instalação baixava e executava silenciosamente implantes RAT de estágio 2 específicos da plataforma a partir de sfrclak[.]com:8000.

O que torna esta campanha notável, além do seu impacto direto, é a ferramenta de segunda fase. O atacante implantou três implementações paralelas do mesmo RAT — uma para Windows, uma para macOS e uma para Linux — todas compartilhando um protocolo C2, estrutura de comando e comportamento de beacon idênticos. Não se trata de três ferramentas diferentes; é uma única estrutura de implante multiplataforma com implementações nativas da plataforma.

A Elastic Security Labs registrou um aviso de segurança no GitHub para o repositório axios em 31 de março, 2026 às 01:50 da manhã UTC para coordenar a divulgação e garantir que os mantenedores e o registro npm pudessem agir nas versões comprometidas.

Assim que a comunidade alertou sobre a vulnerabilidade nas redes sociais, o Elastic Security Labs compartilhou publicamente as primeiras descobertas para ajudar os profissionais de segurança a responderem em tempo real.

Este artigo aborda toda a cadeia de ataque: desde a violação da cadeia de suprimentos no nível do npm, passando pelo dropper ofuscado, até a arquitetura do RAT multiplataforma e as diferenças significativas entre suas três variantes.

Visão geral da campanha

O compromisso é evidente nos metadados do registro npm. O e-mail do mantenedor mudou de jasonsaayman@gmail[.]com — presente em todas as versões legítimas anteriores — para ifstap@proton[.]me nas versões maliciosas. O método de publicação também mudou:

VersãoPublicado porMethodProveniência
axios@1.14.0 (legítimo)jasonsaayman@gmail[.]comGitHub Actions OIDCatestados de proveniência SLSA
axios@1.14.1 (comprometido)ifstap@proton[.]mePublicação direta via CLINenhuma
axios@0.30.4 (comprometido)ifstap@proton[.]mePublicação direta via CLINenhuma

A mudança de um fluxo de publicação OIDC confiável com proveniência SLSA para uma publicação CLI direta com um e-mail alterado é um claro indicador de acesso não autorizado.

Linha do tempo

  • 2026-02-18 17:19 UTCaxios@0.30.3 publicado legitimamente por jasonsaayman@gmail[.]com
  • 2026-03-27 19:01 UTCaxios@1.14.0 publicado legitimamente via GitHub Actions OIDC
  • 2026-03-30 05:57 UTCplain-crypto-js@4.2.0 publicado por nrwise (nrwise@proton.me) — isca limpa para construir o histórico do registro
  • 2026-03-30 23:59 UTCplain-crypto-js@4.2.1 publicado por nrwise — versão maliciosa com backdoor postinstall
  • 2026-03-31 00:21 UTCaxios@1.14.1 publicado por conta comprometida — marcado com latest
  • 2026-03-31 01:00 UTCaxios@0.30.4 publicado por conta comprometida — marcado com legacy

Pacotes afetados

  • axios@1.14.1 — Malicioso, etiquetado como latest no momento da descoberta
  • axios@0.30.4 — Malicioso, etiquetado como legacy no momento da descoberta
  • plain-crypto-js@4.2.0 — Isca limpa, publicada para construir o histórico do registro
  • plain-crypto-js@4.2.1 — Veículo malicioso de entrega de carga (postinstall backdoor)

Versões seguras: axios@1.14.0 (última versão legítima 1.x com procedência SLSA) e axios@0.30.3 (última versão legítima 0.30.x ).

O atacante marcou tanto os canais mais recentes quanto os legados, maximizando o alcance do ataque em projetos que utilizam a API axios atual ou a legada.

Análise de código

Etapa 1: O dropper plain-crypto-js

Toda a cadeia de distribuição depende do gancho de ciclo de vida postinstall do npm. A instalação de qualquer versão comprometida do axios puxa plain-crypto-js@^4.2.1 como dependência, que declara:

"scripts": {
  "postinstall": "node setup.js"
}

Isso faz com que o arquivo setup.js seja executado automaticamente durante a instalação do npm — sem necessidade de interação do usuário.

O arquivo setup.js utiliza um esquema de codificação de duas camadas para ocultar seu comportamento:

  • Camada 1: Inversão da string seguida de decodificação em Base64
  • Camada 2: Cifra XOR usando a chave OrDeR_7077 com um índice dependente da posição (7 * i² % 10)

Todas as strings críticas, nomes de módulos, URLs e comandos do shell são armazenados em um array codificado stq[] e decodificados em tempo de execução. O conteúdo decodificado revela a infraestrutura operacional:

Entrega específica da plataforma

Após decodificar sua tabela de strings, o dropper verifica os.platform() e ramifica para uma das três rotinas de entrega. Cada um envia uma solicitação HTTP POST para http://sfrclak[.]com:8000/6202033 com um corpo específico da plataforma — packages.npm.org/product0 (macOS), packages.npm.org/product1 (Windows), packages.npm.org/product2 (Linux) — permitindo que o C2 forneça a carga útil correta a partir de um único ponto de extremidade. O packages.npm.org/ O prefixo é uma tentativa deliberada de fazer com que o tráfego de saída pareça uma comunicação benigna do registro npm nos logs de rede:

PlataformaMétodo de entregaLocalização da Etapa 2Disfarce
macOSAppleScript via osascript baixa binário com curl/Library/Caches/com.apple.act.monddaemon do sistema Apple
WindowsDownloads de VBScript .ps1 via curl, executa via PowerShell renomeado (%PROGRAMDATA%\wt.exe)%TEMP%\6202033.ps1 (transitório)Terminal do Windows
LinuxDownload direto via curl e execução em Python 3/tmp/ld.pyNenhuma

Antiforense

O conta-gotas realiza duas ações de limpeza:

  1. Autoexclusão: setup.js se remove através de fs.unlink(__filename)
  2. Substituição do manifesto do pacote: Um arquivo limpo chamado package.md (contendo uma configuração benigna da versão 4.2.0 sem nenhum gancho pós-instalação) é renomeado para package.json. sobrescrevendo a versão maliciosa

A inspeção do arquivo node_modules/plain-crypto-js/package.json após o incidente não revelou nenhum vestígio do gatilho postinstall. O arquivo setup.js malicioso foi removido. Somente o arquivo de bloqueio e os registros de auditoria do npm retêm evidências.

Etapa 2: RAT multiplataforma

As três cargas úteis do estágio 2: PowerShell para Windows, C++ compilado para macOS e Python para Linux não são três ferramentas diferentes. São três implementações da mesma especificação RAT, compartilhando um protocolo C2 idêntico, conjunto de comandos, formato de mensagem e comportamento operacional. A consistência indica fortemente um único desenvolvedor ou uma equipe bem coordenada trabalhando a partir de um documento de projeto compartilhado.

Arquitetura compartilhada

As seguintes propriedades são idênticas em todas as três variantes:

  • Transporte C2: HTTP POST
  • Codificação do corpo: JSON codificado em Base64
  • Agente do usuário: mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)
  • Intervalo do sinalizador: 60 segundos
  • UID da sessão: sequência alfanumérica aleatória de 16 caracteres, gerada a cada execução.
  • Tipos de mensagens de saída: FirstInfo, BaseInfo, CmdResult
  • Tipos de comandos de entrada: kill, peinject, runscript, rundir
  • Tipos de comando de resposta: rsp_kill, rsp_peinject, rsp_runscript, rsp_rundir

A string de agente de usuário falsificada do IE8/Windows XP é particularmente notável, sendo anacrônica em todas as três plataformas, e sua presença em um host macOS ou Linux é um forte indicador de detecção.

Inicialização e reconhecimento

Na inicialização, cada variante:

  1. Gera um UID de sessão — 16 caracteres alfanuméricos aleatórios, incluídos em todas as mensagens C2 subsequentes.
  2. Detecta o sistema operacional e a arquitetura — reporta identificadores específicos da plataforma (ex.: windows_x64, macOS, linux_x64)
  3. Enumera os diretórios iniciais de interesse (perfil do usuário, documentos, área de trabalho, diretórios de configuração).
  4. Envia um beacon FirstInfo contendo o UID, o identificador do sistema operacional e um instantâneo do diretório.

Após a inicialização, o implante entra no loop principal. O primeiro pulso do BaseInfo inclui um perfil completo do sistema. As mesmas categorias de dados são coletadas em todas as plataformas, embora as APIs subjacentes sejam diferentes:

Dados coletadosFonte do WindowsFonte macOSFonte Linux
Hostname%COMPUTERNAME% variável de ambienteobternome_do_host()/proc/sys/kernel/nome_do_host
Nome de usuário%USERNAME% variável de ambientegetuid() + getpwuid()os.getlogin()
Versão do SOWMI / registrosysctlbyname("kern.osprodutoversão")plataforma.sistema() + plataforma.release()
Fuso horárioFuso horário do sistemalocaltime_r()data e hora. fuso horário
Tempo de inicializaçãoTempo de atividade do sistemasysctl("kern.boottime")/proc/tempo de atividade
Data de instalaçãoRegistro / WMIstat("/") ou sysctlctime de /var/log/installer ou /var/log/dpkg.log
Modelo de hardwareWMIsysctlbyname("hw.model")/sys/class/dmi/id/nome_do_produto
tipo de CPUWMIsysctlbyname()plataforma.máquina()
Process listPID completo, sessão, nome, caminhopopen("ps") (até 1000)Enumeração completa de /proc (PID, PPID, usuário, linha de comando)

Os batimentos cardíacos subsequentes são leves, contendo apenas um registro de data e hora para confirmar que o implante está ativo.

despacho de comando

A resposta do C2 é analisada como JSON, e o campo "type" determina a ação. Todas as três variantes implementam os mesmos quatro comandos:

matar — Autoextermínio. Envia um reconhecimento rsp_kill e encerra a execução. O mecanismo de persistência da variante do Windows (chave de registro + arquivo em lote) sobrevive ao comando kill, a menos que seja explicitamente removido; as variantes do macOS e do Linux não possuem mecanismo de persistência próprio.

runscript — Execução de script/comando. O comando de interação principal do operador. Aceita um campo Script (código a ser executado) e um campo Param (argumentos). Quando o Script está vazio, o Param é executado diretamente como um comando. O mecanismo de execução é nativo da plataforma:

PlataformaMecanismo de Execução
WindowsPowerShell com -NoProfile -ep Bypass
macOSAppleScript via /usr/bin/osascript
LinuxShell via subprocess.run(shell=True) ou Python via python3 -c

peinject — Entrega de carga binária. Apesar da nomenclatura centrada no Windows ("PE inject"), todas as três plataformas implementam isso como uma forma de inserir e executar payloads binários:

PlataformaImplementation
WindowsCarregamento reflexivo de assemblies .NET via [System.Reflection.Assembly]::Load()
macOSDecodifica e extrai um arquivo binário usando Base64, executando-o com parâmetros fornecidos pelo operador.
LinuxDecodifica um binário em Base64 para /tmp/. string de 6 caracteres> (arquivo oculto), executado via subprocess.Popen().

A implementação do Windows possui execução em memória sem descarte de arquivos, mas sem desabilitar o AMSI, o que certamente causará problemas no carregamento do assembly. As variantes para macOS e Linux adotam a abordagem mais simples de gravar um arquivo binário no disco e executá-lo diretamente.

rundir — Enumeração de diretórios. Aceita caminhos e retorna listagens detalhadas de arquivos (nome, tamanho, tipo, data e hora de criação/modificação, número de filhos para diretórios). Permite ao operador navegar interativamente pelo sistema de arquivos.

Resumo das capacidades

CapacidadeWindows (PowerShell)macOS (C++)Linux (Python)
PersistênciaChave de execução do Registro + arquivo .bat ocultoNenhumaNenhuma
Execução de scriptPowerShellAppleScript via osascriptShell ou Python embutido
Injeção bináriaInjeção de carga .NET reflexiva no cmd.exeBinário drop + executarArquivo binário copiado para /tmp/ + executar
AntiforenseJanelas ocultas, limpeza de arquivos temporáriosArquivo temporário oculto .scptArquivos ocultos em /tmp/.XXXXXX

Atribuição

O binário Mach-O para macOS entregue pelo gancho de pós-instalação plain-crypto-js apresenta uma sobreposição significativa com o WAVESHAPER, um backdoor em C++ rastreado pela Mandiant e atribuído ao UNC1069, um cluster de ameaças ligado à Coreia do Norte.

Conclusão

Esta campanha demonstra a atratividade contínua do ecossistema npm como vetor de ataque à cadeia de suprimentos. Ao comprometer uma única conta de mantenedor em um dos pacotes mais importantes do ecossistema JavaScript, o atacante obteve um mecanismo de distribuição com alcance potencial em milhões de ambientes.

O indicador de detecção mais confiável do conjunto de ferramentas é também sua escolha de design mais curiosa: a string do agente do usuário do IE8/Windows XP codificada de forma idêntica em todas as três variantes da plataforma. Embora forneça uma impressão digital de protocolo consistente para roteamento do lado do servidor C2, é trivialmente detectável em qualquer rede moderna — e é uma anomalia imediata em hosts macOS e Linux.

A Elastic Security Labs continuará monitorando esse cluster de atividades e atualizará esta publicação com quaisquer descobertas adicionais.

MITRE ATT&CK

A Elastic usa a estrutura MITRE ATT&CK para documentar táticas, técnicas e procedimentos comuns que ameaças persistentes avançadas usam contra redes corporativas.

Táticas

As táticas representam o porquê de uma técnica ou subtécnica. É o objetivo tático do adversário: a razão para executar uma ação.

Técnicas

Técnicas representam como um adversário atinge um objetivo tático executando uma ação.

Observações

Os seguintes observáveis foram discutidos nesta pesquisa.

ObservávelTipoNomeReferência
617b67a8e1210e4fc87c92d1d1da45a2f311c08d26e89b12307cf583c900d101SHA-2566202033.ps1Carga útil do Windows
92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645aSHA-256com.apple.act.mondcarga útil do MacOS
fcb81618bb15edfdedfb638b4c08a2af9cac9ecfa551af135a8402bf980375cfSHA-256ld.pyCarga útil Linux
sfrclak[.]comDomínioC2
142.11.206[.]73endereço-ipv4C2

Referências

Os seguintes itens foram referenciados ao longo da pesquisa acima:

Compartilhe este artigo