Atlantis Security
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Atlantis aide essentiellement à exécuter terraform à partir des Pull Requests de votre serveur git.
Allez sur la page des versions d'atlantis à https://github.com/runatlantis/atlantis/releases et téléchargez celle qui vous convient.
Créez un jeton personnel (avec accès au dépôt) de votre utilisateur github
Exécutez ./atlantis testdrive
et cela créera un dépôt de démonstration que vous pouvez utiliser pour communiquer avec atlantis
Vous pouvez accéder à la page web à 127.0.0.1:4141
Atlantis prend en charge plusieurs hôtes git tels que Github, Gitlab, Bitbucket et Azure DevOps. Cependant, pour accéder aux dépôts sur ces plateformes et effectuer des actions, il doit avoir un accès privilégié accordé (au moins des autorisations d'écriture). Les docs encouragent à créer un utilisateur sur ces plateformes spécifiquement pour Atlantis, mais certaines personnes peuvent utiliser des comptes personnels.
Dans tous les cas, du point de vue d'un attaquant, le compte Atlantis sera très intéressant à compromettre.
Atlantis utilise optionnellement Webhook secrets pour valider que les webhooks qu'il reçoit de votre hôte Git sont légitimes.
Une façon de confirmer cela serait de permettre uniquement les requêtes provenant des IP de votre hôte Git, mais une façon plus simple est d'utiliser un Webhook Secret.
Notez que, sauf si vous utilisez un serveur github ou bitbucket privé, vous devrez exposer les points de terminaison webhook à Internet.
Atlantis va exposer des webhooks afin que le serveur git puisse lui envoyer des informations. Du point de vue d'un attaquant, il serait intéressant de savoir si vous pouvez lui envoyer des messages.
Atlantis exécute Terraform en exécutant simplement les commandes terraform plan
et apply
sur le serveur où Atlantis est hébergé. Tout comme lorsque vous exécutez Terraform localement, Atlantis a besoin de credentials pour votre fournisseur spécifique.
C'est à vous de fournir des credentials pour votre fournisseur spécifique à Atlantis :
Le Helm Chart d'Atlantis et le Module AWS Fargate ont leurs propres mécanismes pour les credentials du fournisseur. Lisez leurs docs.
Si vous exécutez Atlantis dans le cloud, alors de nombreux clouds ont des moyens de donner un accès API cloud aux applications qui y fonctionnent, ex :
AWS EC2 Roles (Recherchez "EC2 Role")
De nombreux utilisateurs définissent des variables d'environnement, ex. AWS_ACCESS_KEY
, où Atlantis fonctionne.
D'autres créent les fichiers de configuration nécessaires, ex. ~/.aws/credentials
, où Atlantis fonctionne.
Utilisez le HashiCorp Vault Provider pour obtenir des credentials de fournisseur.
Le conteneur où Atlantis est exécuté contiendra très probablement des credentials privilégiés pour les fournisseurs (AWS, GCP, Github...) qu'Atlantis gère via Terraform.
Par défaut, Atlantis exécutera une page web sur le port 4141 en localhost. Cette page vous permet simplement d'activer/désactiver l'application atlantis et de vérifier l'état du plan des dépôts et de les déverrouiller (elle ne permet pas de modifier des choses, donc elle n'est pas très utile).
Vous ne la trouverez probablement pas exposée à Internet, mais il semble que par défaut aucune credential n'est nécessaire pour y accéder (et si elles le sont, atlantis
:atlantis
sont les valeurs par défaut).
La configuration pour atlantis server
peut être spécifiée via des drapeaux de ligne de commande, des variables d'environnement, un fichier de configuration ou un mélange des trois.
Vous pouvez trouver ici la liste des drapeaux pris en charge par le serveur Atlantis
Vous pouvez trouver ici comment transformer une option de configuration en variable d'environnement
Les valeurs sont choisies dans cet ordre :
Drapeaux
Variables d'environnement
Fichier de configuration
Notez que dans la configuration, vous pourriez trouver des valeurs intéressantes telles que tokens et mots de passe.
Certaines configurations affectent comment les dépôts sont gérés. Cependant, il est possible que chaque dépôt nécessite des paramètres différents, donc il existe des moyens de spécifier chaque dépôt. Voici l'ordre de priorité :
Fichier /atlantis.yml
. Ce fichier peut être utilisé pour spécifier comment atlantis doit traiter le dépôt. Cependant, par défaut, certaines clés ne peuvent pas être spécifiées ici sans certains drapeaux le permettant.
Probablement requis d'être autorisé par des drapeaux comme allowed_overrides
ou allow_custom_workflows
Configuration côté serveur : Vous pouvez le passer avec le drapeau --repo-config
et c'est un yaml configurant de nouveaux paramètres pour chaque dépôt (regex pris en charge)
Valeurs par défaut
PR Protections
Atlantis permet d'indiquer si vous souhaitez que le PR soit approuvé
par quelqu'un d'autre (même si cela n'est pas défini dans la protection de branche) et/ou soit fusionnable
(protections de branche passées) avant d'exécuter apply. D'un point de vue de sécurité, il est recommandé de définir les deux options.
Dans le cas où allowed_overrides
est True, ces paramètres peuvent être écrasés sur chaque projet par le fichier /atlantis.yml
.
Scripts
La configuration du dépôt peut spécifier des scripts à exécuter avant (pré-hooks de workflow) et après (post-hooks de workflow) qu'un workflow est exécuté.
Il n'y a aucune option pour permettre de spécifier ces scripts dans le fichier de dépôt /atlantis.yml
.
Workflow
Dans la configuration du dépôt (configuration côté serveur), vous pouvez spécifier un nouveau workflow par défaut, ou créer de nouveaux workflows personnalisés. Vous pouvez également spécifier quels dépôts peuvent accéder aux nouveaux générés. Ensuite, vous pouvez permettre au fichier atlantis.yaml de chaque dépôt de spécifier le workflow à utiliser.
Si le drapeau de configuration côté serveur allow_custom_workflows
est défini sur True, les workflows peuvent être spécifiés dans le fichier atlantis.yaml
de chaque dépôt. Il est également potentiellement nécessaire que allowed_overrides
spécifie également workflow
pour écraser le workflow qui va être utilisé.
Cela donnera essentiellement RCE dans le serveur Atlantis à tout utilisateur qui peut accéder à ce dépôt.
Vérification des politiques Conftest
Atlantis prend en charge l'exécution des politiques conftest côté serveur contre la sortie du plan. Les cas d'utilisation courants pour cette étape incluent :
Interdire l'utilisation d'une liste de modules
Affirmer les attributs d'une ressource au moment de sa création
Détecter les suppressions de ressources non intentionnelles
Prévenir les risques de sécurité (c'est-à-dire exposer des ports sécurisés au public)
Vous pouvez vérifier comment le configurer dans la documentation.
Dans la documentation, vous pouvez trouver les options que vous pouvez utiliser pour exécuter Atlantis :
Si pendant l'exploitation vous trouvez cette erreur : Error: Error acquiring the state lock
Vous pouvez le corriger en exécutant :
Si vous avez un accès en écriture sur un dépôt, vous pourrez créer une nouvelle branche et générer une PR. Si vous pouvez exécuter atlantis plan
(ou peut-être est-ce exécuté automatiquement) vous pourrez RCE à l'intérieur du serveur Atlantis.
Vous pouvez le faire en faisant charger une source de données externe par Atlantis. Il suffit de mettre un payload comme le suivant dans le fichier main.tf
:
Attaque plus discrète
Vous pouvez effectuer cette attaque même de manière plus discrète, en suivant ces suggestions :
Au lieu d'ajouter le rev shell directement dans le fichier terraform, vous pouvez charger une ressource externe qui contient le rev shell :
Vous pouvez trouver le code rev shell dans https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules
Dans la ressource externe, utilisez la fonctionnalité ref pour cacher le code rev shell terraform dans une branche à l'intérieur du dépôt, quelque chose comme : git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b
Au lieu de créer une PR vers master pour déclencher Atlantis, créez 2 branches (test1 et test2) et créez une PR de l'une à l'autre. Lorsque vous avez terminé l'attaque, il vous suffit de supprimer la PR et les branches.
Vous pouvez dumper les secrets utilisés par terraform en exécutant atlantis plan
(terraform plan
) en mettant quelque chose comme ceci dans le fichier terraform :
Si vous avez un accès en écriture sur un dépôt, vous pourrez créer une nouvelle branche et générer une PR. Si vous pouvez exécuter atlantis apply
, vous pourrez RCE à l'intérieur du serveur Atlantis.
Cependant, vous devrez généralement contourner certaines protections :
Mergeable : Si cette protection est définie dans Atlantis, vous ne pouvez exécuter atlantis apply
que si la PR est fusionnable (ce qui signifie que la protection de branche doit être contournée).
Vérifiez les contournements potentiels des protections de branche
Approuvé : Si cette protection est définie dans Atlantis, un autre utilisateur doit approuver la PR avant que vous puissiez exécuter atlantis apply
Par défaut, vous pouvez abuser du token Gitbot pour contourner cette protection
Exécution de terraform apply
sur un fichier Terraform malveillant avec local-exec.
Vous devez simplement vous assurer qu'une charge utile comme les suivantes se termine dans le fichier main.tf
:
Suivez les suggestions de la technique précédente pour effectuer cette attaque de manière plus discrète.
Lors de l'exécution de atlantis plan
ou atlantis apply
, terraform est exécuté en arrière-plan, vous pouvez passer des commandes à terraform depuis atlantis en commentant quelque chose comme :
Quelque chose que vous pouvez passer sont des variables d'environnement qui pourraient être utiles pour contourner certaines protections. Vérifiez les variables d'environnement terraform dans https://www.terraform.io/cli/config/environment-variables
Exécution de commandes de construction personnalisées malveillantes spécifiées dans un fichier atlantis.yaml
. Atlantis utilise le fichier atlantis.yaml
de la branche de la demande de tirage, pas de master
.
Cette possibilité a été mentionnée dans une section précédente :
Si le serveur de configuration le drapeau allow_custom_workflows
est défini sur True, les workflows peuvent être spécifiés dans le fichier atlantis.yaml
de chaque dépôt. Il est également potentiellement nécessaire que allowed_overrides
spécifie également workflow
pour remplacer le workflow qui va être utilisé.
Cela donnera essentiellement RCE sur le serveur Atlantis à tout utilisateur pouvant accéder à ce dépôt.
Si le drapeau configuration côté serveur allowed_overrides
a apply_requirements
configuré, il est possible pour un dépôt de modifier les protections de plan/apply pour les contourner.
Si quelqu'un envoie des commentaires atlantis plan/apply
sur vos pull requests valides, cela fera exécuter terraform quand vous ne le souhaitez pas.
De plus, si vous n'avez pas configuré dans la protection de branche de demander une réévaluation de chaque PR lorsqu'un nouveau commit est poussé dessus, quelqu'un pourrait écrire des configurations malveillantes (voir les scénarios précédents) dans la configuration terraform, exécuter atlantis plan/apply
et obtenir RCE.
C'est le paramètre dans les protections de branche de Github :
Si vous parvenez à voler le secret du webhook utilisé ou s'il n'y a pas de secret de webhook utilisé, vous pourriez appeler le webhook d'Atlantis et invoker des commandes atlatis directement.
Bitbucket Cloud ne supporte pas les secrets de webhook. Cela pourrait permettre aux attaquants de falsifier des requêtes depuis Bitbucket. Assurez-vous de n'autoriser que les IPs de Bitbucket.
Cela signifie qu'un attaquant pourrait faire des requêtes falsifiées à Atlantis qui semblent provenir de Bitbucket.
Si vous spécifiez --repo-allowlist
, alors ils ne pourraient falsifier que des requêtes concernant ces dépôts, donc le plus de dégâts qu'ils pourraient faire serait de planifier/appliquer sur vos propres dépôts.
Pour éviter cela, autorisez les adresses IP de Bitbucket (voir les adresses IPv4 sortantes).
Si vous avez réussi à accéder au serveur ou au moins à obtenir un LFI, il y a des choses intéressantes que vous devriez essayer de lire :
/home/atlantis/.git-credentials
Contient les identifiants d'accès vcs
/atlantis-data/atlantis.db
Contient les identifiants d'accès vcs avec plus d'infos
/atlantis-data/repos/<org_name>
/
<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate
Fichier d'état terraform
Exemple : /atlantis-data/repos/ghOrg_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
/proc/1/environ
Variables d'environnement
/proc/[2-20]/cmdline
Ligne de commande de atlantis server
(peut contenir des données sensibles)
Parce que n'importe qui peut commenter sur des pull requests publiques, même avec toutes les mitigations de sécurité disponibles, il est toujours dangereux d'exécuter Atlantis sur des dépôts publics sans une configuration appropriée des paramètres de sécurité.
--allow-fork-prs
Si vous exécutez sur un dépôt public (ce qui n'est pas recommandé, voir ci-dessus), vous ne devriez pas définir --allow-fork-prs
(par défaut à false) car n'importe qui peut ouvrir une pull request depuis son fork vers votre dépôt.
--repo-allowlist
Atlantis nécessite que vous spécifiiez une liste blanche de dépôts à partir desquels il acceptera des webhooks via le drapeau --repo-allowlist
. Par exemple :
Dépôts spécifiques : --repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests
Votre organisation entière : --repo-allowlist=github.com/runatlantis/*
Chaque dépôt dans votre installation GitHub Enterprise : --repo-allowlist=github.yourcompany.com/*
Tous les dépôts : --repo-allowlist=*
. Utile lorsque vous êtes dans un réseau protégé mais dangereux sans également définir un secret de webhook.
Ce drapeau garantit que votre installation d'Atlantis n'est pas utilisée avec des dépôts que vous ne contrôlez pas. Voir atlantis server --help
pour plus de détails.
Si des attaquants soumettant des pull requests avec du code Terraform malveillant sont dans votre modèle de menace, alors vous devez être conscient que les approbations terraform apply
ne suffisent pas. Il est possible d'exécuter du code malveillant dans un terraform plan
en utilisant la source de données external
ou en spécifiant un fournisseur malveillant. Ce code pourrait alors exfiltrer vos identifiants.
Pour éviter cela, vous pourriez :
Intégrer les fournisseurs dans l'image d'Atlantis ou héberger et refuser l'egress en production.
Implémenter le protocole de registre de fournisseurs en interne et refuser l'egress public, de cette façon vous contrôlez qui a un accès en écriture au registre.
Modifier votre configuration de dépôt côté serveur's plan
étape pour valider l'utilisation de fournisseurs ou de sources de données non autorisés ou de PRs d'utilisateurs non autorisés. Vous pourriez également ajouter une validation supplémentaire à ce stade, par exemple exiger un "pouce en l'air" sur la PR avant de permettre à la plan
de continuer. Conftest pourrait être utile ici.
Atlantis doit être exécuté avec des secrets de webhook définis via les variables d'environnement $ATLANTIS_GH_WEBHOOK_SECRET
/$ATLANTIS_GITLAB_WEBHOOK_SECRET
. Même avec le drapeau --repo-allowlist
défini, sans un secret de webhook, les attaquants pourraient faire des requêtes à Atlantis en se faisant passer pour un dépôt qui est sur la liste blanche. Les secrets de webhook garantissent que les requêtes webhook proviennent réellement de votre fournisseur VCS (GitHub ou GitLab).
Si vous utilisez Azure DevOps, au lieu de secrets de webhook, ajoutez un nom d'utilisateur et un mot de passe de base.
Azure DevOps prend en charge l'envoi d'un en-tête d'authentification de base dans tous les événements de webhook. Cela nécessite d'utiliser une URL HTTPS pour votre emplacement de webhook.
Si vous utilisez des secrets de webhook mais que votre trafic est sur HTTP, alors les secrets de webhook pourraient être volés. Activez SSL/HTTPS en utilisant les drapeaux --ssl-cert-file
et --ssl-key-file
.
Il est fortement recommandé d'activer l'authentification dans le service web. Activez BasicAuth en utilisant --web-basic-auth=true
et configurez un nom d'utilisateur et un mot de passe en utilisant les drapeaux --web-username=yourUsername
et --web-password=yourPassword
.
Vous pouvez également passer ces valeurs en tant que variables d'environnement ATLANTIS_WEB_BASIC_AUTH=true
ATLANTIS_WEB_USERNAME=yourUsername
et ATLANTIS_WEB_PASSWORD=yourPassword
.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)