Há alguns dias, abordámos o caso do GlassWorm, que comprometeu centenas de repositórios do GitHub e um popular pacote React para números de telefone no npm. Continuámos a investigar a carga útil completa e descobrimos uma estrutura em várias fases que instala um RAT persistente e, na fase 3, instala à força uma extensão do Chrome que se faz passar pelo Google Docs Offline. Esta regista as teclas digitadas, extrai cookies e tokens de sessão, captura capturas de ecrã e recebe comandos de um servidor C2 escondido num memo da blockchain Solana.

Fase 1: A infeção inicial
Projetos sequestrados
O GlassWorm ganha a sua primeira presença através de pacotes maliciosos publicados no npm, no PyPI, no GitHub e no mercado OpenVSX. O autor da ameaça atua em duas frentes simultaneamente: (1) criando novos pacotes maliciosos a partir do zero e (2) comprometendo as contas dos mantenedores para publicar versões maliciosas de projetos legítimos.
Dois tipos de carregadores
A GlassWorm é talvez mais conhecida pelo seu carregador Unicode invisível já abordámos em publicações anteriores, mas não é o único mecanismo de entrega em uso. Uma segunda variante, mais direta, utiliza um código ofuscado convencional preinstall roteiro, tal como visto no recente Vulnerabilidade no react-native-country-select no npm. Ambos acabam por alcançar o mesmo resultado e partilham o mesmo farol C2 baseado em blockchain, mas seguem caminhos muito diferentes para lá chegar.
Independentemente do carregador que chegue ao computador da vítima, a lógica de execução da Fase 1 é a mesma. Após um atraso de 10 segundos na inicialização, o carregador realiza duas verificações antes de prosseguir.
Geofencing. O carregador verifica cinco sinais de localização (os.userInfo().username, process.env.LANG, process.env.LANGUAGE, process.env.LC_ALL, e a configuração regional «Intl» resolvida) em comparação com /ru_RU|ru-RU|Russo|russian/i, e verifica o fuso horário do sistema e o desvio em relação ao UTC, comparando-os com uma lista pré-definida de fusos horários russos que vão desde Europe/Moscow até Asia/Anadyr. Se for detetada uma configuração regional russa, a execução é interrompida.
Rate limiting. O carregador lê ~/init.json (ou %USERPROFILE%\init.json (no Windows) e verifica um carimbo de data/hora armazenado. Se o ficheiro tiver sido gravado há menos de duas horas, a execução é interrompida. Caso contrário, o carimbo de data/hora é atualizado.
Blockchain Solana C2
Por fim, o carregador consulta a blockchain da Solana para obter o seu endereço C2. Em vez de codificar diretamente um URL que pode ser retirado do ar, o autor da ameaça armazena-o no nota campo de uma transação Solana. O carregador chama getSignaturesForAddress contra uma carteira com endereço fixo, percorrendo nove pontos de extremidade RPC públicos até que um responda:
https://api.mainnet-beta.solana.comhttps://solana-mainnet.gateway.tatum.iohttps://go.getblock.us/86aac42ad4484f3c813079afc201451chttps://solana-rpc.publicnode.comhttps://api.blockeden.xyz/solana/KeCh6p22EX5AeRHxMSmchttps://solana.drpc.orghttps://solana.leorpc.com/?api_key=FREEhttps://solana.api.onfinality.io/publichttps://solana.api.pocket.network/
Foram identificados dois endereços de carteira nas duas variantes do loader:
BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC(Carregador Unicode)6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ(Carregador de pré-instalação ofuscado)
O carregador realiza consultas num ciclo de 10 segundos até encontrar uma transação com o campo «memo» preenchido. A funcionalidade «memo» da Solana foi concebida para adicionar anotações às transações, mas, neste caso, funciona como um ponto de entrega secreto. Os memos são permanentes, visíveis publicamente na cadeia e armazenados numa infraestrutura que não pode ser desativada por nenhuma entidade isolada. O operador pode atualizar o URL da Fase 2 a qualquer momento, enviando uma nova transação Solana com um novo memo. Não é necessário modificar nenhum pacote, não é necessário reimplantar nenhuma infraestrutura e não há nada que os defensores possam bloquear na camada de rede.
A nota encontrada na carteira 6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ é:
{"link":"aHR0cDovLzQ1LjMyLjE1MC4yNTEvM2U0VGc4ViUyRjhhQ21PSktpcEFTQURnJTNEJTNE"}O link O valor é um URL codificado em Base64. Decodificado:
http://45.32.150.251/3e4Tg8V%2F8aCmOJKipASADg%3D%3DO carregador acede a este URL com um os cabeçalho definido para a plataforma atual (Darwin, Linux, ou win32), permitindo que o C2 em 45.32.150[.]251 para servir cargas úteis específicas para cada plataforma. O corpo da resposta é a carga útil da Fase 2 encriptada, que é posteriormente desencriptada e executada. À data da redação deste artigo, o C2 ainda estava ativo e a devolver uma carga útil para win32.
Fase 2: Exfiltração secreta
A carga útil da Fase 2 consiste numa estrutura completa para roubo de dados, que inclui a recolha de credenciais, a exfiltração de carteiras de criptomoedas, a análise do perfil do host e a sua própria lógica de dropper para a Fase 3, que é a fase final e persistente. Tudo o que é recolhido é armazenado em %TEMP%\hJxPxpHP\, compactado e enviado através de uma solicitação POST para http://217.69.3[.]152/wall.
Roubo de carteiras de criptomoedas
A carga útil realiza uma pesquisa recursiva %APPDATA% e %LOCALAPPDATA% para perfis de extensões de navegador e dados de aplicações de carteiras autónomas. Tem como alvo 71 IDs de carteiras de extensões de navegador, abrangendo praticamente todas as principais carteiras em uso: MetaMask, Phantom, Coinbase, Exodus, Binance, Ronin, Keplr, etc. Também recolhe .txt ficheiros das pastas «Documentos» e «Ambiente de Trabalho» da vítima, e copia imagens cujos nomes correspondam a palavras-chave associadas a frases-semente ou ativos criptográficos.
Roubo de credenciais de programadores
A Fase 2 tem como alvo os repositórios de credenciais que um programador de software provavelmente tem no seu computador. A carga útil diz ~/.npmrc e process.env.NPM_TOKEN. Qualquer token encontrado é validado em tempo real em relação a https://registry.npmjs.org/-/whoami antes da exfiltração. Também extrai tokens através do credenciais do Git a partir do comando e do armazenamento interno do VS Code.
Secrets deSecrets Cloud
A Fase 2 também copia ficheiros de credenciais para a AWS, GCP, Azure, Docker, Kubernetes, chaves SSH e Heroku .netrc, da DigitalOcean doctl, e o Terraform.
Perfil do anfitrião
Por fim, gera um system_info.txt com um perfil detalhado do hardware, variáveis de ambiente, aplicações instaladas, processos em execução, estrutura do disco e detalhes do sistema operativo.
Preparação para a Fase 3
Após a exfiltração, a Fase 3 é preparada através do download de dois componentes:
- 3a) Ficheiro binário de phishing para carteiras físicas de criptomoedas (Ledger e Trezor).
- 3b) Um RAT imortal baseado em WebSocket, guardado como
%APPDATA%\QtCvyfVWKH\index.js, que inclui vários ficheiros binários:c_x64.node/f_ex86.node— programas que roubam credenciais do navegadordados— Contornar a encriptação ligada às aplicações do Chromeindex_ia32.node/index_x64.node— Módulos HVNCw.node(Windows) /m(macOS) — Instala uma extensão maliciosa no navegador
A carga útil do RAT não está simplesmente codificada com um URL. Em vez disso, ela acede à página pública do Google Calendar em https://calendar.app.google/2NkrcKKj4T6Dn4uK6 e extrai o título do convite. Esse valor é descodificado em Base64 e anexado como um slug de URL a http://45.32.150[.]251. Utilização do Google Calendar como camada de redirecionamento para a entrega de dados é uma tendência que temos vindo a acompanhar desde março de 2025, e continua a aparecer de forma consistente nas ferramentas deste agente malicioso.

