Translated ['src/pentesting-ci-cd/github-security/abusing-github-actions

This commit is contained in:
Translator
2025-06-25 00:23:09 +00:00
parent 232fbc1be2
commit 049cde49ae
2 changed files with 71 additions and 30 deletions

BIN
src/images/CH_logo_ads.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -2,6 +2,16 @@
{{#include ../../../banners/hacktricks-training.md}}
## Ferramentas
As seguintes ferramentas são úteis para encontrar fluxos de trabalho do Github Action e até mesmo encontrar aqueles vulneráveis:
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Confira também sua lista de verificação em [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
## Informações Básicas
Nesta página você encontrará:
@@ -9,9 +19,9 @@ Nesta página você encontrará:
- Um **resumo de todos os impactos** de um atacante conseguindo acessar um Github Action
- Diferentes maneiras de **obter acesso a uma ação**:
- Ter **permissões** para criar a ação
- Abusar de gatilhos relacionados a **pull request**
- Abusar de **gatilhos** relacionados a pull requests
- Abusar de **outras técnicas de acesso externo**
- **Pivotar** a partir de um repositório já comprometido
- **Pivotar** de um repositório já comprometido
- Finalmente, uma seção sobre **técnicas de pós-exploração para abusar de uma ação de dentro** (causando os impactos mencionados)
## Resumo dos Impactos
@@ -153,7 +163,7 @@ Caso membros de uma organização possam **criar novos repositórios** e você p
Se você puder **criar um novo branch em um repositório que já contém uma Ação do Github** configurada, você pode **modificá-la**, **carregar** o conteúdo e então **executar essa ação a partir do novo branch**. Dessa forma, você pode **exfiltrar segredos em 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 discreto você deseja ser):
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):
```yaml
on:
workflow_dispatch: # Launch manually
@@ -170,11 +180,11 @@ branches:
## Execução Forked
> [!NOTE]
> Existem diferentes gatilhos que poderiam permitir a um atacante **executar uma Github Action de outro repositório**. Se essas ações acionáveis forem mal configuradas, um atacante poderá comprometer elas.
> Existem diferentes gatilhos que podem permitir que um atacante **execute uma Github Action de outro repositório**. Se essas ações acionáveis forem mal configuradas, um atacante poderá comprometê-las.
### `pull_request`
O gatilho de 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:
O gatilho de 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:
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
@@ -192,7 +202,7 @@ Um atacante poderia modificar a definição da Github Action para executar coisa
> [!CAUTION]
> **Sim, se o atacante mudar no PR a github action que será acionada, sua Github Action será a utilizada 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 escrita no `GITHUB_TOKEN`, um atacante poderia, por exemplo, **carregar artefatos maliciosos**.
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, **fazer upload de artefatos maliciosos**.
### **`pull_request_target`**
@@ -207,7 +217,7 @@ E este terá **acesso a segredos**.
### `workflow_run`
O gatilho [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permite executar um workflow a partir de outro quando está `completo`, `solicitado` ou `em_andamento`.
O gatilho [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permite executar um workflow a partir de outro quando está `completo`, `solicitado` ou `em progresso`.
Neste exemplo, um workflow é configurado para ser executado após a conclusão do workflow separado "Executar Testes":
```yaml
@@ -217,9 +227,9 @@ workflows: [Run Tests]
types:
- completed
```
Além disso, de acordo com a documentação: O fluxo de trabalho iniciado pelo evento `workflow_run` é capaz de **acessar segredos e escrever tokens, mesmo que o fluxo de trabalho anterior não tenha sido**.
Além disso, de acordo com a documentação: O fluxo de trabalho iniciado pelo evento `workflow_run` é capaz de **acessar segredos e escrever tokens, mesmo que o fluxo de trabalho anterior não tenha**.
Esse tipo de fluxo de trabalho pode ser atacado se **depender** de um **fluxo de trabalho** que pode ser **ativado** por um usuário externo via **`pull_request`** ou **`pull_request_target`**. Alguns exemplos vulneráveis podem ser [**encontrados neste blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** O primeiro consiste no fluxo de trabalho ativado por **`workflow_run`** baixando o código do atacante: `${{ github.event.pull_request.head.sha }}`\
Esse tipo de fluxo de trabalho pode ser atacado se **depender** de um **fluxo de trabalho** 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**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** O primeiro consiste no fluxo de trabalho acionado por **`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 desse artefato de uma maneira que o torne **vulnerável a RCE**.
### `workflow_call`
@@ -230,18 +240,18 @@ TODO: Verificar se, quando executado a partir de um pull_request, o código usad
## Abusando da Execução Bifurcada
Mencionamos todas as maneiras que um atacante externo poderia conseguir fazer um fluxo de trabalho do github ser executado, agora vamos dar uma olhada em como essas execuções, se mal configuradas, poderiam ser abusadas:
Mencionamos todas as maneiras que um atacante externo poderia conseguir fazer um fluxo de trabalho do github executar, agora vamos dar uma olhada em 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** (então executará o **código malicioso do PR**), mas alguém precisa **autorizá-lo primeiro** e ele será executado com algumas [limitações](#pull_request).
No caso de um fluxo de trabalho usando **`pull_request_target` ou `workflow_run`** que depende de um fluxo de trabalho que pode ser ativado 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 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**.
> [!CAUTION]
> No entanto, se a **ação** tiver um **checkout de PR explícito** que irá **obter o código do PR** (e não da base), ele usará o código controlado pelo atacante. Por exemplo (ver linha 12 onde o código do PR é baixado):
> No entanto, se a **ação** tiver um **checkout de PR explícito** que **obterá o código do PR** (e não da base), usará o código controlado pelos atacantes. Por exemplo (ver linha 12 onde o código do PR é baixado):
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Fornecido apenas como um exemplo.
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Fornecido apenas como exemplo.
on:
pull_request_target
@@ -286,19 +296,59 @@ gh-actions-context-script-injections.md
De acordo com a documentação: Você pode tornar uma **variável de ambiente disponível para quaisquer etapas subsequentes** em um job de fluxo de trabalho 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 **env**, ele poderá injetar variáveis de ambiente que poderiam executar código nas etapas seguintes, como **LD_PRELOAD** ou **NODE_OPTIONS**.
Se um atacante puder **injetar qualquer valor** dentro dessa **variável env**, ele poderá injetar variáveis de ambiente que poderiam executar código nas etapas seguintes, como **LD_PRELOAD** ou **NODE_OPTIONS**.
Por exemplo ([**isso**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) e [**isso**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine um fluxo de trabalho 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:
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Dependabot e outros bots confiáveis
Conforme indicado em [**este post do blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), várias organizações têm uma Ação do Github que mescla qualquer PRR do `dependabot[bot]`, como em:
```yaml
on: pull_request_target
jobs:
auto-merge:
runs-on: ubuntu-latest
if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: gh pr merge $ -d -m
```
Qual é um problema porque o campo `github.actor` contém o usuário que causou o último evento que acionou o fluxo de trabalho. E há várias maneiras de fazer o usuário `dependabot[bot]` modificar um PR. Por exemplo:
- Fork o repositório da vítima
- Adicione o payload malicioso à sua cópia
- Ative o Dependabot no seu fork adicionando uma dependência desatualizada. O Dependabot criará um branch corrigindo a dependência com código malicioso.
- Abra um Pull Request para o repositório da vítima a partir desse branch (o PR será criado pelo usuário, então nada acontecerá ainda)
- Então, o atacante volta para o PR inicial que o Dependabot abriu em seu fork e executa `@dependabot recreate`
- Então, o Dependabot realiza algumas ações nesse branch, que modificaram o PR sobre o repositório da vítima, o que faz com que `dependabot[bot]` seja o ator do último evento que acionou o fluxo de trabalho (e, portanto, o fluxo de trabalho é executado).
Seguindo em frente, e se em vez de mesclar, a Github Action tivesse uma injeção de comando como em:
```yaml
on: pull_request_target
jobs:
just-printing-stuff:
runs-on: ubuntu-latest
if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
Bem, o post original do blog propõe duas opções para abusar desse comportamento, sendo a segunda:
- Fork o repositório da vítima e ative o Dependabot com alguma dependência desatualizada.
- Crie uma nova branch com o código de injeção de shell malicioso.
- Altere a branch padrão do repositório para essa.
- Crie um PR a partir dessa branch para o repositório da vítima.
- Execute `@dependabot merge` no PR que o Dependabot abriu em seu fork.
- O Dependabot irá mesclar suas alterações na branch padrão do seu repositório forkado, atualizando o PR no repositório da vítima, fazendo agora com que o `dependabot[bot]` seja o ator do último evento que acionou o fluxo de trabalho e usando um nome de branch malicioso.
### Ações do Github de Terceiros Vulneráveis
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
Como mencionado em [**este post do blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), 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 sobrescrever arquivos que poderiam ser usados 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.
O problema é que se o parâmetro **`path`** não estiver definido, o artefato é extraído no diretório atual e pode sobrescrever arquivos que poderiam ser usados ou até 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:
```yaml
@@ -344,7 +394,7 @@ path: ./script.py
### Sequestro de Repositório de Namespace Deletado
Se uma conta mudar 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** do que foi deletado.
Se uma conta mudar 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** do que foi deletado.
> [!CAUTION]
> Portanto, se uma ação estiver usando um repositório de uma conta inexistente, ainda é possível que um atacante crie essa conta e comprometa a ação.
@@ -360,7 +410,7 @@ Se outros repositórios estavam usando **dependências desses repositórios de u
### Envenenamento de Cache
Um cache é mantido entre **execuções de workflow na mesma 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 poderá também **comprometer** esse workflow.
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 poderá **comprometer** também esse workflow.
{{#ref}}
gh-actions-cache-poisoning.md
@@ -468,7 +518,7 @@ key: ${{ secrets.PUBLISH_KEY }}
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.
Runners **auto-hospedados** podem ter acesso a **informações extra sensíveis**, a outros **sistemas de rede** (pontos 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.
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 pode **roubar os segredos** da outra.
Em 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, despejando sua memória:
```bash
@@ -530,24 +580,15 @@ https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forens
### Informações sensíveis nos logs do Github Actions
Mesmo que o **Github** tente **detectar valores secretos** nos logs das ações e **evitar mostrá-los**, **outros dados sensíveis** que podem ter sido gerados na execução da ação não serão ocultados. Por exemplo, um JWT assinado com um valor secreto não será ocultado, a menos que seja [especificamente configurado](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
Mesmo que o **Github** tente **detectar valores secretos** nos logs das ações e **evitar mostrá-los**, **outros dados sensíveis** que podem ter sido gerados na execução da ação não serão ocultados. Por exemplo, um JWT assinado com um valor secreto não será ocultado a menos que seja [especificamente configurado](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
## Cobertura de suas Pegadas
## Cobrir suas Trilhas
(Técnica de [**aqui**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primeiro de tudo, qualquer PR levantada é claramente visível ao público no Github e à conta alvo do GitHub. No GitHub, por padrão, **não podemos deletar um PR da internet**, mas há uma reviravolta. Para contas do Github que estão **suspensas** pelo Github, todos os seus **PRs são automaticamente deletados** e removidos da internet. Portanto, para ocultar sua atividade, você precisa ou ter sua **conta do GitHub suspensa ou ter sua conta sinalizada**. Isso **ocultaria todas as suas atividades** no GitHub da internet (basicamente remover todos os seus PRs de exploração)
(Técnica de [**aqui**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primeiro de tudo, qualquer PR levantada é claramente visível ao público no Github e à conta alvo do GitHub. No GitHub, por padrão, **não podemos deletar um PR da internet**, mas há uma reviravolta. Para contas do Github que estão **suspensas** pelo Github, todos os seus **PRs são automaticamente deletados** e removidos da internet. Portanto, para esconder sua atividade, você precisa ou ter sua **conta do GitHub suspensa ou ter sua conta sinalizada**. Isso **esconderá todas as suas atividades** no GitHub da internet (basicamente remove todos os seus PRs de exploração).
Uma organização no GitHub é muito proativa em relatar contas ao GitHub. Tudo o que você precisa fazer é compartilhar “algumas coisas” em uma Issue e eles garantirão que sua conta seja suspensa em 12 horas :p e aí está, fez sua exploração invisível no github.
> [!WARNING]
> A única maneira de uma organização descobrir que foi alvo é verificar os logs do GitHub a partir do SIEM, pois na interface do GitHub o PR seria removido.
## Ferramentas
As seguintes ferramentas são úteis para encontrar fluxos de trabalho do Github Action e até mesmo encontrar os vulneráveis:
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
{{#include ../../../banners/hacktricks-training.md}}