Pacotes Ruby e módulos Go maliciosos exploram pipelines de CI para roubo de credenciais

Pacotes Ruby e módulos Go maliciosos exploram pipelines de CI para roubo de credenciais

Campanha usou bibliotecas publicadas por BufferZoneCorp para executar cargas em instalação e inicialização, coletar segredos de ambientes de desenvolvimento, adulterar GitHub Actions e adicionar persistência por SSH.

ComponenteGems Ruby e módulos Go associados à conta GitHub BufferZoneCorp, incluindo nomes que imitavam bibliotecas reconhecíveis como activesupport-logger, devise-jwt, go-retryablehttp, grpc-client e config-loader.
VetorInstalação ou uso dos pacotes em estáções de desenvolvedores, runners de CI e ambientes de build, com execução de lógica maliciosa durante instalação ou por inicialização de módulos Go via init().
ImpactoRoubo de variáveis de ambiente, chaves SSH, segredos AWS, arquivos .npmrc e .netrc, configuração do GitHub CLI, credenciais RubyGems, adulteração de fluxos do GitHub Actions e inserção de chave em ~/.ssh/authorized_keys.
PrioridadeRemover os pacotes, revisar hosts e runners que os instalaram, rotacionar segredos expostos, verificar alterações em workflows e auditar tráfego HTTPS de saída para endpoint Webhook[.]site.
ArtefatosGITHUB_ENV, GITHUB_PATH, HTTP_PROXY, HTTPS_PROXY, wrapper falso para go, diretório de cache no caminho de execução e modificação de ~/.ssh/authorized_keys.
MitigaçãoInvalidar credenciais possivelmente coletadas, limpar caches de build, reconstruir runners afetados quando houver execução confirmada e aplicar bloqueios de dependências por origem, integridade e revisão de lockfiles.
Resumo técnico

Uma campanha de comprometimento de cadeia de suprimentos de software distribuiu gems Ruby e módulos Go com comportamento malicioso voltado a ambientes de desenvolvimento e integração contínua. Os pacotes foram publicados a partir da conta GitHub BufferZoneCorp e usaram nomes visualmente plausíveis para se aproximar de bibliotecas conhecidas, como activesupport-logger, devise-jwt, go-retryablehttp, grpc-client e config-loader. O objetivo operacional era alcançar máquinas de desenvolvedores, runners de CI e ambientes de build nos quais segredos costumam estar disponíveis por variáveis de ambiente, arquivos de configuração, tokens de ferramentas e chaves de autenticação.

A atividade combina duas estratégias. Nas gems Ruby, a execução ocorre durante a instalação, momento em que o pacote tenta coletar credenciais e arquivos sensíveis antes de enviar os dados para um endpoint controlado pelo operador em Webhook[.]site. Nos módulos Go, a capacidade é mais ampla: a carga usa execução via init(), detecta variáveis específicas do GitHub Actions, altera variáveis de proxy, grava um wrapper falso para o binário go, muda o caminho de execução do workflow e adiciona uma chave pública fixa em ~/.ssh/authorized_keys para viabilizar acesso remoto posterior. Os pacotes Ruby foram removidos do RubyGems e os módulos Go foram bloqueados, mas qualquer ambiente que tenha instalado as dependências antes da remoção deve ser tratado como potencialmente exposto.

Fluxo técnico

A cadeia de execução depende de confiança implícita em dependências de terceiros. O operador publicou pacotes que se passavam por módulos úteis ou por variações de nomes conhecidos, aumentando a chance de instalação manual, inclusão por erro em manifestos ou adoção por automações. Em Ruby, o ponto crítico está no ciclo de instalação da gem: quando o pacote é resolvido e instalado, a lógica maliciosa procura material sensível no ambiente local. A coleta inclui variáveis de ambiente, chaves SSH, segredos AWS, arquivos .npmrc e .netrc, configuração do GitHub CLI e credenciais RubyGems. Esses artefatos normalmente dão acesso a registros de pacotes, repositórios privados, infraestrutura cloud, automações de publicação e serviços externos usados no pipeline.

