Uma campanha automatizada usa tokens roubados do GitHub para instalar fluxos de trabalho que imprimem nos registros do GitHub Actions os segredos de um repositório. Os invasores baixam esses registros e, em seguida, excluem as execuções. Os ataques foram bem-sucedidos em repositórios privados e em ambientes do GitHub Enterprise, segundo uma análise da empresa de segurança em nuvem Wiz.
Uma proteção do GitHub que suspende execuções suspeitas de fluxos de trabalho impediu a execução de todos os fluxos analisados pela Wiz em repositórios públicos. A medida, porém, não abrange repositórios privados nem o GitHub Enterprise Server.
Cada fluxo de trabalho é instalado em uma nova ramificação chamada `ci-sync-`, seguida por seis caracteres aleatórios. Excluir a ramificação ou a execução iniciada por ela não desfaz a exposição. Todos os segredos que o repositório podia acessar devem ser trocados, e o token usado para enviar a ramificação precisa ser revogado.
A Wiz acompanha a campanha desde 15 de setembro e a chamou de Gheist, em referência ao agente do usuário `gheist`, enviado pela ferramenta dos invasores nas solicitações à API do GitHub.
A Wiz identificou mais de 13.500 ramificações implantadas em mais de 850 contas comprometidas, que vão de projetos pessoais a repositórios privados de organizações empresariais. A análise não informa quantas organizações tiveram segredos expostos.
Em repositórios privados e no GitHub Enterprise Server, os registros de auditoria do GitHub mostram execuções concluídas em ramificações implantadas e, depois, excluídas pelo agente do usuário `gheist`. Registros do AWS CloudTrail indicam que os próprios fluxos de trabalho das organizações também foram executados nessas ramificações e assumiram funções da AWS, um sinal de que o GitHub Actions foi executado sem aprovação.
Em organizações empresariais, a ferramenta alternou entre tokens de vários usuários e contas de automação em questão de minutos. Também clonou repositórios privados antes de instalar o fluxo de trabalho. Horas depois, credenciais de nuvem da mesma organização foram usadas para enumerar recursos do AWS Secrets Manager. A análise da Wiz não esclarece de onde vieram essas credenciais nem quem as usou.
Em 24 de outubro, a campanha ainda estava ativa e em transformação. Cerca de dois terços das contas envolvidas já não estavam disponíveis no GitHub. A Wiz notificou o GitHub sobre a atividade e avalia que o desaparecimento das contas provavelmente foi resultado de uma resposta.
Segundo a documentação do GitHub, qualquer pessoa com permissão de gravação em um repositório pode ler todos os segredos configurados nele. Um token roubado com esse nível de acesso é suficiente.
Para cada repositório que um token pode acessar, a ferramenta cria uma ramificação `ci-sync-` e envia um único arquivo, `.github/workflows/sync-check.yml`, com a mensagem `ci: sync config`. O commit não é assinado e inclui o nome do proprietário do token. O envio inicia o fluxo de trabalho.
O fluxo imprime o ambiente da tarefa e todos os segredos que ela pode acessar, codificados em base32. O GitHub oculta segredos nos registros, mas sua documentação alerta que isso não é garantido quando um valor é codificado ou alterado de outra forma. Segundo a Wiz, o texto em base32 deixa de corresponder ao segredo original e, por isso, aparece por inteiro.
O fluxo de trabalho define um bloco `permissions` vazio. Isso limita o `GITHUB_TOKEN` da tarefa, que os invasores não precisam usar, mas não impede o acesso aos segredos.
Uma versão da ferramenta também executa uma tarefa para cada ambiente de implantação configurado no repositório. Assim, segredos restritos a esses ambientes também são exibidos. Segundo a Wiz, muitas vezes são credenciais de produção.
Em seguida, a ferramenta baixa o registro pela API do GitHub e exclui a execução segundos depois. Como os segredos são exfiltrados por meio da própria plataforma do GitHub, não há um servidor dos invasores nem uma conexão de saída que possa ser bloqueada.
Desde 28 de julho, o GitHub mantém suspensas as execuções de fluxos de trabalho que identifica como potencialmente maliciosas até que um colaborador com permissão de gravação as aprove. A empresa afirma que a suspensão “atualmente se aplica apenas a repositórios públicos no github.com” e que, por enquanto, o GitHub Enterprise Server não conta com esse recurso.
Todas as execuções públicas da Gheist analisadas pela Wiz, em todas as versões da ferramenta, continuavam aguardando aprovação. Por isso, o código malicioso não foi executado.
A suspensão só se aplica às execuções sinalizadas pelo GitHub. Uma nova variante da GhostAction, uma campanha distinta, conseguiu operar em repositórios públicos até que o GitHub começasse a bloqueá-la, em 9 de outubro, segundo uma pesquisa da empresa de segurança GitGuardian. A Wiz afirma que a Gheist é diferente da GhostAction, que usa outros arquivos de fluxo de trabalho.
Por volta de 19 de outubro, uma versão da ferramenta começou a enviar uma segunda tarefa, voltada a executores autogerenciados, ou seja, máquinas que as próprias organizações operam para processar tarefas do GitHub Actions. Aparentemente, ela mira apenas repositórios com esse tipo de executor registrado.
A tarefa foi programada para buscar credenciais na máquina executora, incluindo 31 tipos de tokens: chaves privadas, ambientes de processos, credenciais de funções de instância da AWS, arquivos de credenciais do executor e o token da conta de serviço do Kubernetes. A Wiz descreve a tarefa como defeituosa, e sua análise não identificou nenhuma execução bem-sucedida.
Entre as fontes dos tokens roubados que a Wiz conseguiu rastrear estão registros de infostealer e tokens expostos em ataques anteriores à supply chain, como o comprometimento do verificador de vulnerabilidades Trivy, em março.
Outros invasores também usam as mesmas contas. Em 6 de outubro, 391 contas, muitas delas também usadas pela Gheist, renomearam cerca de 1.461 repositórios para fazê-los parecer cópias de programas pirateados e distribuir malware. A mudança de nomes apagou 610 das ramificações implantadas.
Algumas vítimas também parecem estar infectadas pelo malware PolinRider, associado por pesquisadores à Coreia do Norte. Em 19 e 20 de outubro, três delas enviaram novamente suas alterações da Gheist, desta vez com um loader incluído no arquivo `vite.config.js`.
A campanha Megalodon, que em maio instalou fluxos de trabalho para roubar segredos em milhares de repositórios do GitHub, também havia atingido 57 dessas contas.
Como verificar seus repositórios
A Wiz recomenda as seguintes verificações:
- Procure ramificações com o nome `ci-sync-` seguido por seis caracteres. A única alteração deve ser a inclusão do arquivo `.github/workflows/sync-check.yml`, com a mensagem `ci: sync config`.
- Nos registros de auditoria do GitHub, procure execuções em ramificações `ci-sync-*` que tenham sido excluídas até um minuto após o término, além de qualquer atividade do agente do usuário `gheist`.
- Se seus fluxos de trabalho usam OIDC para se autenticar em um provedor de nuvem, confira os registros de auditoria da nuvem em busca de assunções de função ou trocas de tokens cujo assunto inclua uma ramificação `ci-sync-`. Essa verificação funciona mesmo sem a coleta de registros do GitHub.
- Em executores autogerenciados, procure os arquivos `.gdmp_pat`, `.gdmp_patg` e `.gdmp_sweep`, além da sequência `gdmp-pivot` nos registros das tarefas.
O OIDC permite que fluxos de trabalho se autentiquem com tokens de curta duração, em vez de chaves de nuvem armazenadas. Por padrão, o assunto de um token inclui o nome da ramificação apenas quando a tarefa não usa um ambiente de implantação, segundo a documentação de OIDC do GitHub.
Os indicadores publicados são:
- Agente do usuário: `gheist`
- Ramificação: `^ci-sync-[0-9a-z]{6}$`
- Mensagem do commit: `ci: sync config`, com a inclusão apenas de `.github/workflows/sync-check.yml`
- Sequência: `toJSON(secrets) }}' | base32 -w 120`
- Sequência: `===== gdmp-pivot:`
- Arquivo: `.gdmp_pat`
- Arquivo: `.gdmp_patg`
- Arquivo: `.gdmp_sweep`
- Hash do objeto blob do Git, fluxo de trabalho simples: `f3da2b8b357dcda02fd455d314be2a95007516a6`
- Hash do objeto blob do Git, versão com limite de tempo: `d09535857a741bbb976bdc084a9a021713133291`
- Hash do objeto blob do Git, versão com separador: `1dc5af9cce950aad1eb1546ecce8565b117540c4`
- Hash do objeto blob do Git, versão com tarefa para executor autogerenciado: `c665b778b2d822453293003e7ca0bbb2cb08e39d`
As versões do fluxo de trabalho que enumeram os ambientes de implantação de um repositório variam de acordo com cada repositório e, por isso, não têm um hash fixo.
O que fazer se encontrar uma ramificação ci-sync
Para um repositório afetado, a Wiz recomenda:
- Troque todos os segredos do repositório, da organização e dos ambientes que ele podia acessar.
- Revogue os tokens usados para enviar as alterações e verifique se os dispositivos de seus proprietários têm infostealers.
- Se uma ramificação `ci-sync` tiver sido executada em um executor autogerenciado, considere comprometidos tanto a máquina quanto a função de instância de nuvem associada.
- Não aprove execuções suspensas de `sync-check` nem execute código de ramificações `ci-sync`.
Para reduzir a utilidade de um token roubado, a Wiz também recomenda:
- Exigir revisores para ambientes que armazenam segredos de produção.
- Restringir as políticas de confiança do OIDC a ramificações ou ambientes protegidos.
- Usar GitHub Apps ou tokens detalhados de curta duração, em vez de tokens de acesso pessoal.
- Operar executores autogerenciados em máquinas de curta duração, sem acesso ao socket do Docker nem acesso irrestrito aos metadados da nuvem.
Segundo a documentação do GitHub, uma tarefa não pode ler os segredos de um ambiente até que um revisor obrigatório a aprove.
Publicidade
Tenha acesso aos melhores hackers éticos do mercado através de um serviço personalizado, especializado e adaptado para o seu negócio. Guardsi: qualidade, confiança e especialidade em segurança ofensiva de quem já protegeu centenas de empresas. Saiba mais...