Abusing Github Actions
Informations de base
Sur cette page, vous trouverez :
Un résumé de tous les impacts d'un attaquant parvenant à accéder à une Github Action
Différentes façons d'accéder à une action :
Avoir des permissions pour créer l'action
Abuser des déclencheurs liés aux pull request
Abuser d'autres techniques d'accès externes
Pivoter à partir d'un dépôt déjà compromis
Enfin, une section sur les techniques post-exploitation pour abuser d'une action de l'intérieur (causant les impacts mentionnés)
Résumé des impacts
Pour une introduction sur Github Actions, consultez les informations de base.
Dans le cas où vous pouvez exécuter des actions Github arbitraires/injecter du code dans un dépôt, vous pourriez être capable de :
Voler les secrets de ce dépôt/organisation.
Si vous ne pouvez qu'injecter, vous pouvez voler tout ce qui est déjà présent dans le workflow.
Abuser des privilèges du dépôt pour accéder à d'autres plateformes telles que AWS et GCP.
Exécuter du code dans des workers personnalisés (si des workers personnalisés sont utilisés) et essayer de pivoter à partir de là.
Écraser le code du dépôt.
Cela dépend des privilèges du
GITHUB_TOKEN
(le cas échéant).Compromettre les déploiements et autres artifacts.
Si le code déploie ou stocke quelque chose, vous pourriez le modifier et obtenir un accès supplémentaire.
GITHUB_TOKEN
Ce "secret" (provenant de ${{ secrets.GITHUB_TOKEN }}
et ${{ github.token }}
) est donné lorsque l'administrateur active cette option :
Ce token est le même qu'une application Github utilisera, donc il peut accéder aux mêmes endpoints : https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Github devrait publier un flux qui permet l'accès inter-dépôts au sein de GitHub, afin qu'un dépôt puisse accéder à d'autres dépôts 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
Notez que le token expire après la fin du job.
Ces tokens ressemblent à ceci : ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7
Quelques choses intéressantes que vous pouvez faire avec ce token :
Notez que dans plusieurs occasions, vous pourrez trouver des tokens d'utilisateur github à l'intérieur des environnements Github Actions ou dans les secrets. Ces tokens peuvent vous donner plus de privilèges sur le dépôt et l'organisation.
Il est possible de vérifier les permissions données à un Github Token dans les dépôts d'autres utilisateurs en vérifiant les logs des actions :
Exécution Autorisée
Ce serait le moyen le plus simple de compromettre les actions Github, car ce cas suppose que vous avez accès à créer un nouveau dépôt dans l'organisation, ou avez des privilèges d'écriture sur un dépôt.
Si vous êtes dans ce scénario, vous pouvez simplement consulter les techniques de post-exploitation.
Exécution à partir de la Création d'un Dépôt
Dans le cas où les membres d'une organisation peuvent créer de nouveaux dépôts et que vous pouvez exécuter des actions github, vous pouvez créer un nouveau dépôt et voler les secrets définis au niveau de l'organisation.
Exécution à partir d'une Nouvelle Branche
Si vous pouvez créer une nouvelle branche dans un dépôt qui contient déjà une Github Action configurée, vous pouvez la modifier, téléverser le contenu, puis exécuter cette action à partir de la nouvelle branche. De cette façon, vous pouvez exfiltrer les secrets au niveau du dépôt et de l'organisation (mais vous devez savoir comment ils sont appelés).
Vous pouvez rendre l'action modifiée exécutable manuellement, lorsqu'une PR est créée ou lorsque du code est poussé (en fonction de la discrétion souhaitée) :
Exécution Forkée
Il existe différents déclencheurs qui pourraient permettre à un attaquant d'exécuter une Github Action d'un autre dépôt. Si ces actions déclenchables sont mal configurées, un attaquant pourrait être en mesure de les compromettre.
pull_request
pull_request
Le déclencheur de workflow 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 mainteneur devra approuver l'exécution du workflow :
Comme la limitation par défaut concerne les contributeurs de 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
.
J'ai testé cela et ça ne fonctionne pas : Une autre option serait de créer un compte avec le nom de quelqu'un qui a contribué au projet et supprimé son compte.
De plus, par défaut, empêche les permissions d'écriture et l'accès aux secrets du dépôt cible comme mentionné dans les docs :
À l'exception de
GITHUB_TOKEN
, les secrets ne sont pas transmis au runner lorsqu'un workflow est déclenché à partir d'un dépôt forké. LeGITHUB_TOKEN
a des permissions en lecture seule dans les pull requests provenant 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 des secrets ou écraser le dépôt en raison des limitations mentionnées.
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 dépôt d'origine !
Comme l'attaquant contrôle également le code exécuté, même s'il n'y a pas de secrets ou de permissions d'écriture sur le GITHUB_TOKEN
, un attaquant pourrait par exemple télécharger des artefacts malveillants.
pull_request_target
pull_request_target
Le déclencheur de workflow pull_request_target
a des permissions d'écriture sur le dépôt cible et accès aux secrets (et ne demande pas de permission).
Notez que le déclencheur de workflow pull_request_target
s'exécute dans le contexte de base et non dans celui donné par la PR (pour ne pas exécuter de code non fiable). Pour plus d'informations sur pull_request_target
, consultez les docs.
De plus, pour plus d'informations sur cette utilisation spécifique dangereuse, consultez ce post de blog github.
Il pourrait sembler que parce que le workflow exécuté est celui défini dans la base et non dans la PR, il est sécurisé 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.
workflow_run
workflow_run
Le déclencheur workflow_run permet d'exécuter un workflow à partir d'un autre lorsqu'il est completed
, requested
ou in_progress
.
Dans cet exemple, un workflow est configuré pour s'exécuter après que le workflow séparé "Run Tests" soit terminé :
De plus, selon la documentation : Le workflow démarré par l'événement workflow_run
est capable d'accéder aux secrets et d'écrire des tokens, même si le workflow précédent ne l'était pas.
Ce type de workflow pourrait être attaqué s'il dépend d'un workflow qui peut être déclenché par un utilisateur externe via pull_request
ou pull_request_target
. Quelques exemples vulnérables peuvent être trouvés dans ce blog. Le premier consiste en un workflow déclenché par workflow_run
téléchargeant le code de l'attaquant : ${{ github.event.pull_request.head.sha }}
Le second consiste à passer un artifact du code non fiable au workflow workflow_run
et à utiliser le contenu de cet artifact d'une manière qui le rend vulnérable à RCE.
workflow_call
workflow_call
TODO
TODO : Vérifier si, lorsqu'il est exécuté à partir d'un pull_request, le code utilisé/téléchargé provient de l'origine ou du PR forké
Abuser de l'exécution forkée
Nous avons mentionné toutes les façons dont un attaquant externe pourrait réussir à faire exécuter un workflow github, maintenant examinons comment ces exécutions, si mal configurées, pourraient être abusées :
Exécution de checkout non fiable
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.
Dans le cas d'un workflow utilisant pull_request_target
ou workflow_run
qui dépend d'un workflow pouvant être déclenché à partir de pull_request_target
ou pull_request
, le code du dépôt original sera exécuté, donc l'attaquant ne peut pas contrôler le code exécuté.
Cependant, si l'action a un checkout PR explicite qui obtiendra le code du PR (et non de la base), elle utilisera le code contrôlé par l'attaquant. Par exemple (voir la ligne 12 où le code du PR est téléchargé) :
Le code potentiellement non fiable 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.
Un github dork pour rechercher des actions vulnérables est : event.pull_request pull_request_target extension:yml
cependant, il existe différentes façons de configurer les jobs pour qu'ils soient exécutés en toute sécurité même si l'action est configurée de manière non sécurisée (comme utiliser des conditionnels sur qui est l'acteur générant le PR).
Injections de script de contexte
Notez qu'il existe certains contextes github 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 :
Gh Actions - Context Script InjectionsInjection de script GITHUB_ENV
D'après la documentation : Vous pouvez rendre une variable d'environnement disponible pour toutes les étapes suivantes dans un job de workflow en définissant ou en mettant à jour la variable d'environnement et en l'écrivant dans le fichier d'environnement GITHUB_ENV
.
Si un attaquant pouvait injecter une valeur quelconque dans cette variable env, il pourrait injecter des variables env qui pourraient exécuter du code dans les étapes suivantes telles que LD_PRELOAD ou NODE_OPTIONS.
Par exemple (ceci et ceci), imaginez un workflow qui fait confiance à un artifact téléchargé pour stocker son contenu dans la variable env GITHUB_ENV
. Un attaquant pourrait télécharger quelque chose comme ceci pour le compromettre :
Actions Github tierces vulnérables
Comme mentionné dans ce post de blog, cette action Github permet d'accéder aux artifacts de différents workflows et même de dépôts.
Le problème est que si le paramètre path
n'est pas défini, l'artifact est extrait dans le répertoire actuel et il peut remplacer des fichiers qui pourraient être utilisés ou même exécutés plus tard dans le workflow. Par conséquent, si l'Artifact est vulnérable, un attaquant pourrait en abuser pour compromettre d'autres workflows faisant confiance à l'Artifact.
Exemple de workflow vulnérable :
Cela pourrait être attaqué avec ce workflow :
Autre Accès Externe
Détournement de Répertoire de Namespace Supprimé
Si un compte change de nom, un autre utilisateur pourrait enregistrer un compte avec ce nom après un certain temps. Si un dépôt avait moins de 100 étoiles avant le changement de nom, Github permettra au nouvel utilisateur enregistré avec le même nom de créer un dépôt avec le même nom que celui supprimé.
Donc, si une action utilise un dépôt d'un compte inexistant, il est toujours possible qu'un attaquant puisse créer ce compte et compromettre l'action.
Si d'autres dépôts utilisaient des dépendances de ce dépôt utilisateur, un attaquant pourra les détourner. Voici une explication plus complète : https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/
Pivotement de Dépôt
Dans cette section, nous parlerons des techniques qui permettraient de pivoter d'un dépôt à un autre en supposant que nous ayons un certain type d'accès au premier (voir la section précédente).
Empoisonnement du Cache
Un cache est maintenu entre les exécutions de workflow dans la même branche. Ce qui signifie que si un attaquant compromet un package qui est ensuite stocké dans le cache et téléchargé et exécuté par un workflow plus privilégié, il pourra également compromettre ce workflow.
GH Actions - Cache PoisoningEmpoisonnement d'Artifact
Les workflows peuvent utiliser des artifacts d'autres workflows et même de dépôts, si un attaquant parvient à compromettre l'Action Github qui télécharge un artifact qui est ensuite utilisé par un autre workflow, il pourrait compromettre les autres workflows :
Gh Actions - Artifact PoisoningPost Exploitation à partir d'une Action
Accès à AWS et GCP via OIDC
Consultez les pages suivantes :
AWS - Federation AbuseGCP - Federation AbuseAccès 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 comme une variable d'environnement, il peut être directement accessible via l'environnement en utilisant
printenv
.
Si le secret est utilisé directement dans une expression, le script shell généré est stocké sur le disque et est accessible.
cat /home/runner/work/_temp/*
Pour une custom action, le risque peut varier en fonction de la manière dont un programme utilise le secret obtenu à partir de l'argument :
Abuser des Self-hosted runners
La façon de trouver quelles Github Actions sont exécutées dans une infrastructure non-github est de rechercher runs-on: self-hosted
dans le fichier de configuration yaml de Github Action.
Les runners self-hosted peuvent avoir accès à des informations extrêmement sensibles, à d'autres systèmes réseau (points de terminaison vulnérables dans le réseau ? service de métadonnées ?) ou, même s'ils sont isolés et détruits, plus d'une action peut être exécutée en même temps et l'action malveillante pourrait voler les secrets de l'autre.
Dans les runners self-hosted, il est également possible d'obtenir les secrets du processus _Runner.Listener** qui contiendra tous les secrets des workflows à n'importe quelle étape en vidant sa mémoire :
Consultez cet article pour plus d'informations.
Registre d'Images Docker Github
Il est possible de créer des actions Github qui construiront et stockeront une image Docker à l'intérieur de Github. Un exemple peut être trouvé dans l'extension suivante :
Last updated