TollBooth / OpenDoor

Scenario 2 of 2 · Proactive audit

OpenDoor — find it before the breach

Same account, same incident — but this time you're auditing the configuration before anything happened, to find the misconfigurations that made TollBooth possible.

Setup (if you closed the terminal)

Open a terminal. cd ~/tollbooth/opendoor. claude. Paste only the prompt text below.

~20 min. CORE phases (1, 3, 5) tell the full story. DEEP phases (2, 4) are for a quiet queue or to run later. No agent? Terminal fallback commands are at the bottom.

Phase 1 Core

Full configuration audit

Paste this, then Enter:

Using your cloud-audit skills, audit every AWS config file in this folder: the S3 bucket policy, the IAM role's permissions, and the EC2 instance-metadata setting. Map each misconfiguration to its CIS control AND its NIST CSF 2.0 category. List the skills you used.

You will see: three findings — a public S3 bucket, an over-permissioned IAM role, and IMDSv1 still allowed — each tagged with a CIS control and a CSF category.

Checkpoint — on track when you see

Three findings: bucket policy Principal '*' + Public Access Block all-false (public S3, CIS 2.1.4 / CSF PR.PS); IAM with PutRolePolicy/ AttachRolePolicy/PassRole on * (self-privesc, CIS 1.15 — not 1.16, that's stale v1.5 numbering / CSF PR.AA); MetadataOptions.HttpTokens='optional' (IMDSv1, CIS 5.7 — not 5.6, that's stale v3.0 numbering / CSF PR.PS). CIS numbers drift between benchmark versions — always confirm against the current release (v5.0.0), never quote from memory.

Reveal the answer

Public bucket: 'PublicRead' (Principal *) + Block Public Access all-false. CIS v5.0.0 2.1.4 (S3 Block Public Access) / CSF PR.PS.

IAM privesc: 'TooBroad' = PutRolePolicy/AttachRolePolicy/PassRole on * (role can self-admin). CIS v5.0.0 1.15 (full-admin IAM policy attached — 1.16 in the current benchmark is an unrelated AWS-Support-role control, an easy stale-number mistake) / CSF PR.AA.

IMDSv1: HttpTokens='optional'. CIS v5.0.0 5.7 (EC2 Metadata Service IMDSv2-only — 5.6 in the current benchmark is VPC peering routing, also unrelated) / CSF PR.PS.

Phase 2 Deep

Rank by blast radius

Same chat:

Of those findings, which single one is most dangerous, and why? Rank all three by how much damage each enables on its own.

You will see: reasoning about which matters most — credential theft vs. self-admin IAM vs. public data exposure.

Checkpoint — on track when you see

A defended ordering. Reasonable top pick: IMDSv1, because it's the actual entry point for credential theft. The point is the reasoning, not one "right" order.

Reveal the answer

Defensible top pick = IMDSv1: it's the live entry point (creds actually stolen through it). IAM privesc = highest potential (full admin) but unused. Public bucket = real exposure, but not the path here.

Phase 3 Core

Correlate with the breach

Same chat:

Now look at ../lab-tollbooth.pcap and ../cloudtrail: for each misconfiguration, did the attacker EXPLOIT it, only PROBE it, or IGNORE it? Show me the evidence for each.

You will see: IMDSv1 exploited, the IAM role only probed, the public bucket bypassed — and they are not all the same.

Checkpoint — on track when you see

Each finding labelled exploited / probed / bypassed with log evidence — and they are deliberately not all the same.

Reveal the answer

IMDSv1 = exploited (creds stolen, used from 203.0.113.66). IAM = probed only (enumeration, no PutRolePolicy in logs). Public bucket = bypassed (see Phase 4).

Phase 4 Deep

Check the agent's call

Same chat:

Double-check the public bucket: the data WAS stolen, so was the public policy actually the path? Check whether the exfil requests were anonymous or authenticated with the stolen key.

You will see: the theft was authenticated with the stolen key — the public policy was not the route. A latent exposure, not the breach path. Correct the agent if it said "exploited."

Checkpoint — on track when you see

The exfil GetObjects are authenticated (stolen key), not anonymous — so the public policy was not the path. If the agent said the bucket was "exploited," this is where you correct it.

Reveal the answer

Exfil GetObjects are authenticated with the stolen key, not anonymous — the public policy was never used. The bucket is a latent exposure, not the breach route. Agents often mis-call this "exploited" — this is the deliberate catch in this phase.

Phase 5 Core

Prioritized remediation

Same chat:

Give me a prioritized fix list: what to change FIRST to break the actual attack, versus what to fix because it is a latent risk even though it was not used here. For each fix, name the MITRE D3FEND countermeasure technique it implements.

You will see: IMDSv2 first (breaks the real chain); tighten IAM; close the public bucket anyway — each tied to a D3FEND ID.

Checkpoint — on track when you see

Ordered by real risk: IMDSv2 first (breaks the chain), then IAM least-privilege, then close the public bucket (latent).

Reveal the answer

1) HttpTokens=required (IMDSv2) — breaks the chain. D3FEND: D3-ITF (inbound traffic filtering on the /proxy SSRF).

2) Remove iam:* on *. D3FEND: no direct technique — this is an authorization-scoping fix, not a traffic control.

3) Block Public Access + drop Principal *. D3FEND: D3-OTF (outbound/access filtering on the bucket).

Explore without spoiling it

jq '.Statement[].Principal' s3-bucket-policy.json                              # any wildcard?
jq '.Reservations[].Instances[].MetadataOptions.HttpTokens' ec2-metadata-options.json

Terminal fallbacks (no agent)

jq -r '.Statement[]|select(.Principal=="*")|.Sid' s3-bucket-policy.json        # public grant
jq -r '.Reservations[].Instances[].MetadataOptions.HttpTokens' ec2-metadata-options.json
cat ../cloudtrail/*.json | jq -r '.Records[]|select(.sourceIPAddress=="203.0.113.66")|.eventName'

Authorized & lawful use only. All data is synthetic and self-contained; no live systems are touched. Promotes the open-source Anthropic Cybersecurity Skills library (Apache-2.0); not affiliated with Anthropic PBC.

← Back to Scenario 1: TollBooth