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

This commit is contained in:
Translator
2025-06-25 00:23:26 +00:00
parent 60303d7c79
commit 324e6800ba
2 changed files with 80 additions and 39 deletions

View File

@@ -2,15 +2,25 @@
{{#include ../../../banners/hacktricks-training.md}}
## Outils
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)
- [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) - Vérifiez également sa liste de contrôle à [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
## Informations de base
Dans cette page, vous trouverez :
Sur cette page, vous trouverez :
- Un **résumé de tous les impacts** d'un attaquant parvenant à accéder à une Github Action
- Différentes manières de **accéder à une 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 requests**
- Abuser d'autres techniques d'accès **externe**
- Abuser d'autres techniques d'**accès externe**
- **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)
@@ -39,7 +49,7 @@ Ce token est le même qu'une **application Github utilisera**, donc il peut acc
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)
Notez que le token **expire après la fin du travail**.\
Notez que le token **expire après la fin du job**.\
Ces tokens ressemblent à ceci : `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Quelques choses intéressantes que vous pouvez faire avec ce token :
@@ -147,7 +157,7 @@ Il est possible de vérifier les permissions accordées à un Github Token dans
### Exécution depuis la Création de Dépôt
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**.
Dans le cas où des 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**.
### Exécution depuis une Nouvelle Branche
@@ -170,7 +180,7 @@ branches:
## Exécution Forkée
> [!NOTE]
> 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.
> Il existe différents déclencheurs qui pourraient permettre à un attaquant d'**exécuter une Github Action 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`
@@ -179,7 +189,7 @@ Le déclencheur de workflow **`pull_request`** exécutera le workflow chaque foi
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> 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`**.
> 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`**.
>
> **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.~~
@@ -187,10 +197,10 @@ De plus, par défaut, cela **empêche les permissions d'écriture** et **l'accè
> À 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**.
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.
Un attaquant pourrait modifier la définition de la Github Action 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]
> **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 !**
> **Oui, si l'attaquant change dans la PR l'action github qui sera déclenchée, son Github Action sera celle utilisée et non celle du dépôt d'origine !**
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**.
@@ -234,12 +244,12 @@ Nous avons mentionné toutes les façons dont un attaquant externe pourrait réu
### Exécution de checkout non fiable
Dans le cas de **`pull_request`,** le workflow sera exécuté dans le **contexte de la PR** (il exécutera donc le **code malveillant de la PR**), mais quelqu'un doit d'abord **l'autoriser** et il s'exécutera avec certaines [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 d'abord **l'autoriser** et il s'exécutera avec certaines [limitations](#pull_request).
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 d'origine sera exécuté, donc l'**attaquant ne peut pas contrôler le code exécuté**.
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]
> Cependant, si l'**action** a un **checkout explicite de la PR** qui **récupère 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é) :
> Cependant, si l'**action** a un **checkout PR explicite** qui **récupère 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:
@@ -272,7 +282,7 @@ Thank you!
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]
> 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).
> Un dork github pour rechercher des actions vulnérables est : `event.pull_request pull_request_target extension:yml` cependant, il existe différentes manières 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).
### Injections de scripts de contexte <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
@@ -286,19 +296,59 @@ gh-actions-context-script-injections.md
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`**.
Si un attaquant pouvait **injecter n'importe quelle valeur** dans 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**.
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**.
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 dans la variable d'environnement **`GITHUB_ENV`**. Un attaquant pourrait télécharger quelque chose comme ceci pour le compromettre :
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>
### Dependabot et autres bots de confiance
Comme indiqué dans [**cet article de blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), plusieurs organisations ont une action Github qui fusionne toute PRR de `dependabot[bot]` comme dans :
```yaml
on: pull_request_target
jobs:
auto-merge:
runs-on: ubuntu-latest
if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: gh pr merge $ -d -m
```
Ce qui pose un problème car le champ `github.actor` contient l'utilisateur qui a causé le dernier événement ayant déclenché le workflow. Et il existe plusieurs façons de faire en sorte que l'utilisateur `dependabot[bot]` modifie une PR. Par exemple :
- Forker le dépôt de la victime
- Ajouter le payload malveillant à votre copie
- Activer Dependabot sur votre fork en ajoutant une dépendance obsolète. Dependabot créera une branche corrigeant la dépendance avec du code malveillant.
- Ouvrir une Pull Request vers le dépôt de la victime depuis cette branche (la PR sera créée par l'utilisateur donc rien ne se passera encore)
- Ensuite, l'attaquant revient à la PR initiale que Dependabot a ouverte dans son fork et exécute `@dependabot recreate`
- Ensuite, Dependabot effectue certaines actions dans cette branche, qui modifient la PR sur le dépôt de la victime, ce qui fait de `dependabot[bot]` l'acteur du dernier événement ayant déclenché le workflow (et donc, le workflow s'exécute).
Passons à autre chose, que se passerait-il si au lieu de fusionner, l'Action Github avait une injection de commande comme dans :
```yaml
on: pull_request_target
jobs:
just-printing-stuff:
runs-on: ubuntu-latest
if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
Bien, le blog original propose deux options pour abuser de ce comportement, la deuxième étant :
- Forker le dépôt de la victime et activer Dependabot avec une dépendance obsolète.
- Créer une nouvelle branche avec le code d'injection de shell malveillant.
- Changer la branche par défaut du dépôt pour celle-ci.
- Créer une PR à partir de cette branche vers le dépôt de la victime.
- Exécuter `@dependabot merge` dans la PR que Dependabot a ouverte dans son fork.
- Dependabot fusionnera ses modifications dans la branche par défaut de votre dépôt forké, mettant à jour la PR dans le dépôt de la victime, faisant maintenant de `dependabot[bot]` l'acteur du dernier événement qui a déclenché le workflow et utilisant un nom de branche malveillant.
### Actions Github tierces vulnérables
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
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.
Comme mentionné dans [**ce blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), cette Action Github permet d'accéder à des artefacts provenant de différents workflows et même de dépôts.
Le problème est que si le paramètre **`path`** n'est pas défini, l'artifact est extrait dans le répertoire courant 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.
Le problème est que si le paramètre **`path`** n'est pas défini, l'artefact est extrait dans le répertoire courant et peut écraser des fichiers qui pourraient être utilisés ou même exécutés dans le workflow. Par conséquent, si l'artefact est vulnérable, un attaquant pourrait en abuser pour compromettre d'autres workflows faisant confiance à l'artefact.
Exemple de workflow vulnérable :
```yaml
@@ -358,7 +408,7 @@ Si d'autres dépôts utilisaient **des dépendances de ces dépôts utilisateurs
> [!NOTE]
> 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).
### Poisoning de Cache
### Empoisonnement de Cache
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.
@@ -366,9 +416,9 @@ Un cache est maintenu entre **les exécutions de workflow dans la même branche*
gh-actions-cache-poisoning.md
{{#endref}}
### Poisoning d'Artifact
### Empoisonnement d'Artifact
Les workflows pourraient utiliser **des artifacts d'autres workflows et même 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** :
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
@@ -466,9 +516,9 @@ key: ${{ secrets.PUBLISH_KEY }}
### Abus des runners auto-hébergés
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.
La manière 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.
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 l'action malveillante pourrait **voler les secrets** de l'autre.
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'ils sont isolés et détruits, **plus d'une action peut être exécutée en même temps** et l'action 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
@@ -479,12 +529,12 @@ Vérifiez [**ce post pour plus d'informations**](https://karimrahal.com/2023/01/
### Registre d'images Docker Github
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 :
Il est possible de créer des actions Github qui **construisent et stockent une image Docker à l'intérieur de Github**.\
Un exemple peut être trouvé dans le suivant extensible :
<details>
<summary>Github Action Build & Push Docker Image</summary>
<summary>Action Github Construire & Pousser l'image Docker</summary>
```yaml
[...]
@@ -522,32 +572,23 @@ Un utilisateur ayant des permissions de lecture sur le dépôt pourra alors tél
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
```
Ensuite, l'utilisateur pourrait rechercher des **secrets divulgués dans les couches d'image Docker :**
Alors, l'utilisateur pourrait rechercher des **secrets divulgués dans les couches d'image Docker :**
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### Informations sensibles dans les journaux de Github Actions
### Informations sensibles dans les journaux des actions Github
Même si **Github** essaie de **détecter les valeurs secrètes** dans les journaux d'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).
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).
## Couvrir vos traces
(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 flaguer votre compte**. Cela **cacherait toutes vos activités** sur GitHub d'internet (en gros, retirer toutes vos PR d'exploitation)
(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. Dans GitHub par défaut, nous **ne pouvons pas supprimer une PR de l'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 de l'internet. Donc, pour cacher votre activité, vous devez soit faire **suspendre votre compte GitHub ou faire flaguer votre compte**. Cela **cacherait toutes vos activités** sur GitHub de l'internet (en gros, supprimer toutes vos PR d'exploitation)
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]
> 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.
## Outils
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)
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
> La seule façon pour une organisation de découvrir 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.
{{#include ../../../banners/hacktricks-training.md}}