Fase 3a: Phishing de carteiras de hardware
Em máquinas em que %APPDATA%\Ledger Live se existir, a Etapa 3 obtém um ficheiro binário .NET WPF a partir de http://45.32.150[.]251/led-win32, deixa-o em %TEMP%\SKuyzYcDD.exe, e acrescenta HKCU\Software\Microsoft\Windows\CurrentVersion\Run\UpdateLedger para persistência. O nome interno do ficheiro é Assaac.exe, atribuído a uma empresa que se autodenomina «LLC LogicSub» (SHA-256: 06fab21dc276e3ab9b5d0a1532398979fd377b080c86d74f2c53a04603a43b1d). O ficheiro binário não é um RAT. A sua única função é roubar carteiras de criptomoedas, fazendo-se passar pelo Ledger Live e pelo Trezor.

Ao iniciar, consulta https://ipapi.co/xml e verifica se o país indicado corresponde a algum dos nove países excluídos da região da CEI: Rússia, Cazaquistão, Quirguistão, Azerbaijão, Tajiquistão, Uzbequistão, Bielorrússia, Moldávia e Arménia. Se a vítima se encontrar em qualquer um desses países, a execução é interrompida. Isto reflete a lógica de geofencing da Fase 1.
O binário regista uma subscrição de eventos WMI para detetar ligações de dispositivos USB:
SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity'Quando um dispositivo Ledger ou Trezor é ligado, abre-se a janela de phishing correspondente. A interface do Ledger apresenta um falso erro de configuração e exibe 24 campos de introdução numerados para a frase de recuperação. A interface do Trezor apresenta uma mensagem falsa a indicar «Falha na validação do firmware, a iniciar reinicialização de emergência», com o mesmo layout de introdução de 24 palavras. Ambas as janelas incluem um botão «RESTORE WALLET».
Um ciclo em segundo plano, executado a intervalos de um segundo, chama Process.GetProcessesByName para encerrar quaisquer processos reais do Ledger Live e voltar a exibir a janela de phishing caso a vítima a feche. O Fechamento da janela O manipulador intercepta as tentativas de fechar a janela com uma caixa de diálogo a avisar que o encerramento pode resultar na perda de ativos criptográficos.
Quando é introduzida uma frase válida, as 24 palavras são transmitidas através de System.Net.Http.HttpClient para 45.150.34[.]158.
Fase 3b: RAT baseado em WebSocket
O RAT é guardado como %APPDATA%\QtCvyfVWKH\index.js e inclui dois mecanismos de persistência para sobreviver a reinicializações. Uma tarefa agendada chamada Atualizar a aplicação é executado no arranque com os privilégios mais elevados, e um HKCU\Software\Microsoft\Windows\CurrentVersion\Run A tecla executa um programa de lançamento do PowerShell em %LOCALAPPDATA%\QtCvyfVWKH\AghzgY.ps1.
A imortalidade está incorporada. O script é acionado SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGUSR2, exceção não capturada, e Rejeição não tratada. Ao receber qualquer um desses sinais, o sistema programa o novo download e o reinício da carga útil. Se o processo for encerrado, ele simplesmente se reinicia mais tarde.
C2 à base de DHT
O RAT não codifica de forma fixa o seu endereço C2 principal. Ele realiza uma pesquisa DHT para encontrar a chave pública fixada 3c90fa0e84dd76c94b1468f38ed640945d72bc12, inicialização através de dht.libtorrent.org, router.bittorrent.com, e router.utorrent.com.
O operador armazena a configuração em tempo real no valor DHT associado a essa chave. Se o comando `dht.get` falhar completamente, o script tenta novamente após cinco minutos. Se não devolver nenhum valor, o script recorre ao «dead-drop» de memos da Solana: ele consulta getSignaturesForAddress para a carteira BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC, descodifica o IP do campo do link do memo e volta a executar a pesquisa. O memo Solana pode ser atualizado com um novo IP a qualquer momento para reiniciar a acessibilidade da DHT sem alterar o carregador.
A configuração recuperada da infraestrutura do atacante:
217.69.0[.]159:10000- Nó de inicialização do DHT45.32.150[.]251- C2 baseado em WebSocket217.69.3[.]152:80- Servidor de exfiltração
Os comandos C2
Assim que a configuração do DHT estiver resolvida, o script abre uma ligação Socket.IO para 45.32.150[.]251:4787 e processa cinco categorias de comando C2:
- start_hvnc / stop_hvnc: Implementa o módulo nativo HVNC para acesso remoto oculto ao ambiente de trabalho.
- meias_de_início / meias_anti-escorregamento: Obtém um módulo WebRTC a partir de
http://45.32.150[.]251/module/wrtc, instala-o em%APPDATA%\_node_x64\webrtc\wrtc-win32-x64\index.js, e executa-o como um proxy SOCKS, transformando o computador da vítima num nó proxy, que serve de infraestrutura para que o autor da ameaça realize outros ataques a partir do endereço IP da vítima. - reget_log: Executa todo o processo de roubo e exfiltração de credenciais do navegador.
- get_system_info: Envia informações sobre o sistema operativo, CPU, memória, nome do anfitrião, tempo de atividade, nome de utilizador e diretório pessoal.
- Comando: Executa código JavaScript arbitrário fornecido pelo atacante através da função eval(), concedendo ao operador capacidade total de execução remota de código.
Roubo de credenciais do navegador
O script destina-se ao Chrome, Edge, Brave, Opera, Opera GX, Vivaldi e Firefox. Ele enumera os diretórios de perfis, verifica os cookies para identificar perfis ativos e, em seguida, chama c_x64.node para extrair credenciais diretamente das bases de dados SQLite do navegador (dados de início de sessão, cookies, dados da Web). O Chrome v127+ encripta a sua chave mestra utilizando a «App-Bound Encryption», o que normalmente impede que um processo externo ao Chrome a leia. O ficheiro binário de dados tenta contornar esta funcionalidade de segurança. Os resultados são armazenados como ficheiros JSON na pasta %TEMP%\EUXFUxzOVe\, incluindo cookies, dados de início de sessão guardados, entradas de preenchimento automático, histórico de navegação, favoritos e cartões de pagamento. O diretório é compactado, encriptado e enviado via POST para 217.69.3[.]152:80/registo.
Extensão maliciosa do Chrome do tipo RAT
O script também instala à força uma extensão que se faz passar por Google Docs offline (versão 1.95.1). Obtém o seu C2 a partir de um memo Solana separado, consultando getSignaturesForAddress para a carteira DSRUBTziADDHSik7WQvSMjvwCHFsbsThrbbjWMoJPUiW. O memorando dessa carteira contém os campos c2server e checkIp, que apontam para o servidor da API da extensão e para o auxiliar de geo-IP. Após analisar o memorando, a extensão regista-se como agente através de POST /api/register, armazena o agent_id devolvido em chrome.storage.local e começa a fazer a sondagem GET /api/commands?agent_id=<id> em intervalos aleatórios de 5 a 30 segundos.

