Abusing Github Actions
Informações Básicas
Nesta página você encontrará:
Um resumo de todos os impactos de um atacante que consegue acessar uma Ação do Github
Diferentes maneiras de obter acesso a uma ação:
Ter permissões para criar a ação
Abusar dos gatilhos relacionados a pull request
Abusar de outras técnicas de acesso externo
Pivotar de um repositório já comprometido
Por fim, uma seção sobre técnicas de pós-exploração para abusar de uma ação de dentro (causar os impactos mencionados)
Resumo dos Impactos
Para uma introdução sobre Ações do Github, confira as informações básicas.
Caso você consiga executar ações do Github arbitrariamente/injetar código em um repositório, você poderia ser capaz de:
Roubar os segredos desse repositório/organização.
Se você só puder injetar, pode roubar o que já está presente no fluxo de trabalho.
Abusar dos privilégios do repositório para acessar outras plataformas como AWS e GCP.
Executar código em workers personalizados (se workers personalizados 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ê poderia modificá-lo 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 um Aplicativo Github usará, então ele pode acessar os mesmos endpoints: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
O Github deveria 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
Observe que o token expira após a conclusão do trabalho.
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 das variáveis de ambiente do Github Actions ou nos segredos. Esses tokens podem conceder a você mais privilégios sobre o repositório e a organização.
É possível verificar as permissões concedidas a um Token do Github em repositórios de outros usuários verificando os logs das ações:
Execução Permitida
Esta seria a maneira mais fácil de comprometer as ações do Github, pois esse caso pressupõe que você tenha acesso para criar um novo repositório na organização, ou tenha privilégios de escrita sobre um repositório.
Se estiver nesse cenário, você pode simplesmente verificar as técnicas de Pós-Exploração.
Execução a partir da Criação de Repositório
No caso de membros de uma organização poderem criar novos repositórios e você puder executar ações do github, você pode criar um novo repositório e roubar os segredos definidos no nível da organização.
Execução a partir de um Novo Branch
Se você puder criar um novo branch em um repositório que já contenha uma Ação do Github configurada, você pode modificá-la, fazer upload do conteúdo e então executar essa ação a partir do novo branch. Dessa forma, você pode exfiltrar segredos do nível do repositório e da 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ê deseja ser):
Execução de Forked
Existem diferentes gatilhos que poderiam permitir a um atacante executar uma Ação do Github de outro repositório. Se essas ações acionáveis estiverem mal configuradas, um atacante poderia comprometê-las.
pull_request
pull_request
O gatilho de fluxo de trabalho pull_request
executará o fluxo de trabalho toda vez que uma solicitação de pull for recebida com algumas exceções: por padrão, se for a primeira vez que você está colaborando, algum mantenedor precisará aprovar a execução do fluxo de trabalho:
Como a limitação padrão é para contribuidores de primeira vez, você poderia contribuir corrigindo um bug/tipo válido e então enviar outras PRs para abusar de seus novos privilégios de pull_request
.
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 excluiu sua conta.
Além disso, por padrão impede permissões de gravação e acesso a segredos ao repositório de destino, conforme mencionado na documentação:
Com exceção do
GITHUB_TOKEN
, os segredos não são passados para o executor quando um fluxo de trabalho é acionado a partir de um repositório forkado. OGITHUB_TOKEN
tem permissões somente leitura em solicitações de pull de repositórios forkados.
Um atacante poderia modificar a definição da Ação do Github para executar coisas arbitrárias e anexar ações arbitrárias. No entanto, ele não será capaz de roubar segredos ou sobrescrever o repositório por causa das limitações mencionadas.
Sim, se o atacante alterar na PR a ação do github que será acionada, sua Ação do Github será a usada e não a do repositório de origem!
Como o atacante também controla o código sendo executado, mesmo que não haja segredos ou permissões de gravação no GITHUB_TOKEN
, um atacante poderia, por exemplo, fazer upload de artefatos maliciosos.
pull_request_target
pull_request_target
O gatilho de fluxo de trabalho pull_request_target
tem permissão de gravação no repositório de destino e acesso a segredos (e não solicita permissão).
Observe que o gatilho de fluxo de trabalho pull_request_target
é executado no contexto base e não no fornecido pela 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 esse uso específico perigoso, verifique este post do blog do github.
Pode parecer que porque o fluxo de trabalho executado é o definido na base e não na 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 fluxo de trabalho de um diferente quando ele é completado
, solicitado
ou em_progresso
.
Neste exemplo, um fluxo de trabalho é configurado para ser executado após o fluxo de trabalho separado "Executar Testes" ser concluído:
Além disso, de acordo com a documentação: O fluxo de trabalho iniciado pelo evento workflow_run
é capaz de acessar segredos e gravar tokens, mesmo que o fluxo de trabalho anterior não tenha feito isso.
Esse tipo de fluxo de trabalho pode ser atacado se estiver dependendo de um fluxo de trabalho que pode ser acionado 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 fluxo de trabalho acionado pelo workflow_run
baixando o código dos atacantes: ${{ github.event.pull_request.head.sha }}
O segundo consiste em passar um artefato do código não confiável para o fluxo de trabalho workflow_run
e usar o conteúdo deste artefato de uma maneira que o torne vulnerável a RCE.
workflow_call
workflow_call
A FAZER
A FAZER: Verificar se, quando executado a partir de um pull_request
, o código usado/baixado é o do original ou do PR bifurcado
Abusando da Execução Bifurcada
Mencionamos todas as maneiras pelas quais um atacante externo poderia fazer um fluxo de trabalho 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 fluxo de trabalho será executado no contexto do PR (portanto, executará o código malicioso dos PRs), mas alguém precisa autorizá-lo primeiro e ele será executado com algumas limitações.
No caso de um fluxo de trabalho usando pull_request_target
ou workflow_run
que depende de um fluxo de trabalho que pode ser acionado 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 irá obter o código do PR (e não da base), ele 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 é executado durante npm install
ou npm build
pois os scripts de compilação e os pacotes referenciados são controlados pelo autor do PR.
Um dork do GitHub para pesquisar ações vulneráveis é: event.pull_request pull_request_target extension:yml
no entanto, existem diferentes maneiras de configurar os trabalhos para serem executados com segurança, mesmo que a ação seja configurada de forma insegura (como usar condicionais sobre quem é o ator gerando o PR).
Injeções de Script de Contexto
Observe 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 poderia levar a uma execução de código arbitrário:
pageGh Actions - Context Script InjectionsInjeção de Script GITHUB_ENV
De acordo com a documentação: Você pode tornar uma variável de ambiente disponível para etapas subsequentes em um trabalho de fluxo de trabalho definindo ou atualizando a variável de ambiente e escrevendo isso no arquivo de ambiente GITHUB_ENV
.
Se um atacante pudesse injetar qualquer valor dentro dessa variável de ambiente, ele poderia injetar variáveis de ambiente que poderiam executar código em etapas seguintes, como LD_PRELOAD ou NODE_OPTIONS.
Por exemplo (este e este), imagine um fluxo de trabalho que confia em um artefato enviado para armazenar seu conteúdo dentro da variável de ambiente GITHUB_ENV
. Um atacante poderia enviar algo assim para comprometê-lo:
Ações do GitHub de Terceiros Vulneráveis
Conforme mencionado neste post do blog, esta Ação do GitHub permite acessar artefatos de diferentes fluxos de trabalho 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 posteriormente ou até mesmo executados no fluxo de trabalho. Portanto, se o Artefato for vulnerável, um atacante poderia abusar disso para comprometer outros fluxos de trabalho que confiam no Artefato.
Exemplo de fluxo de trabalho vulnerável:
Isso poderia ser atacado com este fluxo de trabalho:
Outro Acesso Externo
Sequestro de Repositório de Namespace Deletado
Se uma conta altera seu nome, outro usuário poderia registrar uma conta com esse nome após algum tempo. Se um repositório tinha menos de 100 estrelas anteriormente à 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 do que foi deletado.
Portanto, se uma ação estiver usando um repositório de uma conta inexistente, ainda é possível que um atacante possa criar essa conta e comprometer a ação.
Se outros repositórios estiverem usando dependências dos repositórios desse 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/
Pivoteamento de Repositório
Nesta seção, falaremos sobre técnicas que permitiriam pivoteamento de um repositório para outro supondo que tenhamos algum tipo de acesso no primeiro (verifique a seção anterior).
Envenenamento de Cache
Um cache é mantido entre execuções de fluxo de trabalho na mesma branch. Isso significa que se um atacante comprometer um pacote que é então armazenado no cache e baixado e executado por um fluxo de trabalho mais privilegiado, ele será capaz de comprometer também esse fluxo de trabalho.
pageGH Actions - Cache PoisoningEnvenenamento de Artefato
Os fluxos de trabalho podem usar artefatos de outros fluxos de trabalho e até mesmo de repositórios, se um atacante conseguir comprometer a Ação do Github que faz upload de um artefato que é posteriormente usado por outro fluxo de trabalho, ele poderá comprometer os outros fluxos de trabalho:
pageGh Actions - Artifact PoisoningPós-Exploração de uma Ação
Acessando AWS e GCP via OIDC
Verifique as seguintes páginas:
pageAWS - Federation AbusepageGCP - Federation AbuseAcessando segredos
Se você está injetando conteúdo em um script, é interessante saber como você pode acessar segredos:
Se o segredo ou token estiver definido como uma variável de ambiente, ele pode ser acessado diretamente através do ambiente usando
printenv
.
Se o segredo é usado diretamente em uma expressão, o script shell gerado é armazenado no disco e é acessível.
cat /home/runner/work/_temp/*
Para uma ação personalizada, o risco pode variar dependendo de como um programa está usando o segredo obtido do argumento:
Abusando de runners auto-hospedados
A maneira de descobrir quais Ações do Github estão sendo executadas em infraestrutura não-Github é procurar por runs-on: self-hosted
na configuração yaml da Ação do Github.
Os runners auto-hospedados podem ter acesso a informações extra sensíveis, a outros sistemas de rede (pontos finais 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.
Nos runners auto-hospedados, também é possível obter os segredos do processo _Runner.Listener que conterá todos os segredos dos fluxos de trabalho em qualquer etapa ao despejar sua memória:
Verifique este post para mais informações.
Registro de Imagens Docker do Github
É possível criar ações no Github que irão construir e armazenar uma imagem Docker dentro do Github. Um exemplo pode ser encontrado no seguinte trecho expansível:
Última actualización