A modular platform for deploying intentionally vulnerable AWS configurations
Quick Start • Lab Catalog • How It Works • Security • Contributing
Pathfinding Labs helps security teams learn how to atttack and defend exploitable identity misconfigurations by deploying intentionally vulnerable cloud resources to sandbox environments.
Full lab catalog, individual lab docs, and guided installation: pathfinding.cloud/labs This README is a quick-start guide and command reference for users working directly from the repository.
- One or more AWS accounts (playground/sandbox accounts only — never use production)
- AWS CLI configured with named profiles for each account
Not sure how to set this up? See the setup guides — whether you're starting from a single account, already have accounts ready, or want to create a full multi-account AWS org.
Note: Creating your own AWS organization is a great opportunity to learn org level features, like SCPs and IAM Identity Center.
Requires Go 1.25+
go install -v github.com/DataDog/pathfinding-labs/cmd/plabs@latest
brew tap DataDog/pathfinding-labs https://github.com/DataDog/pathfinding-labs
brew install DataDog/pathfinding-labs/plabsOS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/amd64/')
VERSION=$(curl -fsSL https://api.github.com/repos/DataDog/pathfinding-labs/releases/latest | grep '"tag_name"' | cut -d'"' -f4 | tr -d 'v')
curl -fsSL "https://github.com/DataDog/pathfinding-labs/releases/download/v${VERSION}/plabs_${VERSION}_${OS}_${ARCH}.tar.gz" | tar -xz plabs
sudo mv plabs /usr/local/bin/git clone https://github.com/DataDog/pathfinding-labs.git
cd pathfinding-labs
go build -o plabs ./cmd/plabs
cp plabs /usr/local/bin/
chmod +x /usr/local/bin/plabs
Downloads terraform, clones repo, runs AWS profile setup wizard
plabs initplabs
In the TUI: use ↑↓ to browse labs, space to enable/disable labs, a to apply changes (deploy the enabled labs, tear down the disabled labs)
Modular Architecture: Each attack lab is a self-contained, independently deployable module that can be enabled or disabled via plabs.
┌─────────────────────────────────────────────────────────┐
│ 1. Select labs (plabs TUI or plabs enable) │
│ space to toggle in TUI, or: plabs enable <id> │
├─────────────────────────────────────────────────────────┤
│ 2. Deploy (plabs apply) │
│ Creates vulnerable resources in your AWS account │
├─────────────────────────────────────────────────────────┤
│ 3. Test (plabs demo <id>) │
│ Exploit OR detect with your CSPM │
├─────────────────────────────────────────────────────────┤
│ 4. Clean Up (plabs disable <id> && │
│ plabs apply) │
└─────────────────────────────────────────────────────────┘
All labs expose credentials and resource information via grouped Terraform outputs. Demo scripts read these automatically — no manual credential setup needed.
All configuration is managed through plabs. There is no need to edit Terraform files directly.
Run the interactive setup wizard (recommended):
plabs initOr set values directly (useful for CI/automation):
plabs config set prod-profile my-prod-profile
plabs config set prod-region us-east-1| Key | Required | Description |
|---|---|---|
prod-profile |
Yes | AWS CLI profile for the prod account |
prod-region |
Yes | AWS region for the prod account |
dev-profile |
No | Dev account profile (cross-account labs only) |
dev-region |
No | Dev account region |
ops-profile |
No | Ops account profile (cross-account labs only) |
ops-region |
No | Ops account region |
You only need ONE AWS account to use most of Pathfinding Labs. All single-account labs deploy to prod. Dev and ops are only required for cross-account labs. See the setup guides if you need help getting accounts and profiles configured.
By default, plabs uses the repository it cloned into ~/.plabs/pathfinding-labs/. If you are contributing and want to test local Terraform changes, enable dev mode from inside the repo:
# Run from inside your cloned pathfinding-labs directory
plabs config set dev-mode true
# plabs now uses local modules instead of ~/.plabs/pathfinding-labs/
plabs config set dev-mode false # revert to the managed copyInteractive (TUI):
plabs # open the dashboard
# ↑↓ to navigate, space to toggle, a to deployCLI:
# Enable by lab ID
plabs enable iam-002-iam-createaccesskey
# Enable multiple at once
plabs enable iam-002-iam-createaccesskey lambda-001-iam-passrole
# Disable
plabs disable iam-002-iam-createaccesskeyplabs apply # shows plan, prompts for confirmation
plabs apply -y # skip confirmation
plabs plan # preview changes without deployingEach lab includes a demonstration script that shows how to exploit the vulnerability.
Using plabs (recommended):
plabs demo iam-002-iam-createaccesskey
plabs cleanup iam-002-iam-createaccesskeyDirectly from the lab directory:
cd modules/scenarios/single-account/privesc-one-hop/to-admin/iam-002-iam-createaccesskey
./demo_attack.sh
./cleanup_attack.shThe demo scripts provide:
- ✅ Step-by-step exploitation walkthrough
- ✅ AWS CLI commands with explanations
- ✅ Real-time verification of privilege escalation
- ✅ Color-coded output for clarity
- ✅ Automatic credential retrieval — no manual AWS profile setup needed
Understanding exactly what Pathfinding Labs creates in your account helps you assess the risk and plan your testing environment appropriately.
Every lab creates IAM principals (users, roles) and policies with deliberate misconfigurations. No existing resources in your account are modified. All created resources use the pl- prefix so they are easy to identify and audit.
Each configured environment gets one dedicated starting user with minimal permissions — this is the simulated attacker's initial foothold:
| User | Environment |
|---|---|
pl-pathfinding-starting-user-prod |
Production |
pl-pathfinding-starting-user-dev |
Development |
pl-pathfinding-starting-user-operations |
Operations |
Starting users are granted only two permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:GetCallerIdentity",
"iam:GetUser"
],
"Resource": "*"
}
]
}Each environment also includes one admin-level user used exclusively by cleanup scripts to revert demo artifacts:
pl-admin-user-for-cleanup-scripts
This user has broad permissions. It exists so cleanup scripts can undo changes made during attack demonstrations (e.g., deleting access keys that were created, reverting modified policies). This is another reason to keep your lab environment isolated from production.
Not all labs expose resources to the internet:
| Category | Network Exposure |
|---|---|
| Privilege escalation (all hops) | None — IAM-only, no network resources |
| CSPM Misconfig / Toxic Combo | Some labs intentionally create public S3 buckets, Lambda function URLs, or open security groups |
Each scenario's README documents what it creates and any public-facing resources.
Most labs are IAM-only and incur no AWS charges. Labs that deploy compute or storage resources (EC2, Lambda, ECS) incur small charges while deployed. Recommended: set a billing alert at $10–20/month as a safety net.
Tear down labs when not actively testing:
plabs disable <id> && plabs apply # disable a specific scenario
plabs destroy # destroy all deployed resourcesAll resources are created only in the accounts and regions you configure via plabs config. Teardown is complete — plabs destroy removes everything Pathfinding Labs created.
All resources follow a consistent naming pattern:
pl-{resource-description}-{context}
Examples:
- pl-pathfinding-starting-user-prod
- pl-cak-admin (CreateAccessKey Admin)
- pl-prod-one-hop-putrolepolicy-role
Globally unique resources (S3 buckets) include a random suffix:
pl-{resource}-{account-id}-{random-6-char}
Example:
- pl-sensitive-data-954976316246-a3f9x2
Pathfinding Labs organizes labs into five categories:
Principal directly modifies itself to gain elevated privileges without traversing to another principal. This is the most direct form of privilege escalation where an entity grants itself additional permissions.
Examples:
Role → iam:PutRolePolicy (on self) → AdminUser → iam:PutUserPolicy (on self) → AdminUser → iam:AddUserToGroup → AdminGroup → AdminRole → iam:AttachRolePolicy (on self) → S3 Bucket Access
Single principal traversal labs where one principal gains access to another principal's privileges. These are single-account labs within the prod environment.
Examples:
Role → iam:CreateAccessKey → AdminUser → AdminRole → iam:PassRole + lambda:CreateFunction → AdminRole → AdminRole → lambda:UpdateFunctionCode → Lambda with Admin Role → AdminRole → ssm:SendCommand → EC2 with Admin Role → Admin
Multiple privilege escalation steps chaining through multiple principals. These are single-account labs within the prod environment.
Examples:
User → sts:AssumeRole → RoleA → iam:CreateAccessKey → UserB → AssumeRole → AdminRoleRoleA → iam:PutRolePolicy → RoleB → AssumeRole → RoleC → Sensitive Bucket
Single-condition security misconfigurations that CSPM tools should detect. These are single-account labs within the prod environment.
Examples:
EC2 Instance with Admin Role- Overly permissive instance profileS3 Bucket (public)- Publicly accessible storageSecurity Group (0.0.0.0/0)- Unrestricted network access
Multiple compounding misconfigurations that together create critical security risks. These are single-account labs within the prod environment.
Examples:
Lambda Function (publicly accessible) + Admin RoleEC2 Instance (publicly accessible) + Critical CVE + Admin RoleS3 Bucket (public) + Sensitive Data + No Encryption
Privilege escalation paths that span multiple AWS accounts (dev, ops, prod). These labs demonstrate how compromise in one account can lead to access in another.
Examples:
Dev:User → AssumeRole → Prod:Role → AdminDev:Role → Lambda:InvokeFunction → Prod:Lambda → Extract Credentials → Prod:AdminOps:User → AssumeRole → Prod:Role → S3:SensitiveBucket
pathfinding-labs/
├── modules/
│ ├── environments/ # Base infrastructure (always deployed)
│ │ ├── prod/ # Production environment base resources
│ │ ├── dev/ # Development environment base resources
│ │ └── operations/ # Operations environment base resources
│ │
│ └── scenarios/ # Attack labs (opt-in via flags)
│ ├── single-account/
│ │ ├── privesc-self-escalation/
│ │ │ ├── to-admin/ # Principal modifies itself to gain admin
│ │ │ └── to-bucket/ # Principal modifies itself for S3 access
│ │ ├── privesc-one-hop/
│ │ │ ├── to-admin/ # Single principal traversal to admin
│ │ │ └── to-bucket/ # Single principal traversal to S3 access
│ │ ├── privesc-multi-hop/
│ │ │ ├── to-admin/ # Multiple principal traversals to admin
│ │ │ └── to-bucket/ # Multiple principal traversals to S3 access
│ │ ├── cspm-misconfig/ # Single-condition security misconfigurations
│ │ └── cspm-toxic-combo/ # Multiple compounding misconfigurations
│ ├── tool-testing/ # Edge cases for testing detection engines
│ ├── ctf/ # Capture-the-flag challenges (no demo scripts)
│ ├── attack-simulation/ # Recreations of real-world cloud breaches
│ └── cross-account/
│ ├── dev-to-prod/ # Dev → Prod attack paths
│ │ ├── one-hop/ # Single-hop cross-account escalation
│ │ └── multi-hop/ # Multi-hop cross-account escalation
│ └── ops-to-prod/ # Ops → Prod attack paths
│ └── one-hop/ # Single-hop cross-account escalation
│
├── main.tf # Root module with conditional instantiation
├── variables.tf # Boolean flags for each scenario
├── outputs.tf # Credential outputs for testing
└── terraform.tfvars # Your configuration (gitignored)
Each lab follows a standard structure:
scenario-name/
├── main.tf # Terraform resources
├── variables.tf # Input variables
├── outputs.tf # Output values
├── README.md # Documentation with mermaid diagrams
├── demo_attack.sh # Exploitation demonstration
└── cleanup_attack.sh # Artifact cleanup script
Each lab documents what a properly configured CSPM should detect:
Expected CSPM Alerts:
⚠️ IAM role can create access keys for privileged users⚠️ Privilege escalation path detected⚠️ Role has permissions on admin user⚠️ Potential for credential theft
MITRE ATT&CK Mapping:
- Tactic: Privilege Escalation, Persistence
- Technique: T1098.001 - Account Manipulation: Additional Cloud Credentials
We welcome contributions! To add a new scenario:
- Create the lab directory following the standard structure
- Implement resources with proper provider configuration
- Write documentation including mermaid diagrams and CSPM detection notes
- Create demo scripts showing the exploitation technique
- Add to main.tf with conditional instantiation
- Add boolean variable to variables.tf
- Update terraform.tfvars.example
- Test thoroughly in an isolated AWS account — enable dev mode (
plabs config set dev-mode true) to use your local copy, thenplabs enable <id> && plabs apply - Submit a pull request with clear description
See our Contributing Guide for detailed instructions.
- ❌ NEVER deploy to production AWS accounts
- ❌ NEVER deploy to accounts with real customer data
- ❌ NEVER deploy to accounts with production workloads
- ✅ ALWAYS use isolated playground/sandbox accounts
- ✅ ALWAYS tear down resources when finished
- ✅ ALWAYS monitor costs and set billing alarms
- Use SCPs to prevent accidental production deployment
- Set up billing alerts to catch unexpected charges
- Use separate AWS Organizations for testing
- Review each scenario before enabling
- Document your testing for compliance and audit purposes
- IAM Vulnerable Project - Inspiration for single-account paths
- MITRE ATT&CK Cloud Matrix
- Stratus Red Team by Datadog
This project is licensed under the Apache License 2.0.