Aikido

GlassWorm Esconde um RAT Dentro de uma Extensão Maliciosa do Chrome

Escrito por
Ilyas Makari

Há alguns dias, abordamos o GlassWorm comprometendo centenas de repositórios do GitHub e um popular pacote React de número de telefone no npm. Continuamos investigando o payload completo e encontramos um framework multiestágio que instala um RAT persistente e, na Etapa 3, força a instalação de uma extensão do Chrome que se passa por Google Docs Offline. Ele registra teclas digitadas, descarta cookies e tokens de sessão, captura capturas de tela e recebe comandos de um servidor C2 oculto em um memo de blockchain Solana.

Etapa 1: A Infecção Inicial

Projetos Sequestrados

GlassWorm ganha seu ponto de apoio inicial através de pacotes maliciosos publicados no npm, PyPI, GitHub e no marketplace OpenVSX. O ator da ameaça opera em duas frentes simultaneamente: (1) criando novos pacotes maliciosos do zero, e (2) comprometendo as contas de mantenedores para enviar versões maliciosas de projetos legítimos.

Duas Variações de Loader

GlassWorm é talvez mais conhecido por seu loader Unicode invisível que abordamos em posts anteriores, mas não é o único mecanismo de entrega em uso. Uma segunda variante, mais direta, usa um ofuscado convencional preinstall script, como visto no recente comprometimento de react-native-country-select no npm. Ambos, em última análise, alcançam o mesmo resultado e compartilham o mesmo beacon C2 baseado em blockchain, mas seguem caminhos muito diferentes para chegar lá.

Independentemente de qual loader atinja a máquina da vítima, a lógica de execução da Etapa 1 é a mesma. Após um atraso de inicialização de 10 segundos, o loader realiza duas verificações antes de prosseguir.

Geofencing. O loader verifica cinco sinais de localidade (os.userInfo().username, process.env.LANG, process.env.LANGUAGE, process.env.LC_ALL, e a localidade resolvida do Intl) contra /ru_RU|ru-RU|Russian|russian/i, e verifica o fuso horário do sistema e o deslocamento UTC em relação a uma lista hardcoded de fusos horários russos, abrangendo da Europa/Moscou à Ásia/Anadyr. Se uma localidade russa for detectada, a execução é interrompida.

Rate limiting. O loader lê ~/init.json (ou %USERPROFILE%\init.json no Windows) e verifica um timestamp armazenado. Se o arquivo foi gravado há menos de duas horas, a execução é interrompida. Caso contrário, o timestamp é atualizado.

Solana Blockchain C2

Finalmente, o loader consulta a blockchain Solana para obter seu endereço C2. Em vez de hardcodificar uma URL que pode ser derrubada, o ator da ameaça a armazena no campo memo de uma transação Solana. O loader chama getSignaturesForAddress contra uma carteira hardcoded, alternando entre nove endpoints RPC públicos até que um responda:

  • https://api.mainnet-beta.solana.com
  • https://solana-mainnet.gateway.tatum.io
  • https://go.getblock.us/86aac42ad4484f3c813079afc201451c
  • https://solana-rpc.publicnode.com
  • https://api.blockeden.xyz/solana/KeCh6p22EX5AeRHxMSmc
  • https://solana.drpc.org
  • https://solana.leorpc.com/?api_key=FREE
  • https://solana.api.onfinality.io/public
  • https://solana.api.pocket.network/

Dois endereços de carteira foram observados nas duas variantes do loader:

  • BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC (loader Unicode)
  • 6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ (loader de pré-instalação ofuscado)

O loader faz polling em um loop de 10 segundos até encontrar uma transação com um campo memo não nulo. O recurso memo da Solana foi projetado para adicionar anotações a transações, mas aqui ele funciona como um dead-drop secreto. Os memos são permanentes, publicamente visíveis on-chain e armazenados em uma infraestrutura que não pode ser derrubada por nenhuma parte. O operador pode atualizar a URL do Estágio 2 a qualquer momento enviando uma nova transação Solana com um novo memo. Nenhum pacote precisa ser modificado, nenhuma infraestrutura precisa ser reimplantada e não há nada para os defensores bloquearem na camada de rede.

O memo observado na carteira 6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ é:

{"link":"aHR0cDovLzQ1LjMyLjE1MC4yNTEvM2U0VGc4ViUyRjhhQ21PSktpcEFTQURnJTNEJTNE"}

O link o valor é uma URL codificada em Base64. Decodificado:

http://45.32.150.251/3e4Tg8V%2F8aCmOJKipASADg%3D%3D