Nos módulos Go, a técnica explora o fato de que funções init() executam automaticamente quando o pacote é carregado. A carga detecta GITHUB_ENV e GITHUB_PATH, variáveis usadas pelo GitHub Actions para persistir configurações e alterar o ambiente de etapas seguintes. Em seguida, define HTTP_PROXY e HTTPS_PROXY, grava um executável falso chamado go em um diretório de cache e acrescenta esse diretório ao caminho do workflow. Com isso, execuções posteriores de go podem selecionar o wrapper antes do binário legítimo. O wrapper ainda repassa o controle para o binário real, o que reduz falhas visíveis no job e dificulta a percepção imediata de que o processo foi interceptado.

A persistência por SSH amplia o impacto além da execução temporária do pipeline. Ao adicionar uma chave pública fixa em ~/.ssh/authorized_keys, a carga cria uma forma de acesso remoto ao host comprometido quando o serviço SSH e a conectividade permitirem. Essa condição é especialmente grave em runners auto-hospedados, estáções de desenvolvimento e servidores de build reutilizados, porque credenciais e caches podem permanecer no disco entre execuções. Em runners efêmeros, o risco se concentra na janela de execução, nos segredos expostos ao job e nos artefatos enviados para fora antes da destruição da instância.

Superfície afetada

A exposição principal está em projetos que instalaram as gems Ruby ou importaram os módulos Go associados à campanha. O risco não se limita ao código-fonte da aplicação; ele alcança a infraestrutura de construção. Um runner com variáveis de ambiente contendo tokens de implantação, credenciais AWS, tokens do GitHub, credenciais RubyGems ou chaves SSH fornece ao pacote malicioso um caminho direto para credenciais operacionais. Arquivos como .npmrc e .netrc também podem conter tokens reutilizáveis para registros de pacotes, repositórios, APIs internas e serviços de automação.

Em GitHub Actions, a manipulação de GITHUB_ENV e GITHUB_PATH altera o comportamento de etapas seguintes do workflow. O impacto real depende de quais permissões foram concedidas ao job, quais segredos estavam disponíveis e se o runner é efêmero ou persistente. Workflows que publicam pacotes, assinam artefatos, fazem deploy, acessam cloud ou usam tokens com escopo amplo têm risco maior, porque a coleta de credenciais pode permitir movimentação para fora do pipeline original. Ambientes que mantêm caches de dependências e ferramentas entre builds também precisam ser analisados, pois o wrapper falso para go pode ter sido preservado em caminhos reutilizados.

A remoção dos pacotes dos registros reduz novas instalações diretas, mas não elimina cópias em caches, mirrors privados, imagens de build, lockfiles, artefatos de reprodutibilidade e ambientes já comprometidos. A resposta precisa considerar o histórico de execução: quando a dependência entrou no projeto, quais pipelines foram executados depois disso, quais segredos estavam disponíveis naquele período e quais hosts mantiveram estado entre execuções.

  • Projetos Ruby que instalaram gems publicadas pela conta BufferZoneCorp ou nomes similares aos pacotes citados.
  • Projetos Go que importaram módulos associados à campanha e executaram builds com funções init() carregadas.
  • Runners do GitHub Actions com GITHUB_ENV e GITHUB_PATH disponíveis para alteração durante o workflow.
  • Hosts com ~/.ssh/authorized_keys gravável pelo usuário que executou a instalação ou o build.
Hunting e telemetria

A investigação deve começar pela árvore de dependências e pelo histórico de builds. Em Ruby, revise Gemfile, Gemfile.lock, logs de instalação e caches de gems em busca dos nomes associados e de pacotes publicados pela conta indicada. Em Go, examine go.mod, go.sum, cache de módulos, imagens de build e logs de resolução de dependências. A presença de pacotes já removidos ou bloqueados nos registros públicos não deve ser descartada se houver mirrors internos, caches de proxy ou imagens antigas que ainda contenham o conteúdo.

No endpoint e no runner, procure leitura incomum de arquivos sensíveis durante instalação de dependências ou execução de builds. Acessos a chaves SSH, .npmrc, .netrc, diretórios de configuração do GitHub CLI, arquivos de credenciais RubyGems e variáveis AWS durante a etapa de instalação são sinais fortes quando associados a processos de gerenciadores de pacotes ou compilação. Em ambientes Linux, alterações em ~/.ssh/authorized_keys próximas ao horário de execução do pipeline devem ser tratadas como indicador de persistência, especialmente quando a chave adicionada não corresponde a inventário autorizado.

