Abusing Github Actions
Informações Básicas
Nesta página você encontrará:
Um resumo de todos os impactos de um atacante conseguindo acessar uma Github Action
Diferentes maneiras de obter acesso a uma action:
Tendo permissões para criar a action
Abusando de gatilhos de pull request
Abusando de outras técnicas de acesso externo
Pivotando de um repositório já comprometido
Finalmente, uma seção sobre técnicas de pós-exploração para abusar de uma action por dentro (causando os impactos mencionados)
Resumo dos Impactos
Para uma introdução sobre Github Actions, confira as informações básicas.
Caso você consiga executar ações arbitrárias do Github/injetar código em um repositório, você poderá:
Roubar os segredos desse repositório/organização.
Se você só puder injetar, pode roubar o que já está presente no workflow.
Abusar dos privilégios do repositório para acessar outras plataformas como AWS e GCP.
Executar código em workers customizados (se forem usados) e tentar pivotar a partir daí.
Sobrescrever o código do repositório.
Isso depende dos privilégios do
GITHUB_TOKEN
(se houver).Comprometer implantações e outros artefatos.
Se o código estiver implantando ou armazenando algo, você pode modificar isso e obter mais acesso.
GITHUB_TOKEN
Este "segredo" (vindo de ${{ secrets.GITHUB_TOKEN }}
e ${{ github.token }}
) é fornecido quando o administrador habilita esta opção:
Este token é o mesmo que uma Aplicação Github usará, então pode acessar os mesmos endpoints: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Github deve lançar um fluxo que permite acesso entre repositórios dentro do GitHub, para que um repositório possa acessar outros repositórios internos usando o GITHUB_TOKEN
.
Você pode ver as possíveis permissões deste token em: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
Note que o token expira após a conclusão do job.
Esses tokens se parecem com isso: ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7
Algumas coisas interessantes que você pode fazer com este token:
Note que em várias ocasiões você poderá encontrar tokens de usuário do github dentro dos envs do Github Actions ou nos secrets. Esses tokens podem lhe dar mais privilégios sobre o repositório e a organização.
É possível verificar as permissões dadas a um Github Token em repositórios de outros usuários checando os logs das ações:
Execução Permitida
Esta seria a maneira mais fácil de comprometer ações do Github, pois este caso supõe que você tem acesso para criar um novo repositório na organização, ou tem privilégios de escrita sobre um repositório.
Se você está neste cenário, pode simplesmente verificar as técnicas de Pós-Explotação.
Execução a partir da Criação de Repositório
Caso membros de uma organização possam criar novos repositórios e você possa executar ações do github, você pode criar um novo repositório e roubar os segredos definidos a nível de organização.
Execução a partir de um Novo Branch
Se você pode criar um novo branch em um repositório que já contém uma Github Action configurada, você pode modificá-la, fazer upload do conteúdo e então executar essa ação a partir do novo branch. Desta forma, você pode exfiltrar segredos a nível de repositório e organização (mas você precisa saber como eles são chamados).
Você pode tornar a ação modificada executável manualmente, quando um PR é criado ou quando algum código é enviado (dependendo de quão barulhento você quer ser):
Execução em Fork
Existem diferentes gatilhos que poderiam permitir a um atacante executar uma Github Action de outro repositório. Se essas ações acionáveis estiverem mal configuradas, um atacante poderia comprometê-las.
pull_request
pull_request
O gatilho do workflow pull_request
executará o workflow toda vez que um pull request for recebido com algumas exceções: por padrão, se for a primeira vez que você está colaborando, algum mantenedor precisará aprovar a execução do workflow:
Como a limitação padrão é para colaboradores de primeira vez, você poderia contribuir corrigindo um bug/erro de digitação válido e depois enviar outros PRs para abusar de seus novos privilégios pull_request
.
Eu testei isso e não funciona: Outra opção seria criar uma conta com o nome de alguém que contribuiu para o projeto e deletou sua conta.
Além disso, por padrão impede permissões de escrita e acesso a segredos ao repositório alvo, conforme mencionado na documentação:
Com exceção do
GITHUB_TOKEN
, segredos não são passados para o runner quando um workflow é acionado a partir de um repositório forked. OGITHUB_TOKEN
tem permissões de leitura em pull requests de repositórios forked.
Um atacante poderia modificar a definição da Github Action para executar coisas arbitrárias e adicionar ações arbitrárias. No entanto, ele não poderá roubar segredos ou sobrescrever o repositório devido às limitações mencionadas.
Sim, se o atacante alterar no PR a github action que será acionada, a Github Action dele será a usada e não a do repositório original!
Como o atacante também controla o código sendo executado, mesmo que não haja segredos ou permissões de escrita no GITHUB_TOKEN
, um atacante poderia, por exemplo, carregar artefatos maliciosos.
pull_request_target
pull_request_target
O gatilho do workflow pull_request_target
tem permissão de escrita no repositório alvo e acesso a segredos (e não pede permissão).
Note que o gatilho do workflow pull_request_target
executa no contexto base e não no dado pelo PR (para não executar código não confiável). Para mais informações sobre pull_request_target
verifique a documentação.
Além disso, para mais informações sobre este uso específico e perigoso, verifique este post no blog do github.
Pode parecer que, porque o workflow executado é o definido no base e não no PR, é seguro usar pull_request_target
, mas há alguns casos em que não é.
E este terá acesso a segredos.
workflow_run
workflow_run
O gatilho workflow_run permite executar um workflow a partir de outro quando está completed
, requested
ou in_progress
.
Neste exemplo, um workflow é configurado para ser executado após a conclusão do workflow separado "Run Tests":
Além disso, de acordo com a documentação: O workflow iniciado pelo evento workflow_run
é capaz de acessar segredos e tokens de escrita, mesmo que o workflow anterior não fosse.
Esse tipo de workflow pode ser atacado se estiver dependendo de um workflow que pode ser disparado por um usuário externo via pull_request
ou pull_request_target
. Alguns exemplos vulneráveis podem ser encontrados neste blog. O primeiro consiste no workflow disparado pelo workflow_run
baixando o código do atacante: ${{ github.event.pull_request.head.sha }}
O segundo consiste em passar um artefato do código não confiável para o workflow workflow_run
e usar o conteúdo desse artefato de uma maneira que o torna vulnerável a RCE.
workflow_call
workflow_call
TODO
TODO: Verificar se, quando executado a partir de um pull_request, o código usado/baixado é o da origem ou do PR bifurcado
Abusando da Execução Bifurcada
Mencionamos todas as maneiras pelas quais um atacante externo poderia conseguir fazer um workflow do github ser executado, agora vamos ver como essas execuções, se mal configuradas, poderiam ser abusadas:
Execução de checkout não confiável
No caso de pull_request
, o workflow será executado no contexto do PR (então executará o código malicioso do PR), mas alguém precisa autorizá-lo primeiro e ele será executado com algumas limitações.
No caso de um workflow usando pull_request_target
ou workflow_run
que depende de um workflow que pode ser disparado a partir de pull_request_target
ou pull_request
, o código do repositório original será executado, então o atacante não pode controlar o código executado.
No entanto, se a ação tiver um checkout explícito do PR que obterá o código do PR (e não da base), usará o código controlado pelo atacante. Por exemplo (verifique a linha 12 onde o código do PR é baixado):
O código potencialmente não confiável está sendo executado durante npm install
ou npm build
já que os scripts de build e pacotes referenciados são controlados pelo autor do PR.
Um dork do github para procurar ações vulneráveis é: event.pull_request pull_request_target extension:yml
no entanto, existem diferentes maneiras de configurar os jobs para serem executados com segurança, mesmo que a ação esteja configurada de forma insegura (como usar condicionais sobre quem é o ator que gera o PR).
Injeções de Script de Contexto
Note que existem certos contextos do github cujos valores são controlados pelo usuário que cria o PR. Se a ação do github estiver usando esses dados para executar qualquer coisa, isso pode levar a execução arbitrária de código:
Gh Actions - Context Script InjectionsInjeção de Script no GITHUB_ENV
De acordo com a documentação: Você pode tornar uma variável de ambiente disponível para qualquer etapa subsequente em um job de workflow definindo ou atualizando a variável de ambiente e escrevendo isso no arquivo de ambiente GITHUB_ENV
.
Se um atacante puder injetar qualquer valor dentro dessa variável de ambiente, ele poderá injetar variáveis de ambiente que poderiam executar código nas etapas seguintes, como LD_PRELOAD ou NODE_OPTIONS.
Por exemplo (este e este), imagine um workflow que confia em um artefato carregado para armazenar seu conteúdo dentro da variável de ambiente GITHUB_ENV
. Um atacante poderia carregar algo assim para comprometê-lo:
Ações de Terceiros Vulneráveis no Github
Conforme mencionado neste post do blog, esta Ação do Github permite acessar artefatos de diferentes workflows e até mesmo repositórios.
O problema é que se o parâmetro path
não estiver definido, o artefato é extraído no diretório atual e pode substituir arquivos que poderiam ser usados ou até mesmo executados no workflow posteriormente. Portanto, se o Artefato for vulnerável, um atacante poderia abusar disso para comprometer outros workflows que confiam no Artefato.
Exemplo de workflow vulnerável:
Isso pode ser atacado com este workflow:
Outro Acesso Externo
Hijacking de Repositório de Namespace Deletado
Se uma conta muda seu nome, outro usuário pode registrar uma conta com esse nome após algum tempo. Se um repositório tinha menos de 100 estrelas antes da mudança de nome, o Github permitirá que o novo usuário registrado com o mesmo nome crie um repositório com o mesmo nome que o deletado.
Então, se uma ação está usando um repositório de uma conta inexistente, ainda é possível que um atacante crie essa conta e comprometa a ação.
Se outros repositórios estavam usando dependências desses repositórios de usuário, um atacante poderá sequestrá-los. Aqui você tem uma explicação mais completa: https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/
Repo Pivoting
Nesta seção, falaremos sobre técnicas que permitiriam pivotar de um repositório para outro, supondo que temos algum tipo de acesso no primeiro (verifique a seção anterior).
Envenenamento de Cache
Um cache é mantido entre execuções de workflow no mesmo branch. O que significa que se um atacante comprometer um pacote que é então armazenado no cache e baixado e executado por um workflow mais privilegiado, ele também poderá comprometer esse workflow.
GH Actions - Cache PoisoningEnvenenamento de Artefato
Workflows podem usar artefatos de outros workflows e até mesmo repositórios, se um atacante conseguir comprometer a Github Action que faz upload de um artefato que é posteriormente usado por outro workflow, ele poderá comprometer os outros workflows:
Gh Actions - Artifact PoisoningPós-Exploração a partir de uma Ação
Acessando AWS e GCP via OIDC
Verifique as seguintes páginas:
AWS - Federation AbuseGCP - Federation AbuseAcessando segredos
Se você está injetando conteúdo em um script, é interessante saber como acessar segredos:
Se o segredo ou token estiver configurado como uma variável de ambiente, ele pode ser acessado diretamente através do ambiente usando
printenv
.
Se o segredo for usado diretamente em uma expressão, o script shell gerado é armazenado em disco e é acessível.
cat /home/runner/work/_temp/*
Para uma custom action, o risco pode variar dependendo de como um programa está usando o segredo obtido do argumento:
Abusando de Self-hosted runners
A maneira de descobrir quais Github Actions estão sendo executadas em infraestrutura não-Github é procurar por runs-on: self-hosted
na configuração yaml da Github Action.
Self-hosted runners podem ter acesso a informações extras sensíveis, a outros sistemas de rede (endpoints vulneráveis na rede? serviço de metadados?) ou, mesmo que esteja isolado e destruído, mais de uma ação pode ser executada ao mesmo tempo e a maliciosa poderia roubar os segredos da outra.
Em self-hosted runners também é possível obter os **segredos do processo _Runner.Listener_** que conterá todos os segredos dos workflows em qualquer etapa, despejando sua memória:
Confira este post para mais informações.
Registro de Imagens Docker do Github
É possível criar ações do Github que construam e armazenem uma imagem Docker dentro do Github. Um exemplo pode ser encontrado no expansível a seguir:
Last updated