diff --git a/src/pentesting-ci-cd/argocd-security.md b/src/pentesting-ci-cd/argocd-security.md new file mode 100644 index 000000000..ba2c46aa4 --- /dev/null +++ b/src/pentesting-ci-cd/argocd-security.md @@ -0,0 +1,219 @@ +# Argo CD Security + +{{#include ../banners/hacktricks-training.md}} + +## Informations de base + +[Argo CD](https://argo-cd.readthedocs.io/) est une plateforme de continuous delivery GitOps pour Kubernetes. Elle surveille les dépôts Git, rend les manifests Kubernetes avec des outils tels que Helm, Kustomize, Jsonnet ou des plugins de configuration management, et réconcilie l'état réel du cluster avec l'état souhaité stocké dans Git. + +Du point de vue d'un attacker, considérez Argo CD comme un **deployment engine avec des credentials Kubernetes**. Une compromission utile d'Argo CD peut conduire à : + +- Accès à des dépôts Git privés et aux credentials des dépôts. +- Accès aux secrets du cluster Kubernetes utilisés par Argo CD. +- Exécution de code lors de la génération de manifests dans `argocd-repo-server`. +- Déploiement non autorisé d'objets Kubernetes via des dépôts Git de confiance, des applications Argo CD ou la manipulation du cache. + +## Architecture & Composants intéressants + +Objets et services Kubernetes courants : +```bash +kubectl get pods,svc,endpoints,ingress -A | grep -iE 'argocd|argo-cd' +kubectl get applications,appprojects,applicationsets -A 2>/dev/null +kubectl get secrets,configmaps -n argocd 2>/dev/null +kubectl get networkpolicy -n argocd 2>/dev/null +``` +Services intéressants : + +- **`argocd-server`** : API publique, interface web, API CLI, authentification et authorization. +- **`argocd-application-controller`** : compare l’état souhaité et l’état live, puis applique les resources à Kubernetes. +- **`argocd-repo-server`** : clone les repositories, met en cache les données Git, et exécute Helm/Kustomize/Jsonnet/plugins pour générer les manifests. Le port gRPC par défaut est **8081**. +- **`argocd-redis`** : cache pour les données d’application, de manifest et de référence Git. Le port Redis par défaut est **6379**. +- **`argocd-applicationset-controller`** : génère des objets Argo CD `Application` à partir de generators tels que Git, SCM, clusters et pull requests. + +Depuis un pod compromis ou un segment réseau interne, vérifiez l’accessibilité interne : +```bash +nc -vz 443 +nc -vz 8081 +nc -vz 6379 +``` +## Public API / UI Attacks + +Si vous avez des credentials Argo CD ou une instance exposée, commencez par la surface API normale : +```bash +argocd login +argocd account get-user-info +argocd account list +argocd proj list +argocd app list +argocd repo list +argocd cluster list +argocd admin settings rbac can +``` +Chemins d’attaque utiles : + +- **Application write access** : modifier `source.repoURL`, `source.path`, les valeurs Helm, les options Kustomize, les paramètres du plugin ou les options de sync afin qu’Argo CD déploie des manifests contrôlés par l’attaquant. +- **Project misconfiguration** : les objets `AppProject` peuvent autoriser des `sourceRepos` trop larges, des `destinations` trop larges, un `clusterResourceWhitelist` non sûr, ou des restrictions de namespace trop faibles. +- **Repository credential abuse** : les secrets de repository, les identifiants GitHub App, les clés SSH et les tokens peuvent permettre de pousser vers des repos de confiance ou d’ajouter des dépendances malveillantes. +- **Cluster credential abuse** : les secrets de cluster peuvent contenir des bearer tokens ou une configuration exec-provider utilisée par Argo CD pour déployer vers les clusters cibles. +- **Local admin / project tokens** : des tokens Argo CD de longue durée peuvent être réutilisés via l’API tant qu’ils ne sont pas révoqués ou expirés. + +Énumérez la configuration depuis Kubernetes lorsque vous avez un accès en lecture au cluster : +```bash +kubectl get applications.argoproj.io -A -o yaml +kubectl get appprojects.argoproj.io -A -o yaml +kubectl get applicationsets.argoproj.io -A -o yaml +kubectl get secrets -n argocd -o yaml | grep -nE 'repoURL|sshPrivateKey|password|bearerToken|githubApp|tlsClientCertData|tlsClientCertKey' +kubectl get cm -n argocd argocd-cm argocd-rbac-cm argocd-cmd-params-cm -o yaml +``` +## Abuse de dépôt Git de confiance + +Si vous pouvez pousser vers un dépôt approuvé par Argo CD, vous pouvez généralement influencer ce qui est déployé. L’impact dépend des limites de `AppProject` et des permissions du service account utilisé par le application controller. + +Emplacements courants des payloads : + +- YAML Kubernetes brut sous un chemin de l’application. +- Templates de chart Helm et `values.yaml`. +- Overlays Kustomize, remote bases et generators. +- Jsonnet ou entrée de config management plugin. +- Fichiers generator ApplicationSet qui créent ou mettent à jour des objets `Application`. + +Vérifiez si l’application utilise automated sync, pruning, self-heal, sync windows ou des approbations manuelles : +```bash +kubectl get applications.argoproj.io -A \ +-o custom-columns='NS:.metadata.namespace,APP:.metadata.name,PROJECT:.spec.project,AUTOSYNC:.spec.syncPolicy.automated,REPO:.spec.source.repoURL,PATH:.spec.source.path,DEST:.spec.destination.server' +``` +## Abus direct de `argocd-repo-server` + +Ne supposez pas que l'API publique Argo CD est la seule surface d'attaque. Les composants internes d'Argo CD communiquent avec `argocd-repo-server` via gRPC. Si des pods arbitraires peuvent atteindre repo-server, des requêtes internes contrôlées par un attaquant peuvent contourner les vérifications normalement imposées par `argocd-server`. + +Vérifications pratiques: +```bash +kubectl get svc -n argocd argocd-repo-server -o yaml +kubectl get endpoints -n argocd argocd-repo-server -o wide +nc -vz 8081 +``` +Signes intéressants : + +- Le point de terminaison gRPC du repo-server est accessible depuis des pods non-Argo CD. +- Les NetworkPolicies sont absentes ou ne font que de l'allow-list egress sans deny ingress. +- Le repo-server a accès à des custom config management plugins, à des outils de déchiffrement, ou à du contenu de dépôt provenant de plusieurs tenants. +- Redis est accessible depuis des pods non-Argo CD, permettant l'inspection ou la modification du cache si des credentials sont disponibles ou non requis. + +## Unauthenticated Repo-Server RCE via Kustomize Options + +En juillet 2026, Synacktiv a divulgué une chaîne d'exécution de code non authentifiée dans `repo-server` d'Argo CD lorsqu'un attaquant peut atteindre le service gRPC interne. L'attaque abuse de l'accès direct à `/repository.RepoServerService/GenerateManifest` et de `KustomizeOptions` contrôlées par l'attaquant. + +La primitive dangereuse consiste à forcer repo-server à cloner du contenu de dépôt contrôlé par l'attaquant et à exécuter Kustomize avec le support Helm : +```bash +kustomize build --enable-helm --helm-command ./payload.sh +``` +Une entrée Kustomize malveillante minimale doit déclencher le traitement Helm : +```yaml +helmCharts: +- name: pwn +version: 0.0.1 +``` +Pourquoi cela fonctionne : + +- `argocd-repo-server` clone le dépôt avant le rendering. +- `--helm-command ./payload.sh` se résout relativement au dépôt cloné. +- L’exécution de code ne nécessite pas d’injection de métacaractères shell si l’attaquant peut contrôler le dépôt rendu et les options de build Kustomize. + +Au moment de la divulgation de Synacktiv le 1er juillet 2026, ils ont signalé que le problème n’avait pas de correctif officiel ni de CVE. Traitez cela d’abord comme un problème d’exposition réseau : l’exploitation nécessite un accès au port gRPC interne de repo-server. + +## Redis Cache Poisoning to Deploy Manifests + +Après une exécution de code dans `argocd-repo-server`, ou après un accès direct à Redis avec des identifiants valides, inspectez les entrées de cache stockées dans Redis. Argo CD stocke couramment des valeurs JSON compressées en gzip. + +Préfixes de clés intéressants : +```text +mfst|... # cached rendered manifests +git-refs|... # Git branch/ref to commit mappings +app|... # application resource/cache data +cluster|... # cluster cache information +``` +L’attaque de cache poisoning décrite par Synacktiv abuse de deux états : + +1. Modifier l’entrée de cache manifeste `mfst|...` pertinente pour inclure un manifest Kubernetes contrôlé par l’attaquant. +2. Modifier le mapping `git-refs|...` مرتبط pour qu’Argo CD pense que la branche a bougé, puis revienne à la révision mise en cache. + +Impact : + +- Avec Auto Sync activé, Argo CD peut appliquer automatiquement le manifest empoisonné en cache. +- Sans Auto Sync, le payload peut quand même s’appliquer lorsqu’un utilisateur sync manuellement l’application. +- L’impact final est limité par la destination de l’application cible et les permissions Kubernetes disponibles pour Argo CD. + +## ApplicationSet Attacks + +ApplicationSet est particulièrement sensible parce qu’il crée ou met à jour des objets `Application` à partir de la sortie du generator. + +Review: +```bash +kubectl get applicationsets.argoproj.io -A -o yaml +kubectl get appprojects.argoproj.io -A -o yaml +``` +Modèles intéressants : + +- Les générateurs git lisant des fichiers inscriptibles par l’attaquant qui contrôlent les noms d’app, les paths, les projects ou les destinations. +- Les générateurs de pull request pour les dépôts publics, où des contributeurs non fiables peuvent influencer les applications générées. +- Les champs de template qui autorisent des clusters/namespaces de destination larges. +- Les AppProjects qui autorisent `sourceRepos: ["*"]` ou des `destinations` larges. +- Les applications générées qui héritent de la synchronisation automatisée et de la suppression. + +## Post-Exploitation + +Depuis un shell de pod Argo CD, priorisez : +```bash +env +cat /proc/1/environ 2>/dev/null | tr '\0' '\n' +find /var/run/secrets /app/config -type f -maxdepth 4 2>/dev/null +mount | grep -E 'secret|token|config' +``` +Objectifs utiles : + +- Voler `REDIS_PASSWORD` ou le matériel Redis TLS/client. +- Extraire les credentials du repository depuis les secrets montés ou les secrets Kubernetes d'Argo CD. +- Identifier les credentials du cluster utilisés par Argo CD. +- Lire les manifests générés et la sortie des plugins qui peuvent contenir des secrets injectés. +- Vérifier si des custom plugins, SOPS, Helm secrets, Vault plugins ou des cloud CLIs exposent des keys de décryption et des cloud credentials. + +## Détection & Durcissement + +Vérifications importantes : + +- Restreindre le port **8081** de `argocd-repo-server` et le port **6379** de Redis avec des NetworkPolicies afin que seuls les composants Argo CD attendus puissent y accéder. +- Dans les déploiements Helm, vérifier que les network policies sont réellement créées. Les valeurs du chart Helm Argo CD ont historiquement laissé la création des network policies des composants désactivée par défaut. +- Garder `argocd-server` comme point d'entrée authentifié. Les services internes ne devraient pas être accessibles depuis des workloads arbitraires. +- Désactiver les outils de config management et plugins inutilisés. +- Restreindre `AppProject` `sourceRepos`, `destinations`, les permissions de namespace et les ressources au niveau cluster. +- Éviter de stocker des credentials de repository trop larges qu'un utilisateur Argo CD peu privilégié pourrait réutiliser. +- Surveiller les requêtes repo-server, les options de build Kustomize, les exécutions de plugins, les écritures Redis et les accès inattendus aux keys `mfst|` / `git-refs|`. +- Faire tourner les utilisateurs locaux Argo CD, les project tokens, les repository credentials et les cluster credentials après une compromission. + +Commandes utiles : +```bash +kubectl get networkpolicy -n argocd +kubectl get networkpolicy -A | grep -i argocd +kubectl describe networkpolicy -n argocd argocd-repo-server-network-policy 2>/dev/null +kubectl describe networkpolicy -n argocd argocd-redis-network-policy 2>/dev/null +``` +## Note d'analyse statique : Typed API Requests dans CodeQL + +Pour les services Go utilisant des handlers gRPC/REST, les remote sources CodeQL par défaut peuvent manquer des flows une fois que l'input brut a été unmarshaled en typed request objects. Un modèle utile pour des services de style Argo CD est : + +- Receiver type comme `Server` ou `Service`. +- Le premier paramètre est `context.Context`. +- Le deuxième paramètre est un typed request object. + +Modélisez ce deuxième paramètre comme une remote source et ajoutez des custom sinks pour les arguments de `exec.Command` / `exec.CommandContext`. Cela aide à trouver des flows depuis des champs de internal API request vers les command execution helpers. + +## Références + +- [Synacktiv - Caught in the Octopus Trap: Unauthenticated RCE in Argo CD with CodeQL](https://www.synacktiv.com/en/publications/caught-in-the-octopus-trap-unauthenticated-rce-in-argo-cd-with-codeql) +- [Argo CD docs - Security considerations](https://argo-cd.readthedocs.io/en/stable/operator-manual/security/) +- [Argo CD docs - High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/) +- [Argo CD docs - repo-server command reference](https://argo-cd.readthedocs.io/en/stable/operator-manual/server-commands/argocd-repo-server/) +- [Argo CD - repo-server NetworkPolicy manifest](https://github.com/argoproj/argo-cd/blob/master/manifests/base/repo-server/argocd-repo-server-network-policy.yaml) +- [Argo CD docs - metrics](https://argo-cd.readthedocs.io/en/latest/operator-manual/metrics/) +- [Argo Helm - chart values reference](https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/README.md) +- [Kustomize - Helm chart generator example](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md) diff --git a/src/pentesting-ci-cd/pentesting-ci-cd-methodology.md b/src/pentesting-ci-cd/pentesting-ci-cd-methodology.md index d5b4f2d80..bdaf47f9d 100644 --- a/src/pentesting-ci-cd/pentesting-ci-cd-methodology.md +++ b/src/pentesting-ci-cd/pentesting-ci-cd-methodology.md @@ -1,4 +1,4 @@ -# Méthodologie de Pentesting CI/CD +# Méthodologie Pentesting CI/CD {{#include ../banners/hacktricks-training.md}} @@ -6,7 +6,7 @@ ## VCS -VCS signifie **Version Control System**, ce système permet aux développeurs de **gérer leur code source**. Le plus courant est **git** et vous le trouverez généralement utilisé par les entreprises sur l’une des **plateformes** suivantes : +VCS signifie **Version Control System**, ce système permet aux développeurs de **gérer leur code source**. Le plus courant est **git** et vous trouverez généralement des entreprises qui l’utilisent sur l’une des **plateformes** suivantes : - Github - Gitlab @@ -16,38 +16,38 @@ VCS signifie **Version Control System**, ce système permet aux développeurs de - Cloud providers (ils proposent leurs propres plateformes VCS) -## Pipelines CI/CD +## CI/CD Pipelines -Les pipelines CI/CD permettent aux développeurs d’**automatiser l’exécution du code** pour divers usages, notamment la construction, les tests et le déploiement d’applications. Ces workflows automatisés sont **déclenchés par des actions spécifiques**, comme des push de code, des pull requests ou des tâches planifiées. Ils sont utiles pour fluidifier le processus entre le développement et la production. +Les pipelines CI/CD permettent aux développeurs d’**automatiser l’exécution du code** à diverses fins, notamment la compilation, les tests et le déploiement des applications. Ces workflows automatisés sont **déclenchés par des actions spécifiques**, comme des pushes de code, des pull requests ou des tâches planifiées. Ils sont utiles pour fluidifier le processus du développement vers la production. -Cependant, ces systèmes doivent être **exécutés quelque part** et généralement avec des **credentials privilégiés pour déployer du code ou accéder à des informations sensibles**. +Cependant, ces systèmes doivent être **exécutés quelque part** et généralement avec des **identifiants privilégiés pour déployer du code ou accéder à des informations sensibles**. -## Méthodologie de Pentesting VCS +## VCS Pentesting Methodology > [!NOTE] -> Même si certaines plateformes VCS permettent de créer des pipelines, dans cette section nous allons analyser uniquement les attaques potentielles visant le contrôle du code source. +> Même si certaines plateformes VCS permettent de créer des pipelines, pour cette section nous allons analyser uniquement les attaques potentielles sur le contrôle du code source. -Les plateformes qui contiennent le code source de votre projet contiennent des informations sensibles et il faut être très prudent avec les permissions accordées dans cette plateforme. Voici quelques problèmes courants sur les plateformes VCS qu’un attaquant pourrait exploiter : +Les plateformes qui contiennent le code source de votre projet contiennent des informations sensibles et les personnes doivent être très prudentes avec les permissions accordées dans cette plateforme. Voici quelques problèmes courants sur les plateformes VCS qu’un attaquant pourrait exploiter : - **Leaks** : Si votre code contient des leaks dans les commits et que l’attaquant peut accéder au repo (parce qu’il est public ou parce qu’il y a accès), il pourrait découvrir les leaks. -- **Access** : Si un attaquant peut **accéder à un compte sur la plateforme VCS**, il pourrait obtenir **davantage de visibilité et de permissions**. +- **Accès** : Si un attaquant peut **accéder à un compte dans la plateforme VCS**, il pourrait obtenir **plus de visibilité et de permissions**. - **Register** : Certaines plateformes autorisent simplement les utilisateurs externes à créer un compte. -- **SSO** : Certaines plateformes n’autorisent pas l’enregistrement, mais permettent à n’importe qui d’accéder avec un SSO valide (donc un attaquant pourrait utiliser son compte github pour entrer par exemple). +- **SSO** : Certaines plateformes n’autorisent pas les utilisateurs à s’enregistrer, mais permettent à n’importe qui d’accéder avec un SSO valide (un attaquant pourrait donc utiliser son compte github pour entrer, par exemple). - **Credentials** : Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... il existe plusieurs types de tokens qu’un utilisateur pourrait voler pour accéder d’une manière ou d’une autre à un repo. -- **Webhooks** : Les plateformes VCS permettent de générer des webhooks. S’ils ne sont **pas protégés** par des secrets non visibles, un **attaquant pourrait les exploiter**. +- **Webhooks** : Les plateformes VCS permettent de générer des webhooks. S’ils ne sont pas **protégés** par des secrets non visibles, **un attaquant pourrait les exploiter**. - Si aucun secret n’est en place, l’attaquant pourrait exploiter le webhook de la plateforme tierce -- Si le secret est dans l’URL, le même problème se produit et l’attaquant a aussi le secret -- **Code compromise:** Si un acteur malveillant dispose d’un certain type d’accès **write** sur les repos, il pourrait essayer **d’injecter du code malveillant**. Pour réussir, il pourrait devoir **bypasser les branch protections**. Ces actions peuvent être réalisées avec différents objectifs en tête : -- Compromettre la branche principale pour **compromettre la production**. -- Compromettre la branche principale (ou d’autres branches) pour **compromettre les machines des développeurs** (car ils exécutent généralement des tests, terraform ou d’autres choses dans le repo sur leurs machines). -- **Compromettre le pipeline** (voir la section suivante) +- Si le secret est dans l’URL, la même chose se produit et l’attaquant a aussi le secret +- **Code compromise:** Si un acteur malveillant dispose d’un certain niveau d’accès **write** sur les repos, il pourrait essayer **d’injecter du code malveillant**. Pour réussir, il pourrait avoir besoin de **bypasser les branch protections**. Ces actions peuvent être menées avec différents objectifs en tête : +- Compromettre la branche principale pour **compromise production**. +- Compromettre la branche principale (ou d’autres branches) pour **compromise developer machines** (car ils exécutent généralement des tests, terraform ou d’autres choses dans le repo sur leurs machines). +- **Compromise the pipeline** (voir la section suivante) -## Méthodologie de Pentesting des Pipelines +## Pipelines Pentesting Methodology -La manière la plus courante de définir un pipeline est d’utiliser un **fichier de configuration CI hébergé dans le repository** que le pipeline construit. Ce fichier décrit l’ordre des jobs exécutés, les conditions qui influencent le flux, ainsi que les paramètres de l’environnement de build.\ -Ces fichiers ont généralement un nom et un format cohérents, par exemple — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), et les fichiers YAML GitHub Actions situés sous .github/workflows. Lorsqu’il est déclenché, le job du pipeline **récupère le code** depuis la source sélectionnée (par exemple le commit / la branche), et **exécute les commandes spécifiées dans le fichier de configuration CI** sur ce code. +La manière la plus courante de définir un pipeline est d’utiliser un **fichier de configuration CI hébergé dans le repository** que le pipeline construit. Ce fichier décrit l’ordre des jobs exécutés, les conditions qui affectent le flux, et les paramètres de l’environnement de build.\ +Ces fichiers ont généralement un nom et un format cohérents, par exemple — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), et les fichiers YAML GitHub Actions situés dans .github/workflows. Lorsqu’il est déclenché, le job du pipeline **récupère le code** depuis la source sélectionnée (par ex. commit / branch), et **exécute les commandes spécifiées dans le fichier de configuration CI** sur ce code. -Par conséquent, l’objectif ultime de l’attaquant est d’une manière ou d’une autre **compromettre ces fichiers de configuration** ou les **commandes qu’ils exécutent**. +Par conséquent, l’objectif ultime de l’attaquant est d’une manière ou d’une autre de **compromettre ces fichiers de configuration** ou les **commandes qu’ils exécutent**. > [!TIP] > Certains builders hébergés permettent aux contributeurs de choisir le Docker build context et le chemin du Dockerfile. Si le context est contrôlé par l’attaquant, vous pouvez le définir en dehors du repo (par exemple, "..") pour ingérer des fichiers de l’hôte pendant le build et exfiltrer des secrets. Voir : @@ -58,59 +58,60 @@ Par conséquent, l’objectif ultime de l’attaquant est d’une manière ou d ### PPE - Poisoned Pipeline Execution -Le chemin Poisoned Pipeline Execution (PPE) exploite les permissions dans un repository SCM pour manipuler un pipeline CI et exécuter des commandes malveillantes. Les utilisateurs ayant les permissions nécessaires peuvent modifier les fichiers de configuration CI ou d’autres fichiers utilisés par le job du pipeline pour y inclure des commandes malveillantes. Cela "empoisonne" le pipeline CI, ce qui conduit à l’exécution de ces commandes malveillantes. +Le chemin Poisoned Pipeline Execution (PPE) exploite des permissions dans un repository SCM pour manipuler un pipeline CI et exécuter des commandes malveillantes. Les utilisateurs disposant des permissions nécessaires peuvent modifier les fichiers de configuration CI ou d’autres fichiers utilisés par le job du pipeline afin d’y inclure des commandes malveillantes. Cela « empoisonne » le pipeline CI, conduisant à l’exécution de ces commandes malveillantes. Pour qu’un acteur malveillant réussisse une attaque PPE, il doit être capable de : -- Avoir un **write access à la plateforme VCS**, car généralement les pipelines sont déclenchés lors d’un push ou d’une pull request. (Voir la méthodologie de pentesting VCS pour un résumé des moyens d’obtenir l’accès). -- Noter qu’une **external PR peut parfois compter comme un "write access"**. -- Même s’il a des permissions de write, il doit s’assurer de pouvoir **modifier le fichier de config CI ou d’autres fichiers sur lesquels la config s’appuie**. -- Pour cela, il peut avoir besoin de pouvoir **bypasser les branch protections**. +- Avoir un **write access** à la plateforme VCS, car les pipelines sont généralement déclenchés lorsqu’un push ou une pull request est effectué. (Voir la méthodologie pentesting VCS pour un résumé des moyens d’obtenir l’accès). +- Noter que parfois une **external PR compte comme un "write access"**. +- Même s’il a des permissions write, il doit s’assurer qu’il peut **modifier le fichier de config CI ou les autres fichiers dont dépend la config**. +- Pour cela, il pourrait avoir besoin de **bypasser les branch protections**. Il existe 3 variantes de PPE : - **D-PPE** : Une attaque **Direct PPE** se produit lorsque l’acteur **modifie le fichier de config CI** qui va être exécuté. - **I-DDE** : Une attaque **Indirect PPE** se produit lorsque l’acteur **modifie** un **fichier** sur lequel le fichier de config CI qui va être exécuté **s’appuie** (comme un make file ou une config terraform). -- **Public PPE or 3PE** : Dans certains cas, les pipelines peuvent être **déclenchés par des utilisateurs qui n’ont pas de write access dans le repo** (et qui ne font même pas forcément partie de l’org) parce qu’ils peuvent envoyer une PR. -- **3PE Command Injection** : En général, les pipelines CI/CD vont **définir des variables d’environnement** contenant des **informations sur la PR**. Si cette valeur peut être contrôlée par un attaquant (comme le titre de la PR) et est **utilisée** à un **endroit dangereux** (comme l’exécution de **commandes sh**), un attaquant peut y **injecter des commandes**. +- **Public PPE or 3PE** : Dans certains cas, les pipelines peuvent être **déclenchés par des utilisateurs qui n’ont pas de write access dans le repo** (et qui peuvent même ne pas faire partie de l’org) parce qu’ils peuvent envoyer une PR. +- **3PE Command Injection** : En général, les pipelines CI/CD vont **définir des variables d’environnement** avec des **informations sur la PR**. Si cette valeur peut être contrôlée par un attaquant (comme le titre de la PR) et est **utilisée** à un **endroit dangereux** (comme l’exécution de **sh commands**), un attaquant peut **y injecter des commandes**. -### Bénéfices de l’exploitation +### Exploitation Benefits -En connaissant les 3 variantes pour empoisonner un pipeline, voyons ce qu’un attaquant pourrait obtenir après une exploitation réussie : +Connaissant les 3 variantes pour empoisonner un pipeline, voyons ce qu’un attaquant pourrait obtenir après une exploitation réussie : -- **Secrets** : Comme mentionné précédemment, les pipelines nécessitent des **privilèges** pour leurs jobs (récupérer le code, le builder, le déployer...). Ces **privilèges** sont généralement **accordés via des secrets**. Ces secrets sont généralement accessibles via des **variables d’env ou des fichiers dans le système**. Par conséquent, un attaquant essaiera toujours d’exfiltrer autant de secrets que possible. -- Selon la plateforme du pipeline, l’attaquant **pourrait devoir spécifier les secrets dans la config**. Cela signifie que si l’attaquant ne peut pas modifier la configuration CI du pipeline (**I-PPE** par exemple), il pourrait **seulement exfiltrer les secrets que ce pipeline possède**. -- **Computation** : Le code est exécuté quelque part ; selon l’endroit, un attaquant pourrait être en mesure de pivoter davantage. -- **On-Premises** : Si les pipelines sont exécutés on premises, un attaquant pourrait se retrouver dans un **réseau interne avec accès à davantage de ressources**. -- **Cloud** : L’attaquant pourrait accéder à **d’autres machines dans le cloud** mais pourrait aussi **exfiltrer** des **tokens** IAM roles/service accounts à partir de celles-ci pour obtenir un **accès supplémentaire dans le cloud**. -- **Platforms machine** : Parfois, les jobs seront exécutés sur les **machines de la plateforme des pipelines**, qui se trouvent généralement dans un cloud avec **pas plus d’accès**. -- **Select it:** Parfois, la **plateforme des pipelines aura configuré plusieurs machines** et si vous pouvez **modifier le fichier de configuration CI**, vous pouvez **indiquer où vous voulez exécuter le code malveillant**. Dans cette situation, un attaquant lancera probablement un reverse shell sur chaque machine possible pour essayer d’aller plus loin. -- **Compromise production** : Si vous êtes dans le pipeline et que la version finale en est construite puis déployée, vous pourriez **compromettre le code qui va finir par s’exécuter en production**. +- **Secrets** : Comme mentionné précédemment, les pipelines nécessitent des **privileges** pour leurs jobs (récupérer le code, le build, le deploy...) et ces **privileges** sont généralement **accordés dans des secrets**. Ces secrets sont généralement accessibles via des **variables d’env ou des fichiers dans le système**. Par conséquent, un attaquant essaiera toujours d’exfiltrer autant de secrets que possible. +- Selon la plateforme du pipeline, l’attaquant **pourrait devoir spécifier les secrets dans la config**. Cela signifie que si l’attaquant ne peut pas modifier le pipeline de configuration CI (**I-PPE** par exemple), il pourrait **uniquement exfiltrer les secrets que ce pipeline possède**. +- **Computation** : Le code est exécuté quelque part, selon l’endroit où il est exécuté un attaquant pourrait être en mesure de pivoter plus loin. +- **On-Premises** : Si les pipelines sont exécutés on premises, un attaquant pourrait se retrouver dans un **internal network avec accès à davantage de ressources**. +- **Cloud** : L’attaquant pourrait accéder à **d’autres machines dans le cloud** mais pourrait aussi **exfiltrer** des **tokens** IAM roles/service accounts depuis celles-ci afin d’obtenir un **accès supplémentaire dans le cloud**. +- **Platforms machine** : Parfois les jobs seront exécutés sur les **machines de la plateforme de pipelines**, qui se trouvent généralement dans un cloud sans **plus d’accès**. +- **Select it:** Parfois la **plateforme de pipelines aura configuré plusieurs machines** et si vous pouvez **modifier le fichier de configuration CI** vous pouvez **indiquer où vous voulez exécuter le code malveillant**. Dans cette situation, un attaquant exécutera probablement un reverse shell sur chaque machine possible pour tenter de l’exploiter davantage. +- **Compromise production** : Si vous êtes dans le pipeline et que la version finale est construite et déployée à partir de celui-ci, vous pourriez **compromettre le code qui va finir par s’exécuter en production**. ### Dependency & Registry Supply-Chain Abuse -Compromettre un pipeline CI/CD ou lui voler des credentials peut permettre à un attaquant de passer de **l’exécution dans le pipeline** à une **exécution de code à l’échelle de l’écosystème** en backdoorant des dépendances ou des outils de release : +Compromettre un pipeline CI/CD ou voler des credentials depuis celui-ci peut permettre à un attaquant de passer de **pipeline execution** à **ecosystem-wide code execution** en backdoorant des dependencies ou des outils de release : -- **Install-time code execution via package hooks** : publier une version de package qui ajoute `preinstall`, `postinstall`, `prepare`, ou des hooks similaires afin que le payload s’exécute automatiquement sur les postes des développeurs et sur les runners CI pendant l’installation des dépendances. +- **Install-time code execution via package hooks** : publier une version de package qui ajoute des hooks `preinstall`, `postinstall`, `prepare` ou similaires afin que le payload s’exécute automatiquement sur les postes de développement et les runners CI pendant l’installation des dependencies. - **Secondary execution paths** : même si les cibles installent avec `--ignore-scripts`, un package malveillant peut toujours enregistrer un **nom de CLI courant** dans le champ `bin` afin que le wrapper contrôlé par l’attaquant soit symlinked dans `PATH` et s’exécute plus tard lorsque la commande est utilisée. -- **Runtime bootstrapping** : un petit installer peut télécharger un second runtime ou toolchain pendant l’installation (par exemple Bun ou un interpreter packé) puis lancer le payload principal avec celui-ci, évitant ainsi les dépendances locales requises. -- **Credential harvesting from build environments** : une fois le code exécuté dans CI, vérifiez les variables d’environnement, `~/.npmrc`, `~/.git-credentials`, les clés SSH, les configs des cloud CLIs et les outils locaux comme `gh auth token`. Sur GitHub Actions, recherchez aussi les secrets et artifacts spécifiques au runner. -- **Workflow injection with stolen GitHub tokens** : un token avec les permissions **`repo` + `workflow`** suffit pour créer une branche, commit un fichier malveillant dans `.github/workflows/`, le déclencher, collecter les artifacts/logs produits, puis supprimer la branche temporaire / le workflow run pour réduire les traces. -- **Wormable registry propagation** : les tokens npm volés doivent être validés pour les permissions **publish** et pour vérifier s’ils contournent la 2FA. Si oui, énumérez les packages modifiables, téléchargez leurs tarballs, injectez un loader comme `setup.mjs`, définissez `preinstall` pour l’exécuter, augmentez la version patch, puis republiez. Cela transforme une compromission CI en auto-exécution en aval dans d’autres environnements. +- **Runtime bootstrapping** : un petit installer peut télécharger un second runtime ou toolchain pendant l’installation (par exemple Bun ou un interpreter packé), puis lancer le payload principal avec celui-ci, évitant les dépendances locales. +- **Credential harvesting from build environments** : une fois le code exécuté dans CI, vérifiez les variables d’environnement, `~/.npmrc`, `~/.git-credentials`, les clés SSH, les configs de cloud CLI, et les outils locaux tels que `gh auth token`. Sur GitHub Actions, cherchez aussi les secrets et artifacts spécifiques au runner. +- **Workflow injection with stolen GitHub tokens** : un token avec les permissions **`repo` + `workflow`** suffit pour créer une branche, commit un fichier malveillant dans `.github/workflows/`, le déclencher, collecter les artifacts/logs produits, puis supprimer la branche temporaire/l’exécution du workflow pour réduire les traces. +- **Wormable registry propagation** : les tokens npm volés doivent être validés pour les permissions de **publish** et pour vérifier s’ils contournent le 2FA. Si c’est le cas, énumérez les packages modifiables, téléchargez leurs tarballs, injectez un loader comme `setup.mjs`, définissez `preinstall` pour l’exécuter, augmentez la version patch, puis republish. Cela transforme une compromission CI en auto-exécution en aval dans d’autres environnements. -#### Vérifications pratiques pendant une assessment +#### Practical checks during an assessment -- Passez en revue l’automatisation de release pour détecter des hooks de package-manager ajoutés à `package.json`, des entrées `bin` inattendues, ou des bumps de version qui ne modifient que l’artifact de release. -- Vérifiez si CI stocke des credentials de registry longue durée dans des fichiers en clair comme `~/.npmrc` au lieu d’utiliser des OIDC à courte durée ou trusted publishing. -- Vérifiez si les tokens GitHub disponibles dans CI peuvent écrire des fichiers workflow ou créer des branches/tags. -- Si un package compromis est suspecté, inspectez le tarball publié et pas seulement le Git repository, car le loader/runtime malveillant peut exister uniquement dans l’artifact publié. -- Cherchez une exécution inattendue de package-manager dans CI comme `npm install` au lieu de `npm ci`, des téléchargements/exécutions Bun inattendus, ou de nouveaux artifacts de workflow générés à partir de branches transitoires. +- Examinez l’automatisation de release pour les hooks de package-manager ajoutés à `package.json`, les entrées `bin` inattendues, ou les bumps de version qui ne modifient que l’artifact de release. +- Vérifiez si CI stocke des credentials de registry longue durée en clair dans des fichiers comme `~/.npmrc` au lieu d’utiliser un OIDC de courte durée ou trusted publishing. +- Vérifiez si les tokens GitHub disponibles dans CI peuvent écrire des fichiers de workflow ou créer des branches/tags. +- Si un package compromis est suspecté, inspectez le tarball publié et pas seulement le repository Git, car le loader/runtime malveillant peut exister uniquement dans l’artifact publié. +- Recherchez une exécution inattendue du package-manager dans CI, comme `npm install` au lieu de `npm ci`, des téléchargements/exécutions inattendus de Bun, ou de nouveaux artifacts de workflow générés à partir de branches transitoires. +- Examinez aussi les moteurs de déploiement GitOps comme cibles CI/CD. L’énumération spécifique à Argo CD, l’abus de repo-server et les attaques de poisoning du cache Redis sont couverts dans [Argo CD Security](argocd-security.md). -## Plus d’infos pertinentes +## More relevant info ### Tools & CIS Benchmark -- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) est un outil open-source pour auditer la sécurité de votre supply chain logicielle selon un nouveau [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). L’audit se concentre sur l’ensemble du processus SDLC, où il peut révéler des risques depuis le code time jusqu’au deploy time. +- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) est un outil open-source pour auditer la sécurité de votre stack software supply chain selon un nouveau [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). L’audit se concentre sur l’ensemble du processus SDLC, où il peut révéler des risques du code time au deploy time. ### Top 10 CI/CD Security Risk @@ -118,7 +119,7 @@ Consultez cet article intéressant sur les 10 principaux risques CI/CD selon Cid ### Labs -- Sur chaque plateforme que vous pouvez lancer localement, vous trouverez comment la démarrer en local afin de pouvoir la configurer comme vous le souhaitez pour la tester +- Sur chaque plateforme que vous pouvez exécuter localement, vous trouverez comment la lancer localement afin de pouvoir la configurer comme vous le souhaitez pour la tester - Gitea + Jenkins lab: [https://github.com/cider-security-research/cicd-goat](https://github.com/cider-security-research/cicd-goat) ### Automatic Tools