O operador pode emitir os seguintes comandos:
- domsnapshot: extrai o conteúdo completo
document.documentElement.outerHTMLda guia ativa - getcookies: recolhe cookies, opcionalmente filtrados por domínio
- dump da memória local: descarrega tudo
localStoragepares chave/valor - take_screenshot: captura uma imagem da página com a tabulação codificada em base64
- capturar_área_de_trabalho: lê a área de transferência através de
navigator.clipboard.readText() - histórico: extrai até 5.000 entradas do histórico do navegador (janela padrão: 7 dias)
- marcadores: exporta a árvore completa de marcadores
- enumeração: identifica o navegador, o hardware, os detalhes do WebGL/GPU e verifica as extensões instaladas através de
chrome-extension://<id>/manifest.json - iniciar keylogger / parar keylogger / obter dados do keylogger: intercepta os eventos keydown, keyup, keypress, input, change, focus e blur em todas as páginas; captura os valores digitados, os metadados do formulário e o contexto do elemento de destino; atualiza o
POST /api/exfila cada cinco segundos
Todos os dados recolhidos são enviados para POST /api/exfil como { agent_id, ação, carga }.
A extensão também realiza uma vigilância específica das sessões. Ela obtém as regras dos sites monitorizados a partir de /api/obter-url-para-visualização e é fornecido com a Bybit (.bybit.com) pré-configurada como destino, à espera dos cookies «secure-token» e «deviceid». Quando os deteta, aciona um webhook «auth-detected» para /api/webhook/autenticação-detetada que contém os dados dos cookies e os metadados da página. O C2 também pode fornecer regras de redirecionamento que forçam as abas ativas a aceder a URLs controladas pelo atacante.
Detecção e Proteção
As ameaças invisíveis exigem defesas ativas. Não se pode confiar na revisão visual do código ou na verificação automática padrão para detetar o que não se consegue ver. Na Aikido, integramos a deteção do Glassworm e de outros agentes maliciosos diretamente no nosso fluxo de análise de malware.
Se você já usa Aikido, esses pacotes seriam sinalizados em seu feed como uma descoberta crítica 100/100.