O loader busca esta URL com um os cabeçalho definido para a plataforma atual (darwin, linux, ou win32), permitindo que o C2 em 45.32.150[.]251 sirva payloads específicos da plataforma. O corpo da resposta é o payload criptografado do Estágio 2, que é subsequentemente descriptografado e executado. No momento da escrita, o C2 ainda estava ativo e retornando um payload para win32.

Estágio 2: Exfiltração de Segredos

O payload do Estágio 2 é um framework completo de roubo de dados com coleta de credenciais, exfiltração de carteiras de criptomoedas, perfilamento de host e sua própria lógica de dropper para o Estágio 3 final e persistente. Tudo o que é coletado é preparado em %TEMP%\hJxPxpHP\, compactado e enviado via uma requisição POST para http://217.69.3[.]152/wall.

Roubo de Carteira de Criptomoedas

O payload busca recursivamente em %APPDATA% e %LOCALAPPDATA% por perfis de extensões de navegador e dados de aplicativos de carteira autônomos. Ele visa 71 IDs de carteiras de extensões de navegador, cobrindo praticamente todas as principais carteiras em uso: MetaMask, Phantom, Coinbase, Exodus, Binance, Ronin, Keplr, etc. Ele também coleta .txt arquivos das pastas Documentos e Desktop da vítima, e copia imagens cujos nomes de arquivo correspondem a palavras-chave associadas a frases sementes ou ativos de criptomoedas.

Roubo de Credenciais de Desenvolvedor

O Estágio 2 visa os repositórios de credenciais que um desenvolvedor de software provavelmente terá em sua máquina. O payload lê ~/.npmrc e process.env.NPM_TOKEN. Qualquer token encontrado é validado em tempo real contra https://registry.npmjs.org/-/whoami antes da exfiltração. Ele também extrai tokens via o credencial git comando e do armazenamento interno do VS Code.

Exfiltração de Cloud Secrets

O Estágio 2 também copia arquivos de credenciais para AWS, GCP, Azure, Docker, Kubernetes, chaves SSH, o da Heroku .netrc, o da DigitalOcean doctl, e Terraform.

Perfilamento do Host

Finalmente, ele gera um system_info.txt com um perfil detalhado de hardware, variáveis de ambiente, aplicativos instalados, processos em execução, layout do disco e detalhes do sistema operacional.

Preparando para o Estágio 3

Após a exfiltração, o Estágio 3 é preparado pelo download de dois componentes:

  • 3a) Binário de phishing para carteiras de criptomoedas físicas (Ledger e Trezor).
  • 3b) Um RAT imortal baseado em Websocket, salvo como %APPDATA%\QtCvyfVWKH\index.js, que vem com vários binários:
    • c_x64.node / f_ex86.node — roubadores de credenciais de navegador
    • data — bypass de criptografia vinculada a aplicativo do Chrome
    • index_ia32.node / index_x64.node — Módulos HVNC
    • w.node (Windows) / m (macOS) — Instala uma extensão de navegador maliciosa

O payload do RAT não é simplesmente hardcoded com uma URL. Em vez disso, ele busca a página pública do Google Calendar em https://calendar.app.google/2NkrcKKj4T6Dn4uK6 e extrai o título do convite. Esse valor é decodificado em Base64 e anexado como um slug de URL a http://45.32.150[.]251. Usar o Google Calendar como uma camada de indireção para entrega de payload é um padrão que temos rastreado desde março de 2025, e continua a aparecer consistentemente nas ferramentas deste ator de ameaça.

Estágio 3a: Phishing de Carteira de Hardware

Em máquinas onde %APPDATA%\Ledger Live existe, o Estágio 3 busca um binário .NET WPF de http://45.32.150[.]251/led-win32, o deposita em %TEMP%\SKuyzYcDD.exe, e adiciona HKCU\Software\Microsoft\Windows\CurrentVersion\Run\UpdateLedger para persistência. O nome interno do arquivo é Assaac.exe, atribuído a uma empresa que se autodenomina "LLC LogicSub" (SHA-256: 06fab21dc276e3ab9b5d0a1532398979fd377b080c86d74f2c53a04603a43b1d). O binário não é um RAT. Sua única função é roubar carteiras de criptomoedas ao se passar por Ledger Live e Trezor.

Captura de tela da execução do CAPE Sandbox

Ao iniciar, ele consulta https://ipapi.co/xml e verifica o país retornado em relação a nove exclusões 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 estiver em qualquer um desses países, a execução é interrompida. Isso reflete a lógica de geofencing da Etapa 1.

O binário registra uma assinatura de evento WMI para detectar conexões de dispositivos USB:

SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity'

