Wiz CTF #7: State of Affairs

Wiz CTF stamp 7

No flags are included in this writeup.

Overview

State of Affairs focused on Terraform automation. The challenge was not “find a secret in a .tf file.” It was about understanding Terraform’s state model and how dangerous it becomes when an attacker can influence the state or backend data consumed by automation.

Field Value
Month December 2025
Points 20
Main area Terraform, state poisoning, IaC automation

Terraform State As An Attack Surface

Terraform state is not just metadata. It can influence providers, resources, destruction behavior, and automation decisions. If a workflow periodically runs Terraform in a directory where an attacker can write state-related files, the state becomes an execution surface.

The key idea was winning the race for the Terraform data directory. On a fresh environment, if the expected .terraform structure did not exist yet, creating it first allowed control over what Terraform believed its backend and local state looked like.

Building The Poisoned State

The payload needed three pieces:

  • a .terraform backend metadata file pointing to a controlled local state file
  • a valid-looking state file with a malicious provider/resource entry
  • correct backend hash/metadata so Terraform accepted the structure instead of rejecting it

That last part mattered. Terraform does validate backend configuration, so sloppy state poisoning does not work. The state had to look boring enough for Terraform to proceed.

Letting Automation Do The Work

Once the poisoned structure was in place, the scheduled Terraform automation became the executor.

The flow looked like this:

  1. prepare controlled Terraform metadata/state
  2. wait for automation to run terraform init / apply
  3. Terraform accepts the backend and state
  4. a resource exists in state but not in config
  5. Terraform plans a destroy
  6. the malicious provider executes during the destroy path

That was the interesting mental shift: the exploit did not need to run the privileged command directly. It only needed to shape the state so trusted automation performed the dangerous action.

Root Cause

The core issue was unsafe trust in writable Terraform working directories:

  • Terraform state and backend metadata were created in a location the attacker could control
  • automation trusted existing local state
  • provider execution was allowed during normal Terraform lifecycle actions
  • state contents were treated as operational truth

Takeaways

State of Affairs changed how I think about IaC files. In Terraform-heavy environments, the .tf files are only half of the story. The state and backend metadata deserve the same level of protection.

Defensive checks I would care about:

  • do not run Terraform automation in world-writable directories
  • isolate TF_DATA_DIR
  • treat state files as sensitive and security-critical
  • pin and review providers
  • monitor unexpected backend changes and provider downloads
  • avoid scheduled automation that trusts attacker-writable local state

This challenge was a strong reminder that infrastructure automation is code execution with a nicer UI.