Ainda não usa Aikido? Crie uma conta gratuita e conecte seus repositórios. O plano gratuito inclui nossa cobertura de detecção de malware (não é necessário cartão de crédito).
Por fim, uma ferramenta capaz de bloquear malware de cadeia de abastecimento em tempo real, à medida que este surge, pode evitar uma infeção grave. Esta é a ideia subjacente Aikido Chain, uma ferramenta gratuita e de código aberto que integra o npm, o npx, o yarn, o pnpm e o pnpx e recorre tanto à IA como a investigadores humanos especializados em malware para detetar e bloquear os mais recentes riscos de cadeia de abastecimento antes que estes entrem no seu ambiente.
Indicadores de Comprometimento
Rede — Endereços IP
45.32.150[.]251— Entrega da carga útil na Fase 2, RAT WebSocket na Fase 3 (:4787)217.69.3[.]152— Servidor de exfiltração: Fase 2 (/wall), Fase 3 (/log)217.69.0[.]159— Nó de inicialização do DHT (:10000)45.150.34[.]158— Fuga da frase-semente do Ledger/Trezor
Rede — URLs C2
http://45.32.150[.]251/3e4Tg8V%2F8aCmOJKipASADg%3D%3D— Carga útil encriptada da Fase 2http://45.32.150[.]251/led-win32— Download do ficheiro binário de phishing do Ledger/Trezorhttp://45.32.150[.]251/get_arhive_npm/nt70c2J3PG%2BfPBSFHJKoWQ%3D%3D— Arquivo de módulos nativoshttp://45.32.150[.]251/get_encrypt_file_exe/E/E%2BT9tEjmURMwNnCCY2CA%3D%3D— Carga útil operacional do HVNChttp://45.32.150[.]251/module/wrtc— Módulo WebRTC do proxy SOCKShttp://45.32.150[.]251:4787— Canal RAT WebSocket (Socket.IO)http://217.69.3[.]152/wall— Terminal de exfiltração da Fase 2http://217.69.3[.]152:80/log— Ponto final de exfiltração de credenciais do navegador (Fase 3)https://calendar.app[.]google/2NkrcKKj4T6Dn4uK6— Indireção de URL da Fase 3 através do convite do Google Calendar
Carteiras Solana
BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC— Carregador Unicode de Fase 1 com dead-drop C2; Recurso alternativo DHT de Fase 36YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ— Carregador de pré-instalação ofuscado da Fase 1 com ponto de entrega C2DSRUBTziADDHSik7WQvSMjvwCHFsbsThrbbjWMoJPUiW— Extensão do navegador C2 dead-drop
Hashes de ficheiros (SHA-256)
06fab21dc276e3ab9b5d0a1532398979fd377b080c86d74f2c53a04603a43b1d— Assaac.exe / SKuyzYcDD.exe (ficheiro binário de phishing para Ledger/Trezor)f171c383e21243ac85b5ee69821d16f10e8d718089a5c090c41efeaa42e81fca— c_x64.node (programa para roubar credenciais do navegador, Windows x64)9df62cefd87784c7ee1ca8b4e6fc49737a90492fa6c23901e3b7981b18c6c988— f_ex86.node (programa que rouba credenciais do navegador, Windows x86)43253a888417dfab034f781527e08fb58e929096cb4ef69456c3e13550cb4e9e— dados (contornar a encriptação ligada à aplicação do Chrome)4a60afa085fe5a847aef164578537bc33b9b58954143381e0c65c6354e4501e3— index_ia32.node (módulo HVNC, Windows x86)de81eacd045a88598f16680ce01bf99837b1d8170c7fc38a18747ef10e930776— index_x64.node (módulo HVNC, Windows x64)fdba5be3da2467e642bd8710f971e6b266b30ac15f5f413982fd719d7e0bffd9— w.node (instalador forçado da extensão do Chrome, Windows x64)ee3e4dd5c1e073b8805f4107ccc7bc7e6e3c209fe13ea04ff3f2173c8dbe74a6— m (Instalador forçado da extensão do Chrome, binário universal para macOS)
Nomes dos ficheiros
~/init.json/%USERPROFILE%\init.json— Carimbo de data/hora de limitação de taxa; contém UUID, versão e data%TEMP%\hJxPxpHP\— Diretório de preparação de credenciais da Fase 2%TEMP%\EUXFUxzOVe\— Diretório de armazenamento temporário de credenciais do navegador da Fase 3%TEMP%\SKuyzYcDD.exe— Ficheiro binário de phishing do Ledger/Trezor%APPDATA%\QtCvyfVWKH\index.js— Script principal do RAT da Fase 3%LOCALAPPDATA%\QtCvyfVWKH\AghzgY.ps1— Lançador de persistência do PowerShell da Fase 3%APPDATA%\_node_x86\node\node.exe— Runtime do Node.js v22.9.0 x86 descarregado silenciosamente%APPDATA%\_node_x64\node\node.exe— Runtime do Node.js v22.9.0 x64 descarregado silenciosamente%APPDATA%\_node_x64\webrtc\wrtc-win32-x64\index.js— Módulo proxy SOCKS%LOCALAPPDATA%\Google\Chrome\jucku\— Diretório de extensões maliciosas do Chrome (Windows)/Biblioteca/Apoio a Aplicações/Google/Chrome/myextension/— Diretório de extensões maliciosas do Chrome (macOS)
Registo
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\UpdateApp— Persistência do RAT na Fase 3HKCU\Software\Microsoft\Windows\CurrentVersion\Run\UpdateLedger→%TEMP%\SKuyzYcDD.exe— Persistência de ficheiros binários em ataques de phishing do Ledger
Tarefas agendadas
Atualizar a aplicação— CorridasAghzgY.ps1(Fase 3) no arranque, com privilégios máximos
WMI
SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity'— Gatilho de deteção de carteiras de hardware USB (ficheiro binário de phishing da Ledger)
Extensão do navegador
- Nome de exibição: Google Docs Offline (versão 1.95.1)
- Nome do diretório de extensões (Windows): jucku
- Nome do diretório da extensão (macOS): myextension
Nomes dos processos
Assaac— Nome do processo interno do ficheiro binário de phishing do Ledger/Trezor