Quando um dispositivo Ledger ou Trezor é conectado, a janela de phishing correspondente é aberta. A interface do Ledger exibe um erro de configuração falso e apresenta 24 campos numerados para inserção da frase de recuperação. A interface do Trezor exibe uma mensagem falsa de "Firmware validation failed, initiating emergency reboot" com o mesmo layout de entrada de 24 palavras. Ambas as janelas incluem um botão "RESTORE WALLET".

Um loop em segundo plano, executado em intervalos de um segundo, chama Process.GetProcessesByName para encerrar quaisquer processos reais do Ledger Live e reexibe a janela de phishing caso a vítima a feche. O Window_Closing handler intercepta tentativas de fechamento com um aviso em diálogo de que o fechamento pode resultar na perda de criptoativos.

Quando uma frase válida é enviada, as 24 palavras são transmitidas via System.Net.Http.HttpClient para 45.150.34[.]158.

Etapa 3b: RAT baseado em Websocket

O RAT é salvo como %APPDATA%\QtCvyfVWKH\index.js e vem com dois mecanismos de persistência para sobreviver a reinicializações. Uma tarefa agendada chamada UpdateApp é executada na inicialização com os privilégios mais altos, e uma HKCU\Software\Microsoft\Windows\CurrentVersion\Run chave executa um launcher PowerShell em %LOCALAPPDATA%\QtCvyfVWKH\AghzgY.ps1.

A imortalidade é incorporada. O script se conecta SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGUSR2, uncaughtException, e unhandledRejection. Em qualquer um desses sinais, ele agenda o re-download e a reinicialização do payload. Se o processo for encerrado, ele simplesmente se reconstrói mais tarde.

C2 Baseado em DHT

O RAT não codifica seu endereço C2 principal. Ele realiza uma consulta DHT para a chave pública fixada 3c90fa0e84dd76c94b1468f38ed640945d72bc12, inicializando via dht.libtorrent.org, router.bittorrent.com, e router.utorrent.com.

O operador armazena a configuração ativa no valor DHT daquela chave. Se dht.get falhar completamente, o script tenta novamente após cinco minutos. Se não retornar nenhum valor, o script recorre ao dead-drop de memo do Solana: ele consulta getSignaturesForAddress para a carteira BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC, decodifica o IP do campo de link do memo e executa a consulta novamente. O memo do Solana pode ser atualizado com um novo IP a qualquer momento para restabelecer a acessibilidade DHT sem tocar no carregador.

A configuração recuperada da infraestrutura do atacante:

  • 217.69.0[.]159:10000 - Nó de bootstrap DHT
  • 45.32.150[.]251 - C2 baseado em WebSocket
  • 217.69.3[.]152:80 - Servidor de exfiltração

Os Comandos C2

Uma vez que a configuração DHT é resolvida, o script abre uma conexão Socket.IO para 45.32.150[.]251:4787 e processa cinco categorias de comando C2:

  • start_hvnc / stop_hvnc: Implanta o módulo nativo HVNC para acesso remoto oculto à área de trabalho.
  • start_socks / stop_socks: Busca um módulo WebRTC de http://45.32.150[.]251/module/wrtc, o instala em %APPDATA%\_node_x64\webrtc\wrtc-win32-x64\index.js, e o executa como um proxy SOCKS, transformando a máquina da vítima em um nó proxy, servindo como infraestrutura para o ator da ameaça realizar outros ataques a partir do IP da vítima.
  • reget_log: Executa o pipeline completo de roubo e exfiltração de credenciais do navegador.
  • get_system_info: Envia informações de SO, CPU, memória, hostname, uptime, nome de usuário e diretório inicial.
  • command: Executa JavaScript arbitrário fornecido pelo atacante via eval(), concedendo ao operador execução remota de código completa.

Roubo de Credenciais do Navegador

O script tem como alvo Chrome, Edge, Brave, Opera, Opera GX, Vivaldi e Firefox. Ele enumera diretórios de perfil, verifica cookies para identificar perfis ativos e, em seguida, chama c_x64.node para extrair credenciais diretamente dos bancos de dados SQLite do navegador (Login Data, Cookies, Web Data). O Chrome v127+ criptografa sua chave mestra usando App-Bound Encryption, o que normalmente impede que um processo fora do Chrome a leia. O binário de dados tenta contornar esse recurso de segurança. Os resultados são organizados como arquivos JSON em %TEMP%\EUXFUxzOVe\, cobrindo cookies, logins salvos, entradas de preenchimento automático, histórico de navegação, favoritos e cartões de pagamento. O diretório é compactado, criptografado e enviado via POST para 217.69.3[.]152:80/log.

RAT de Extensão Maliciosa do Chrome