Na telemetria de rede, filtre conexões HTTPS de saída originadas de runners, estáções de desenvolvimento e servidores de build para destinos Webhook[.]site. Como o endpoint exato não foi fornecido, a detecção deve considerar domínio, resolução DNS, SNI, logs de proxy e metadados de TLS. Também é necessário revisar alterações em variáveis HTTP_PROXY e HTTPS_PROXY dentro de jobs, porque a carga dos módulos Go usa esses nomes para influenciar tráfego. Em GitHub Actions, eventos de modificação de caminho por GITHUB_PATH, escrita em GITHUB_ENV e execução de um binário go fora do caminho esperado ajudam a reconstruir a ordem de execução.

  • Instalação ou resolução de activesupport-logger, devise-jwt, go-retryablehttp, grpc-client, config-loader quando associados ao conjunto malicioso.
  • Conexões HTTPS de saída para Webhook[.]site a partir de runners, estáções de desenvolvimento ou servidores de build.
  • Criação de executável chamado go em diretório de cache e posterior precedência desse diretório em PATH.
  • Escritas não autorizadas em ~/.ssh/authorized_keys durante ou logo após execução de pipeline.
  • Leitura de .npmrc, .netrc, chaves SSH, credenciais RubyGems, configuração do GitHub CLI e variáveis AWS por processos de instalação.
Mitigação

A primeira ação é remover as dependências maliciosas de manifestos, lockfiles, caches locais, caches de CI, mirrors internos e imagens de build. Em seguida, os pipelines que executaram esses pacotes devem ser identificados por data, projeto, ramo, runner e conjunto de segredos disponível. Como a campanha foi desenhada para roubar credenciais, a rotação deve abranger tokens GitHub, chaves SSH, segredos AWS, credenciais RubyGems, tokens de registros de pacotes e credenciais armazenadas em .npmrc ou .netrc. Revogar apenas a dependência não é suficiente quando a execução já ocorreu.

Runners persistentes exigem contenção mais rigorosa. Verifique ~/.ssh/authorized_keys, remova entradas desconhecidas, audite usuários locais, limpe diretórios de cache que possam conter o wrapper falso para go e valide o caminho de execução usado nos workflows. Quando houver confirmação de execução da carga ou impossibilidade de estabelecer o estado do host, a abordagem mais confiável é reconstruir o runner a partir de imagem limpa e reemitir credenciais necessárias com escopos mínimos. Runners efêmeros reduzem persistência em disco, mas ainda exigem rotação dos segredos expostos durante a execução comprometida.

No controle preventivo, restrinja permissões de GITHUB_TOKEN, limite exposição de segredos por ambiente, separe workflows de build e publicação, exija revisão para novas dependências e monitore alterações em lockfiles. Use políticas de allowlist para registros e namespaces confiáveis quando possível, valide integridade de dependências e bloqueie execução de pacotes recém-publicados ou com metadados suspeitos em pipelines sensíveis. Para Go, trate funções init() em dependências novas como superfície de execução e revise módulos que alteram ambiente, caminho, proxy ou arquivos de autenticação. Para Ruby, dê atenção a scripts de instalação e comportamento de gems durante resolução e instalação.

  • Remover os pacotes dos manifestos e regenerar lockfiles após revisão manual das dependências transitivas.
  • Limpar caches de CI, caches de módulos Go, caches de gems, mirrors internos e imagens de build que possam conter os pacotes.
  • Rotacionar tokens GitHub, credenciais AWS, chaves SSH, credenciais RubyGems e tokens presentes em .npmrc ou .netrc.
  • Auditar ~/.ssh/authorized_keys e remover chaves não inventariadas em estáções, servidores de build e runners auto-hospedados.
  • Revisar workflows do GitHub Actions para alterações em GITHUB_ENV, GITHUB_PATH, HTTP_PROXY, HTTPS_PROXY e precedência inesperada no PATH.
  • Reduzir escopos de segredos em pipelines, separar etapas de build e publicação e reconstruir runners persistentes quando a integridade não puder ser comprovada.

Postar um comentário

0 Comentários