
A campanha ForceMemo ampliou o alcance do GlassWorm ao reescrever ramos padrão de projetos, comprometer pacotes npm e usar transações Solana como mecanismo para localizar payloads.
| Componente | Repositórios Python no GitHub, pacotes npm React Native, extensões VS Code/Open VSX/Windsurf e o malware GlassWorm na variante ForceMemo. |
| Vetor | Tokens GitHub roubados de ambientes de desenvolvimento foram usados para fazer force-push no ramo padrão, anexando código ofuscado a arquivos como setup.py, main.py e app.py. |
| Impacto | Execução de um stealer JavaScript, busca dinâmica de payload por transações Solana, roubo de dados de navegadores Chromium, persistência e possível comprometimento de usuários que instalam ou executam código afetado. |
| Prioridade | Revogar tokens de desenvolvedor, auditar histórico reescrito em repositórios, bloquear versões maliciosas em dependências e investigar endpoints que executaram projetos ou extensões afetadas. |
| Artefatos | A campanha usa código Base64 ofuscado, caracteres Unicode invisíveis, hooks preinstall, extensionPack, extensionDependencies, VSIX trojanizado e execução em memória via eval() ou vm.Script. |
| Mitigação | Revisar commits no ramo padrão desde 8 de março de 2026, validar pacotes npm publicados sem release correspondente, remover extensões suspeitas e rotacionar segredos expostos em ambientes de desenvolvimento. |
A campanha GlassWorm passou a usar uma técnica de entrega chamada ForceMemo para inserir malware em projetos de desenvolvimento por meio de tokens GitHub roubados. Em vez de depender apenas de extensões maliciosas de IDE, o operador usa credenciais de contas de desenvolvedor para reescrever o ramo padrão de repositórios e anexar código ofuscado a arquivos Python comuns. O ataque atinge projetos como aplicações Django, pesquisas de aprendizado de máquina, painéis Streamlit e pacotes PyPI, criando risco para qualquer pessoa que instale o projeto diretamente do repositório ou clone e execute o código localmente.
A primeira leva de injeções identificada começou em 8 de março de 2026. O método observado preserva mensagem, autor e data do commit legítimo original, enquanto rebasa as alterações e faz force-push com conteúdo malicioso. Esse detalhe reduz a visibilidade na interface do GitHub, pois não há pull request, revisão de código ou trilha de commit nova facilmente percebida pelo mantenedor. A mesma infraestrutura baseada em transações Solana também aparece em outras partes da campanha, incluindo pacotes npm, extensões de VS Code/Open VSX e uma extensão maliciosa voltada ao Windsurf IDE.
O payload final descrito na campanha é um stealer escrito em JavaScript. Ele busca instruções e URLs de estágio seguinte por meio de campos de transação associados a carteiras Solana, carrega componentes adicionais, evita execução em sistemas com localidade russa e tenta manter persistência conforme a plataforma. O conjunto de técnicas indica uma operação voltada a ambientes de desenvolvimento, com interesse particular em segredos, tokens, dados de navegador e credenciais que possam alimentar novas etapas de comprometimento na cadeia de software.
O fluxo ForceMemo começa com o comprometimento de sistemas de desenvolvedores por GlassWorm, incluindo extensões maliciosas usadas em IDEs como VS Code e Cursor. O malware possui componente dedicado para coletar segredos, entre eles tokens GitHub. Com esses tokens, o operador acessa as contas afetadas e aplica alterações maliciosas nos repositórios mantidos por essas contas. A injeção aparece no fim de arquivos Python de alto valor operacional, como setup.py, main.py e app.py, porque esses pontos costumam ser executados durante instalação, inicialização ou uso normal do projeto.
A técnica de force-push altera a história do Git e rebasa o commit legítimo mais recente com o código adulterado. Como a mensagem, o autor e a data original são mantidos, revisões superficiais podem não mostrar uma mudança óbvia. O risco cresce quando pipelines, ambientes de teste, usuários finais ou outros desenvolvedores consomem o repositório sem verificar o conteúdo real do commit. O código anexado contém carga Base64 ofuscada e lógica associada ao GlassWorm, incluindo checagem de localidade russa para interromper a execução nesses ambientes.
Depois da execução inicial, o malware consulta transações em carteiras Solana previamente ligadas à campanha para extrair o endereço do próximo payload. Esse uso da blockchain funciona como resolvedor de dead drop: a infraestrutura de comando não precisa ficar fixa no código comprometido, e o operador pode atualizar a URL em transações sem modificar todos os artefatos já distribuídos. O contexto também registra que o endereço de C2 teve transações desde 27 de novembro de 2025 e que a URL de payload era atualizada regularmente, inclusive várias vezes em um único dia.
A campanha não ficou restrita a Python. Dois pacotes npm React Native, react-native-international-phone-number e react-native-country-select, mantidos pelo usuário astroonauta, foram brevemente comprometidos com versões maliciosas publicadas diretamente no registro, sem release correspondente no GitHub. Essas versões continham hook preinstall que invocava JavaScript ofuscado, verificava variáveis de ambiente e fuso horário para excluir vítimas russas, consultava uma carteira Solana associada ao GlassWorm e entregava malware específico por plataforma. O payload descriptografado era executado em memória, sem gravação direta em disco, usando eval() em macOS/Linux ou vm.Script em outras plataformas.
Outra frente envolve extensões maliciosas e extensões dormentes. A campanha usou extensionPack e extensionDependencies para distribuir payloads de forma transitiva, ampliando sobrevivência e evasão. Duas extensões publicadas sem função maliciosa em 12 de março de 2026 foram atualizadas seis dias depois com um loader que roda ao carregar a extensão, enumera IDEs instaladas localmente e baixa um VSIX de um caminho fixo em release no GitHub. O arquivo autoimport-smart-tool-2.5.8.vsix é descrito como clone trojanizado de uma extensão popular de autoimportação e inclui geofencing russo, persistência e consulta à blockchain Solana para obter o próximo estágio.
A superfície de exposição inclui mantenedores cujos ambientes de desenvolvimento instalaram extensões maliciosas, repositórios sob contas com tokens roubados e consumidores que instalam código diretamente de repositórios GitHub afetados. O risco também se estende a projetos que usam dependências npm comprometidas em etapas de instalação, porque hooks preinstall são executados antes de o pacote ficar disponível para a aplicação. Em ambientes corporativos, a exposição pode alcançar estáções de desenvolvedores, pipelines de CI/CD, caches de dependências, artefatos internos e imagens de build que tenham consumido versões maliciosas.
O conjunto de artefatos citados mostra que a campanha se desloca entre ecossistemas: Python, JavaScript/npm, extensões VS Code/Open VSX e Windsurf IDE. Também há registro de mais de 433 projetos e pacotes afetados entre repositórios Python no GitHub, repositórios JavaScript, extensões VS Code e bibliotecas npm. Em paralelo, mais de 151 repositórios GitHub teriam sido comprometidos com código oculto por caracteres Unicode invisíveis, e mais de 20 extensões maliciosas adicionais, além de cerca de 20 extensões dormentes relacionadas, foram detectadas dentro do mesmo esforço operacional.
- Projetos Python que executam
setup.py,main.pyouapp.pya partir de repositórios GitHub comprometidos. - Pacotes npm React Native publicados em versões maliciosas com hook
preinstalle sem release GitHub correspondente. - Extensões de IDE que usam dependências transitivas, VSIX baixado de GitHub Releases ou loader executado no carregamento da extensão.
- Estáções de desenvolvedores com tokens GitHub, segredos de repositório, credenciais de navegador Chromium ou carteiras de criptomoedas acessíveis ao usuário local.
A investigação deve começar pela comparação entre o conteúdo real do ramo padrão e o histórico esperado do repositório. Como o force-push preserva metadados do commit legítimo, a análise precisa validar diferenças de árvore, assinatura de commits, eventos de force-push, alterações em arquivos de entrada e discrepâncias entre clones locais, tags, releases e pacotes publicados. Repositórios com alterações no fim de arquivos Python sensíveis desde 8 de março de 2026 merecem revisão manual, especialmente quando a alteração contém Base64 ofuscado, Unicode invisível ou lógica de execução dinâmica.
Em endpoints, a telemetria deve priorizar execução de Node.js ou Python originada por IDEs, instaladores de pacote, scripts de projeto e hooks de dependência. Sinais como criação de arquivo ~/init.json, execução em memória por primitivos JavaScript, consulta a transações Solana, download de payload por URL resolvida dinamicamente, criação de tarefa agendada oculta no PowerShell e configuração de chave Run no Registro do Windows são relevantes para triagem. A presença de checagens de localidade russa em scripts de extensão, pacote ou payload também deve ser tratada como forte indicador comportamental dentro desta campanha.
Em CI/CD, procure instalações de dependências vindas diretamente de repositórios GitHub, builds que consumiram versões npm publicadas em 16 de março de 2026 para os pacotes citados e jobs que executaram código de projetos afetados sem pinning rigoroso. Em ambientes de identidade, investigue tokens GitHub usados em horários anômalos, force-push incomum no ramo padrão, publicação de pacote sem pipeline conhecido e acesso a múltiplos repositórios logo após sinais de comprometimento em estáção de desenvolvedor.
- Eventos de force-push no ramo padrão com preservação incomum de autor, mensagem e data de commit.
- Código Base64 ou caracteres Unicode invisíveis adicionados ao fim de
setup.py,main.pyouapp.py. - Hooks
preinstallem dependências npm que iniciam JavaScript ofuscado antes da instalação concluir. - Extensões de IDE que enumeram instalações locais e baixam VSIX de GitHub Releases.
- Persistência por tarefa agendada oculta, chave Run no Registro do Windows ou arquivo de bloqueio
~/init.json.
A resposta deve combinar contenção de identidade, limpeza de cadeia de software e análise de endpoints. Tokens GitHub de contas envolvidas precisam ser revogados e recriados somente depois da validação do host do desenvolvedor. Repositórios com histórico reescrito devem ser restaurados a partir de referência confiável, com revisão de diffs em arquivos de inicialização e instalação. Também é necessário validar releases, tags, pacotes publicados e artefatos de build para impedir que uma alteração removida do Git permaneça em cache, registro interno ou imagem de contêiner.
Para dependências, a ação prática é bloquear versões maliciosas conhecidas, revisar lockfiles, limpar caches de gerenciadores de pacotes e reconstruir artefatos a partir de fontes verificadas. Organizações que permitem instalação direta de dependências por URL GitHub devem aplicar controle adicional, porque esse modelo contorna parte das validações existentes em registros de pacote. Em extensões de IDE, a mitigação exige inventário por estáção, remoção de extensões suspeitas, bloqueio de fontes não aprovadas e inspeção de extensões que foram publicadas inicialmente limpas e depois atualizadas com loader.
A contenção de hosts deve considerar que o payload tenta executar em memória e pode roubar credenciais de navegadores Chromium. Portanto, a ausência de arquivo de payload em disco não encerra a investigação. Após remover artefatos, a equipe deve rotacionar segredos de repositório, tokens de provedores cloud, credenciais de CI/CD, chaves de publicação npm e outros materiais acessíveis ao usuário afetado. Contas com permissão de publicação ou administração de repositórios devem receber revisão de sessões ativas, chaves SSH, aplicativos OAuth autorizados e escopos de tokens.
- Revogar tokens GitHub e credenciais de publicação usados por desenvolvedores com sinais de comprometimento.
- Auditar todos os repositórios da conta afetada para force-push no ramo padrão e alterações em arquivos de execução inicial.
- Restaurar conteúdo a partir de commits, tags ou mirrors confiáveis e publicar correções explícitas para consumidores.
- Bloquear versões npm comprometidas, revisar lockfiles e limpar caches de CI/CD antes de reconstruir artefatos.
- Inventariar extensões de IDE, remover extensões maliciosas ou dormentes e restringir instalação a fontes aprovadas.
0 Comentários