O script também força a instalação de uma extensão que se disfarça de Google Docs Offline (versão 1.95.1). Ele resolve seu C2 a partir de um memo Solana separado, fazendo polling em getSignaturesForAddress para a carteira DSRUBTziADDHSik7WQvSMjvwCHFsbsThrbbjWMoJPUiW. O memo dessa carteira contém os campos c2server e checkIp apontando para o servidor API da extensão e o auxiliar geo-IP. Após analisar o memo, a extensão se registra como um agente via POST /api/register, armazena o agent_id retornado em chrome.storage.local e começa a fazer polling em GET /api/commands?agent_id=<id> em um intervalo aleatório de 5 a 30 segundos.

Captura de tela da extensão maliciosa ao lado da legítima

O operador pode emitir os seguintes comandos:

  • domsnapshot: exfiltra o conteúdo completo document.documentElement.outerHTML da aba ativa
  • getcookies: coleta cookies, opcionalmente filtrados por domínio
  • localstoragedump: despeja todos os localStorage pares chave/valor
  • take_screenshot: captura uma captura de tela da aba codificada em base64
  • capture_clipboard: lê a área de transferência via navigator.clipboard.readText()
  • history: extrai até 5.000 entradas do histórico do navegador (janela padrão: 7 dias)
  • bookmarks: exporta a árvore completa de favoritos
  • enumeration: faz o fingerprint do navegador, hardware, detalhes de WebGL/GPU e sonda extensões instaladas via chrome-extension://<id>/manifest.json
  • startkeylogger / stopkeylogger / getkeyloggerdata: intercepta eventos keydown, keyup, keypress, input, change, focus e blur em todas as páginas; captura valores digitados, metadados de formulário e contexto do elemento alvo; descarrega para POST /api/exfil a cada cinco segundos

Todos os dados coletados são enviados para POST /api/exfil como { agent_id, action, payload }.

A extensão também realiza vigilância de sessão direcionada. Ela puxa regras de sites monitorados de /api/get-url-for-watch e vem com Bybit (.bybit.com) pré-configurado como alvo, monitorando os cookies secure-token e deviceid. Ao detectar, ele dispara um webhook auth-detected para /api/webhook/auth-detected contendo o material do cookie e metadados da página. O C2 também pode fornecer regras de redirecionamento que forçam abas ativas para URLs controladas pelo atacante.

Detecção e Proteção

Ameaças invisíveis exigem defesas ativas. Não é possível confiar em revisão visual de código ou linting padrão para detectar o que não se pode ver. Na Aikido, integramos a detecção de Glassworm e outros atores de ameaça diretamente em nosso pipeline de varredura 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).

Finalmente, uma ferramenta que pode parar malwares de supply-chain em tempo real, assim que aparecem, pode prevenir uma infecção séria. Esta é a ideia por trás do Aikido Safe Chain, uma ferramenta gratuita e de código aberto que envolve npm, npx, yarn, pnpm e pnpx, e usa tanto IA quanto pesquisadores humanos de malware para detectar e bloquear os mais recentes riscos de supply chain antes que entrem em seu ambiente.

Indicadores de Comprometimento

Rede — Endereços IP

  • 45.32.150[.]251 — Entrega de payload da Fase 2, RAT WebSocket da Fase 3 (:4787)
  • 217.69.3[.]152 — Servidor de exfiltração: Fase 2 (/wall), Fase 3 (/log)
  • 217.69.0[.]159 — Nó bootstrap DHT (:10000)
  • 45.150.34[.]158 — Exfiltração de seed phrase Ledger/Trezor

Rede — URLs C2

  • http://45.32.150[.]251/3e4Tg8V%2F8aCmOJKipASADg%3D%3D — Payload criptografado da Fase 2
  • http://45.32.150[.]251/led-win32 — Download de binário de phishing Ledger/Trezor
  • http://45.32.150[.]251/get_arhive_npm/nt70c2J3PG%2BfPBSFHJKoWQ%3D%3D — Arquivo de módulo nativo
  • http://45.32.150[.]251/get_encrypt_file_exe/E/E%2BT9tEjmURMwNnCCY2CA%3D%3D — Payload operacional HVNC
  • http://45.32.150[.]251/module/wrtc — Módulo WebRTC de proxy SOCKS
  • http://45.32.150[.]251:4787 — Canal RAT WebSocket (Socket.IO)
  • http://217.69.3[.]152/wall — Endpoint de exfiltração da Fase 2
  • http://217.69.3[.]152:80/log — Endpoint de exfiltração de credenciais de navegador da Fase 3
  • https://calendar.app[.]google/2NkrcKKj4T6Dn4uK6 — Indireção de URL da Fase 3 via Convite do Google Calendar

Carteiras Solana

  • BjVeAjPrSKFiingBn4vZvghsGj9KCE8AJVtbc9S8o8SC — Loader Unicode C2 dead-drop Estágio 1; fallback DHT Estágio 3
  • 6YGcuyFRJKZtcaYCCFba9fScNUvPkGXodXE1mJiSzqDJ — Loader de pré-instalação ofuscado C2 dead-drop Estágio 1
  • DSRUBTziADDHSik7WQvSMjvwCHFsbsThrbbjWMoJPUiW — Extensão de navegador C2 dead-drop

Hashes de Arquivos (SHA-256)

  • 06fab21dc276e3ab9b5d0a1532398979fd377b080c86d74f2c53a04603a43b1d — Assaac.exe / SKuyzYcDD.exe (binário de phishing Ledger/Trezor)
  • f171c383e21243ac85b5ee69821d16f10e8d718089a5c090c41efeaa42e81fca — c_x64.node (ladrão de credenciais de navegador, Windows x64)
  • 9df62cefd87784c7ee1ca8b4e6fc49737a90492fa6c23901e3b7981b18c6c988 — f_ex86.node (ladrão de credenciais de navegador, Windows x86)
  • 43253a888417dfab034f781527e08fb58e929096cb4ef69456c3e13550cb4e9e — data (bypass de criptografia vinculada a aplicativo 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 de extensão do Chrome, Windows x64)
  • ee3e4dd5c1e073b8805f4107ccc7bc7e6e3c209fe13ea04ff3f2173c8dbe74a6 — m (instalador forçado de extensão do Chrome, binário universal macOS)

Nomes de Arquivos

  • ~/init.json / %USERPROFILE%\init.json — Timestamp de limitação de taxa; contém uuid, versão, data
  • %TEMP%\hJxPxpHP\ — Diretório de staging de credenciais Estágio 2
  • %TEMP%\EUXFUxzOVe\ — Diretório de staging de credenciais de navegador Estágio 3
  • %TEMP%\SKuyzYcDD.exe — Binário de phishing Ledger/Trezor descartado
  • %APPDATA%\QtCvyfVWKH\index.js — Script principal do RAT (Stage 3)
  • %LOCALAPPDATA%\QtCvyfVWKH\AghzgY.ps1 — Inicializador de persistência PowerShell (Stage 3)
  • %APPDATA%\_node_x86\node\node.exe — Runtime Node.js v22.9.0 x86 baixado silenciosamente
  • %APPDATA%\_node_x64\node\node.exe — Runtime Node.js v22.9.0 x64 baixado silenciosamente
  • %APPDATA%\_node_x64\webrtc\wrtc-win32-x64\index.js — Módulo de proxy SOCKS
  • %LOCALAPPDATA%\Google\Chrome\jucku\ — Diretório de extensão maliciosa do Chrome (Windows)
  • /Library/Application Support/Google/Chrome/myextension/ — Diretório de extensão maliciosa do Chrome (macOS)

Registro

  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run\UpdateApp — Persistência do RAT (Stage 3)
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Run\UpdateLedger%TEMP%\SKuyzYcDD.exe — Persistência do binário de phishing Ledger

Tarefas Agendadas

  • UpdateApp — Executa AghzgY.ps1 (Stage 3) na inicialização com privilégios máximos

WMI

  • SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity' — Gatilho de detecção de carteira de hardware USB (binário de phishing Ledger)

Extensão de Navegador

  • Nome de exibição: Google Docs Offline (versão 1.95.1)
    • Nome do diretório da extensão (Windows): jucku
    • Nome do diretório da extensão (macOS): myextension

Nomes de Processos

  • Assaac — Nome do processo interno do binário de phishing Ledger/Trezor
Compartilhar:

https://www.aikido.dev/blog/glassworm-chrome-extension-rat

Comece hoje, gratuitamente.

Comece Gratuitamente
Não é necessário cc

Assine para receber notícias sobre ameaças.

4.7/5
Cansado de falsos positivos?

Experimente Aikido como 100 mil outros.
Começar Agora
Obtenha um tour personalizado

Confiado por mais de 100 mil equipes

Agende Agora
Escaneie seu aplicativo em busca de IDORs e caminhos de ataque reais

Confiado por mais de 100 mil equipes

Iniciar Escaneamento
Veja como o pentest de IA testa seu aplicativo

Confiado por mais de 100 mil equipes

Iniciar Testes
Escaneie seus repositórios em busca de ataques GlassWorm

Confiado por 100 mil equipes

Comece gratuitamente

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.