Module S10 — Cloud Red Team Harness Engineering

Course: 2A — Building AI Harnesses for Cybersecurity Module: S10 — Cloud Red Team Harness Engineering Duration: 60 minutes Level: Senior Engineer and above Prerequisites: S00–S09 complete

A harness that attacks the cloud the way cloud adversaries do — API-first, identity-first, no port scanning. The cloud kill chain from reconnaissance to impact. IAM privilege escalation as graph path-finding. And evidence collected to a schema that maps directly to SOC 2, ISO 27001, and PCI DSS for the client deliverable.


Learning Objectives

  1. Articulate how a cloud offensive harness differs from a network pentest harness (API-first, identity-first, no port scanning) and execute the cloud kill chain under scope enforcement.
  2. Build an IAM privilege escalation path-finder that enumerates reachable permissions from a starting identity and chains iam:PassRole, CreatePolicy, and AttachRolePolicy into escalation paths.
  3. Design a cloud evidence schema that captures API call, response, timestamp, account, region, and resource ARN, and map findings to SOC 2, ISO 27001, and PCI DSS for the client deliverable.

S10.1 — Cloud-Specific Offensive Architecture

A network pentest harness scans ports, enumerates services, and exploits vulnerabilities in running software. A cloud red team harness does none of these things. The cloud is not a network — it is an API. The attack surface is not open ports; it is identities, permissions, and configurations. The cloud offensive harness is built on a fundamentally different architecture.

API-first, identity-first, no port scanning

The defining difference is the attack surface boundary. In a network pentest, the boundary is the network — hosts, ports, services. In a cloud engagement, the boundary is the identity layer — which principals exist, what they can do, what they can assume, and what is exposed. Port scanning is irrelevant. An AWS account has no ports to scan. It has IAM policies to enumerate, roles to map, and API endpoints to query.

The cloud offensive harness is API-first: every action is an API call against the cloud provider's control plane, not a packet against a network interface. It is identity-first: the primary attack surface is IAM — users, roles, policies, and trust relationships — not the compute infrastructure. And it does no port scanning: the reconnaissance phase enumerates cloud resources and permissions via provider APIs (AWS API, Azure ARM, GCP API), not via nmap.

This changes the tool suite. The S02 bug bounty harness wrapped nmap, httpx, nuclei, ffuf. The S10 cloud red team harness wraps a different set of tools entirely:

Tool Cloud Purpose
Prowler AWS, Azure, GCP CIS benchmark and cloud security configuration checks
ScoutSuite Multi-cloud Audits configuration across AWS, Azure, GCP; builds a visual attack surface
Pacu AWS The AWS exploitation framework; IAM escalation, post-exploitation
Stormspotter Azure Azure attack graph builder; maps identity and resource relationships
GCP IAM Recommender GCP Identifies over-privileged service accounts and recommends least-privilege

Each tool is wrapped as a harness tool following the S02.2 pattern: Pydantic-typed input, scope-checked against the engagement authorization, rate-limited, and evidence-logged. The wrapping is what makes these offensive tools safe to run under authorization — the scope check is the legal boundary.

The cloud kill chain

The cloud kill chain mirrors the network kill chain in phases but differs in execution at each phase:

Reconnaissance          → Enumerate public assets, identities, permissions via API
    ↓
Initial Access          → Exploit exposed service or compromised credential
    ↓
Privilege Escalation    → IAM abuse (iam:PassRole, policy manipulation)
    ↓
Lateral Movement        → Cross-account, cross-service pivots via trust relationships
    ↓
Impact                  → Data exfiltration, resource hijacking, persistence

The harness automates each phase under scope enforcement. The scope file defines the account boundaries, region constraints, and service exclusions. Every API call is checked against the scope before execution — the same S00.3 scope enforcement middleware, adapted for cloud API calls.

Scope enforcement in cloud contexts

Cloud scope is defined by account boundaries, region constraints, and service exclusions. A typical cloud engagement scope file:

engagement_id: "cloud-redteam-2026-q3"
cloud_provider: "aws"
account_boundaries:
  - account_id: "123456789012"    # the target lab account
    description: "Client AWS lab account"
    authorized: true
  - account_id: "000000000000"    # any other account
    authorized: false
region_constraints:
  allowed: ["us-east-1", "us-west-2"]
  denied: ["us-gov-*"]            # never touch govcloud
service_exclusions:
  - "iam:DeleteRole"              # destructive — never
  - "s3:DeleteBucket"             # destructive — never
  - "ec2:TerminateInstances"      # impact action — never without explicit approval
rate_limit:
  max_api_calls_per_second: 10

The scope check runs before every API call. An attempt to enumerate or act on an out-of-scope account is blocked. A call to a denied region is blocked. A destructive API call (DeleteRole, DeleteBucket, TerminateInstances) is blocked unconditionally unless the scope file explicitly authorizes it with a separate approval. The scope file is the legal boundary; the middleware enforces it.

The scope middleware is the same architectural pattern from S00.3 and S02.2, adapted for cloud API calls. In a network pentest, scope is enforced at the IP level — only scan in-scope IPs. In a cloud engagement, scope is enforced at the API level — only call APIs against in-scope accounts, regions, and services. The middleware intercepts every outbound API call, checks it against the scope file, and blocks or permits. This is not advisory; it is a hard boundary. A misconfiguration in the harness (a tool pointing at the wrong account, an escalation technique that crosses an account boundary) is caught by the middleware before any unauthorized action occurs.

The destructive-action blocking deserves emphasis. An authorized cloud engagement demonstrates paths to impact — it does not cause impact. A finding that an adversary could delete a production database is demonstrated by showing the identity has the permission, not by deleting the database. The scope file blocks destructive calls unconditionally. Even if the harness has valid credentials and the identity has the permission, the middleware prevents rds:DeleteDBInstance, ec2:TerminateInstances, s3:DeleteBucket from executing. This is what separates a red team engagement from an actual attack — the restraint is engineered into the harness, not left to operator discipline.


S10.2 — IAM Privilege Escalation Harnesses

IAM is the primary attack surface in cloud environments. Not the network, not the compute, not the storage — the identity and access management layer. A cloud breach is almost always an IAM abuse: an over-privileged role used to access data it should not, a trust relationship exploited to assume a more powerful identity, a permission chain that escalates from low-privilege to admin. The IAM privilege escalation harness automates finding these chains.

Privilege escalation paths

The canonical AWS privilege escalation paths are documented and finite. The harness enumerates which paths are available from a given starting identity and chains them:

Each path is a node-and-edge graph: the current identity's permissions are the starting edges, each escalation technique is a transition to a more privileged state, and the goal is a permission set that reaches the target (e.g., s3:GetObject on a sensitive bucket, or *:* for full admin).

Graph-based PE path finding

The harness models privilege escalation as graph traversal — the same technique as S09.2's attack-path analysis, applied to the IAM layer:

from collections import deque

class PrivilegeGraph:
    def __init__(self, identity_arn: str, permissions: set[str]):
        self.start = identity_arn
        self.permissions = permissions  # e.g. {"iam:PassRole", "lambda:CreateFunction", ...}
        self.escalation_techniques = self._load_techniques()

    def _load_techniques(self) -> list[dict]:
        """Load the known IAM escalation techniques and their requirements."""
        return [
            {
                "name": "PassRole + Lambda",
                "requires": {"iam:PassRole", "lambda:CreateFunction", "lambda:InvokeFunction"},
                "grants": "execution-role-permissions",
            },
            {
                "name": "CreatePolicy + AttachRolePolicy",
                "requires": {"iam:CreatePolicy", "iam:AttachRolePolicy", "iam:ListAttachedRolePolicies"},
                "grants": "*:*",
            },
            {
                "name": "UpdateAssumeRolePolicy",
                "requires": {"iam:UpdateAssumeRolePolicy"},
                "grants": "target-role-permissions",
            },
        ]

    def find_escalation_paths(self, target_permissions: set[str]) -> list[list[str]]:
        """BFS from current permissions to target permissions via escalation techniques."""
        paths = []
        queue = deque([(self.start, list(self.permissions), [])])
        visited = {frozenset(self.permissions)}

        while queue:
            identity, current_perms, path = queue.popleft()
            if target_permissions.issubset(set(current_perms)):
                paths.append(path)
                continue
            if len(path) >= 5:  # depth limit
                continue
            for tech in self.escalation_techniques:
                if tech["requires"].issubset(set(current_perms)):
                    new_perms = current_perms + [tech["grants"]]
                    key = frozenset(new_perms)
                    if key not in visited:
                        visited.add(key)
                        queue.append((identity, new_perms, path + [tech["name"]]))
        return paths

The graph is the IAM permission space. Nodes are permission sets. Edges are escalation techniques that transition from one permission set to a more powerful one. The path-finding searches from the starting identity's permissions to the target permissions (the goal state). The output is the list of escalation chains — the exact sequence of techniques that would take an adversary from initial access to the target.

Tools: Pacu and Stormspotter

Pacu is the AWS exploitation framework. It implements many of these escalation techniques as modules — iam__privesc_scan enumerates the current identity's permissions and identifies available escalation paths. Stormspotter is the Azure equivalent: it builds a graph of Azure identities and resources and visualizes the attack surface. Both produce structured output that the harness consumes.

The harness wraps Pacu/Stormspotter as tools, feeds their output into the privilege graph, and produces a structured escalation-path report. The harness adds what the tools alone do not provide: the chain reasoning (which paths combine), the scope enforcement (every API call is checked), and the evidence schema (every action is logged for the client report).

Evidence collection for IAM escalation paths

Every escalation path the harness identifies must be backed by evidence — not asserted, demonstrated. The evidence schema captures the API call, the response, the timestamp, the account, the region, and the resource ARN. For an iam:PassRole escalation, the evidence is: the GetRole API call showing the identity has PassRole permission, the Lambda creation showing the role was passed, the Lambda invocation showing the escalation succeeded, and the response showing the elevated access worked.

This evidence is what distinguishes a demonstrated escalation path from a theoretical one. The client does not need to trust the harness's assertion that "Role-A can escalate to admin." The evidence shows the exact API calls, in order, that achieve it. Reproducible, verifiable, client-presentable. This is S02.3's evidence chain engineering, applied to the cloud context.

The difference between demonstrated and theoretical

A theoretical escalation path is a hypothesis: "given these permissions, this technique should work." A demonstrated escalation path is a proof: "these API calls were made, in this order, and the response confirms the escalation succeeded." The difference matters for three reasons.

First, the client's remediation depends on the proof. A theoretical path might not be exploitable in the specific environment — there may be a guardrail (a service control policy, a permissions boundary) that blocks the technique in practice. The demonstration either succeeds (confirming the path is real and the remediation is urgent) or fails (revealing the guardrail, which is itself a finding about defense-in-depth). Second, the auditor needs reproducibility. A compliance review may ask to see the evidence months after the engagement. The hash-chained evidence log, with exact API calls and responses, is reproducible — anyone with the credentials can re-run the sequence and confirm the result. Third, the engineering team needs to verify the fix. After remediation (removing the over-permissive PassRole permission), the team re-runs the evidence sequence to confirm the escalation no longer works. The fix is verified against the same evidence that demonstrated the vulnerability.


S10.3 — Findings, Evidence, and Client Deliverables

The cloud red team engagement produces findings — demonstrated paths from initial access to impact. Each finding must be structured, evidenced, and mapped to compliance frameworks for the client deliverable. The evidence schema and the compliance mapping are what make the findings actionable for the client's auditor, not just interesting to the client's security team.

The cloud evidence schema

Every finding is backed by a chain of evidence records. The cloud evidence schema extends S02.3's hash-chained evidence log with cloud-specific fields:

interface CloudEvidenceRecord {
  // Identification
  id: string;
  trace_id: string;
  session_id: string;

  // What happened (cloud-specific)
  timestamp: string;          // UTC ISO 8601
  cloud_provider: "aws" | "azure" | "gcp";
  account_id: string;
  region: string;
  api_call: string;           // e.g. "iam:GetRole", "s3:GetObject"
  resource_arn: string;       // the specific resource acted upon
  actor_arn: string;          // which identity made the call

  // What was sent and received
  request: string;            // exact API request (parameters)
  response: string;           // exact API response
  http_status: number;

  // Legal anchor
  scope_ref: string;          // which scope entry authorized this call

  // Finding linkage
  finding_id: string | null;
  impact_assessment: string | null;

  // Tamper-evidence
  previous_hash: string;
  record_hash: string;

  // Retention
  retention_class: "public" | "redacted" | "restricted";
  retention_expires: string | null;
}

The account_id, region, api_call, and resource_arn fields are the cloud-specific additions. They make the evidence precise: not just "a call was made," but "the call s3:GetObject was made against arn:aws:s3:::client-sensitive-data in us-east-1 from account 123456789012 at this exact timestamp, authorized by this scope entry, producing this exact response." The hash chain (from S02.3) ensures tamper-evidence — no record can be altered without breaking the chain.

Mapping cloud findings to compliance frameworks

The client's auditor does not care about iam:PassRole chains. The auditor cares whether the organization meets SOC 2, ISO 27001, or PCI DSS requirements. The finding-to-framework mapping is what translates the red team's technical findings into the auditor's compliance language:

COMPLIANCE_MAPPING = {
    "iam_over_privilege": {
        "soc2": "CC6.3 — The entity authorizes, modifies, or removes access to data",
        "iso27001": "A.9.2.5 — Review of user access rights",
        "pci_dss": "7.2.1 — Establish an access control system for systems components",
    },
    "public_exposure": {
        "soc2": "CC6.1 — The entity implements logical access controls",
        "iso27001": "A.13.1.1 — Network controls",
        "pci_dss": "1.2.1 — Restrict inbound/outbound traffic",
    },
    "privilege_escalation_path": {
        "soc2": "CC6.3 — Authorization of access (escalation path violates least privilege)",
        "iso27001": "A.9.4.4 — Use of privileged utility programs",
        "pci_dss": "7.1.1 — Define access needs for each role (escalation path exceeds defined needs)",
    },
    "missing_encryption": {
        "soc2": "CC6.7 — The entity restricts physical access to data (transmission protection)",
        "iso27001": "A.10.1.1 — Policy on the use of cryptographic controls",
        "pci_dss": "3.4 — Render PAN unreadable wherever it is stored",
    },
}

def map_finding_to_compliance(finding_type: str) -> dict:
    return COMPLIANCE_MAPPING.get(finding_type, {
        "soc2": "Review required — no direct control mapping",
        "iso27001": "Review required — no direct control mapping",
        "pci_dss": "Review required — no direct control mapping",
    })

Each finding type maps to specific controls in each framework. An over-privileged IAM role is not just "a misconfiguration" — it is a violation of SOC 2 CC6.3 (access authorization), ISO 27001 A.9.2.5 (access rights review), and PCI DSS 7.2.1 (access control system). This mapping makes the finding immediately actionable for the compliance team: they know which control is at risk and what the remediation satisfies.

Client report structure

The cloud red team client deliverable follows a structure that serves both technical and executive audiences:

  1. Executive summary. The overall risk assessment: what was tested, what was found, the business impact, and the prioritized remediation roadmap. One page, non-technical language, framed in risk and compliance terms.
  2. Finding table. Each finding: ID, title, severity, affected resource, compliance mapping, status. The structured overview the technical team uses to track remediation.
  3. Attack narrative. For each significant finding, the step-by-step story: how the initial access was obtained, how the escalation chain proceeded, what the impact would be. The narrative is backed by the evidence chain — each step references the specific evidence records that demonstrate it.
  4. Remediation roadmap. Prioritized actions, mapped to the finding table and compliance frameworks. What to fix first (critical paths), what to fix next (medium findings), and what to accept as residual risk.

The report is generated from the structured findings and evidence store — not written by hand. The evidence chain ensures every claim in the narrative is backed by a reproducible API call sequence. The compliance mapping ensures every finding speaks the auditor's language. This is what makes the deliverable client-ready: technical depth for the engineers, executive framing for the CISO, and compliance language for the auditors.


Anti-Patterns

The network-pentest-in-the-cloud

Running nmap against cloud infrastructure. The cloud is not a network — it is an API. Port scanning finds nothing useful and wastes engagement time. Cure: API-first, identity-first offensive architecture (S10.1).

The unscooped cloud engagement

Running enumeration and exploitation without account boundaries enforced. The harness touches a production account or a denied region. Cure: scope enforcement middleware on every API call, with account boundaries and service exclusions (S10.1).

The theoretical escalation path

Reporting "Role-A could escalate to admin" without demonstrating it. The client cannot verify the claim; the auditor cannot use it. Cure: evidence-collected escalation paths with exact API call sequences (S10.2, S10.3).

The compliance-unmapped finding

A finding described technically ("iam:PassRole chain allows S3 access") with no compliance mapping. The auditor does not know which control is at risk. Cure: the finding-to-framework mapping (S10.3) — every finding speaks SOC 2, ISO 27001, and PCI DSS.


Key Terms

Term Definition
API-first Cloud offensive architecture where every action is an API call against the control plane, not a network packet
Identity-first The IAM layer (users, roles, policies, trust relationships) is the primary attack surface in cloud environments
Cloud kill chain Recon → Initial Access → Privilege Escalation → Lateral Movement → Impact; executed via API, not network
IAM escalation path A chain of IAM permission abuses that transitions from low privilege to high privilege (e.g., PassRole + Lambda)
Privilege graph Graph of permission sets (nodes) and escalation techniques (edges); BFS finds paths from start to target
Cloud evidence schema Hash-chained evidence records with account_id, region, api_call, resource_arn — reproducible and verifiable
Compliance mapping Translation of technical findings to SOC 2, ISO 27001, and PCI DSS control references for the auditor

Lab Exercise

See 07-lab-spec.md. Three labs: (1) cloud offensive harness configuration with scope enforcement and full kill chain enumeration; (2) IAM privilege escalation path-finder; (3) client-ready report generation with evidence schema and compliance mapping.


References

  1. Pacu — the AWS exploitation framework. IAM escalation modules, post-exploitation.
  2. Stormspotter — Azure attack graph builder. Maps identity and resource relationships.
  3. Prowler, ScoutSuite — cloud configuration auditing across AWS, Azure, GCP.
  4. Rhino Security Labs — AWS IAM Privilege Escalation methods. The canonical documentation of IAM escalation techniques.
  5. S02.2 — Harness tool wrapping. Pacu/Stormspotter are wrapped with the same Pydantic-schema + scope-check pattern.
  6. S02.3 — Evidence chain engineering. The hash-chained evidence log; S10 extends it with cloud-specific fields.
  7. S09.2 — Attack path analysis. The graph-based path-finding technique; S10.2 applies it to the IAM layer.
# Module S10 — Cloud Red Team Harness Engineering

**Course**: 2A — Building AI Harnesses for Cybersecurity
**Module**: S10 — Cloud Red Team Harness Engineering
**Duration**: 60 minutes
**Level**: Senior Engineer and above
**Prerequisites**: S00–S09 complete

> *A harness that attacks the cloud the way cloud adversaries do — API-first, identity-first, no port scanning. The cloud kill chain from reconnaissance to impact. IAM privilege escalation as graph path-finding. And evidence collected to a schema that maps directly to SOC 2, ISO 27001, and PCI DSS for the client deliverable.*

---

## Learning Objectives

1. Articulate how a cloud offensive harness differs from a network pentest harness (API-first, identity-first, no port scanning) and execute the cloud kill chain under scope enforcement.
2. Build an IAM privilege escalation path-finder that enumerates reachable permissions from a starting identity and chains iam:PassRole, CreatePolicy, and AttachRolePolicy into escalation paths.
3. Design a cloud evidence schema that captures API call, response, timestamp, account, region, and resource ARN, and map findings to SOC 2, ISO 27001, and PCI DSS for the client deliverable.

---

# S10.1 — Cloud-Specific Offensive Architecture

A network pentest harness scans ports, enumerates services, and exploits vulnerabilities in running software. A cloud red team harness does none of these things. The cloud is not a network — it is an API. The attack surface is not open ports; it is identities, permissions, and configurations. The cloud offensive harness is built on a fundamentally different architecture.

## API-first, identity-first, no port scanning

The defining difference is the attack surface boundary. In a network pentest, the boundary is the network — hosts, ports, services. In a cloud engagement, the boundary is the identity layer — which principals exist, what they can do, what they can assume, and what is exposed. Port scanning is irrelevant. An AWS account has no ports to scan. It has IAM policies to enumerate, roles to map, and API endpoints to query.

The cloud offensive harness is API-first: every action is an API call against the cloud provider's control plane, not a packet against a network interface. It is identity-first: the primary attack surface is IAM — users, roles, policies, and trust relationships — not the compute infrastructure. And it does no port scanning: the reconnaissance phase enumerates cloud resources and permissions via provider APIs (AWS API, Azure ARM, GCP API), not via nmap.

This changes the tool suite. The S02 bug bounty harness wrapped nmap, httpx, nuclei, ffuf. The S10 cloud red team harness wraps a different set of tools entirely:

| Tool | Cloud | Purpose |
| --- | --- | --- |
| **Prowler** | AWS, Azure, GCP | CIS benchmark and cloud security configuration checks |
| **ScoutSuite** | Multi-cloud | Audits configuration across AWS, Azure, GCP; builds a visual attack surface |
| **Pacu** | AWS | The AWS exploitation framework; IAM escalation, post-exploitation |
| **Stormspotter** | Azure | Azure attack graph builder; maps identity and resource relationships |
| **GCP IAM Recommender** | GCP | Identifies over-privileged service accounts and recommends least-privilege |

Each tool is wrapped as a harness tool following the S02.2 pattern: Pydantic-typed input, scope-checked against the engagement authorization, rate-limited, and evidence-logged. The wrapping is what makes these offensive tools safe to run under authorization — the scope check is the legal boundary.

## The cloud kill chain

The cloud kill chain mirrors the network kill chain in phases but differs in execution at each phase:

```
Reconnaissance          → Enumerate public assets, identities, permissions via API
    ↓
Initial Access          → Exploit exposed service or compromised credential
    ↓
Privilege Escalation    → IAM abuse (iam:PassRole, policy manipulation)
    ↓
Lateral Movement        → Cross-account, cross-service pivots via trust relationships
    ↓
Impact                  → Data exfiltration, resource hijacking, persistence
```

- **Reconnaissance.** Enumerate the target's public assets (S3 buckets, API Gateways, exposed endpoints), identities (IAM users, roles, service accounts), and permissions (what each identity can do). Done entirely through provider APIs — `ListBuckets`, `GetRole`, `ListAttachedRolePolicies`. No network scanning.
- **Initial Access.** Gain a foothold. An exposed service with a vulnerability, a compromised credential (leaked access key, over-permissive service account token), or a public resource that accepts unauthenticated interaction.
- **Privilege Escalation.** The core of cloud offense. From the initial access identity, abuse IAM permissions to gain higher privilege. This is S10.2 in detail.
- **Lateral Movement.** Pivot from the compromised identity to other identities and resources. Cross-account via trust relationships (Role-A in account X can be assumed by Role-B in account Y). Cross-service via shared VPCs, peering connections, or over-broad security groups.
- **Impact.** Data exfiltration (download from S3/RDS), resource hijacking (cryptomining via EC2/GPU instances), or persistence (create new IAM users or roles with backdoor access that survive credential rotation).

The harness automates each phase under scope enforcement. The scope file defines the account boundaries, region constraints, and service exclusions. Every API call is checked against the scope before execution — the same S00.3 scope enforcement middleware, adapted for cloud API calls.

## Scope enforcement in cloud contexts

Cloud scope is defined by account boundaries, region constraints, and service exclusions. A typical cloud engagement scope file:

```yaml
engagement_id: "cloud-redteam-2026-q3"
cloud_provider: "aws"
account_boundaries:
  - account_id: "123456789012"    # the target lab account
    description: "Client AWS lab account"
    authorized: true
  - account_id: "000000000000"    # any other account
    authorized: false
region_constraints:
  allowed: ["us-east-1", "us-west-2"]
  denied: ["us-gov-*"]            # never touch govcloud
service_exclusions:
  - "iam:DeleteRole"              # destructive — never
  - "s3:DeleteBucket"             # destructive — never
  - "ec2:TerminateInstances"      # impact action — never without explicit approval
rate_limit:
  max_api_calls_per_second: 10
```

The scope check runs before every API call. An attempt to enumerate or act on an out-of-scope account is blocked. A call to a denied region is blocked. A destructive API call (DeleteRole, DeleteBucket, TerminateInstances) is blocked unconditionally unless the scope file explicitly authorizes it with a separate approval. The scope file is the legal boundary; the middleware enforces it.

The scope middleware is the same architectural pattern from S00.3 and S02.2, adapted for cloud API calls. In a network pentest, scope is enforced at the IP level — only scan in-scope IPs. In a cloud engagement, scope is enforced at the API level — only call APIs against in-scope accounts, regions, and services. The middleware intercepts every outbound API call, checks it against the scope file, and blocks or permits. This is not advisory; it is a hard boundary. A misconfiguration in the harness (a tool pointing at the wrong account, an escalation technique that crosses an account boundary) is caught by the middleware before any unauthorized action occurs.

The destructive-action blocking deserves emphasis. An authorized cloud engagement demonstrates paths to impact — it does not cause impact. A finding that an adversary could delete a production database is demonstrated by showing the identity has the permission, not by deleting the database. The scope file blocks destructive calls unconditionally. Even if the harness has valid credentials and the identity has the permission, the middleware prevents `rds:DeleteDBInstance`, `ec2:TerminateInstances`, `s3:DeleteBucket` from executing. This is what separates a red team engagement from an actual attack — the restraint is engineered into the harness, not left to operator discipline.

---

# S10.2 — IAM Privilege Escalation Harnesses

IAM is the primary attack surface in cloud environments. Not the network, not the compute, not the storage — the identity and access management layer. A cloud breach is almost always an IAM abuse: an over-privileged role used to access data it should not, a trust relationship exploited to assume a more powerful identity, a permission chain that escalates from low-privilege to admin. The IAM privilege escalation harness automates finding these chains.

## Privilege escalation paths

The canonical AWS privilege escalation paths are documented and finite. The harness enumerates which paths are available from a given starting identity and chains them:

- **`iam:PassRole` + service creation.** If an identity has `iam:PassRole` and can create a service (Lambda, EC2), it can pass a more privileged role to the new service and act through it. Pass a role with `s3:*` to a new Lambda, invoke the Lambda, read every bucket.
- **`iam:CreatePolicy` / `iam:AttachRolePolicy`.** If an identity can create policies and attach them, it can grant itself any permission. Create a policy with `*:*`, attach it to its own role.
- **`iam:UpdateAssumeRolePolicy`.** If an identity can modify a role's trust policy, it can add itself as a trusted principal and assume the role — gaining whatever permissions that role has.
- **`lambda:InvokeFunction` chains.** A Lambda that has access to resources the current identity cannot reach. Invoke it with a crafted payload to act through the Lambda's execution role.
- **`sts:AssumeRole` chains.** A role whose trust policy permits assumption by the current identity. Assume it, gain its permissions, look for further escalation from the new position.

Each path is a node-and-edge graph: the current identity's permissions are the starting edges, each escalation technique is a transition to a more privileged state, and the goal is a permission set that reaches the target (e.g., `s3:GetObject` on a sensitive bucket, or `*:*` for full admin).

## Graph-based PE path finding

The harness models privilege escalation as graph traversal — the same technique as S09.2's attack-path analysis, applied to the IAM layer:

```python
from collections import deque

class PrivilegeGraph:
    def __init__(self, identity_arn: str, permissions: set[str]):
        self.start = identity_arn
        self.permissions = permissions  # e.g. {"iam:PassRole", "lambda:CreateFunction", ...}
        self.escalation_techniques = self._load_techniques()

    def _load_techniques(self) -> list[dict]:
        """Load the known IAM escalation techniques and their requirements."""
        return [
            {
                "name": "PassRole + Lambda",
                "requires": {"iam:PassRole", "lambda:CreateFunction", "lambda:InvokeFunction"},
                "grants": "execution-role-permissions",
            },
            {
                "name": "CreatePolicy + AttachRolePolicy",
                "requires": {"iam:CreatePolicy", "iam:AttachRolePolicy", "iam:ListAttachedRolePolicies"},
                "grants": "*:*",
            },
            {
                "name": "UpdateAssumeRolePolicy",
                "requires": {"iam:UpdateAssumeRolePolicy"},
                "grants": "target-role-permissions",
            },
        ]

    def find_escalation_paths(self, target_permissions: set[str]) -> list[list[str]]:
        """BFS from current permissions to target permissions via escalation techniques."""
        paths = []
        queue = deque([(self.start, list(self.permissions), [])])
        visited = {frozenset(self.permissions)}

        while queue:
            identity, current_perms, path = queue.popleft()
            if target_permissions.issubset(set(current_perms)):
                paths.append(path)
                continue
            if len(path) >= 5:  # depth limit
                continue
            for tech in self.escalation_techniques:
                if tech["requires"].issubset(set(current_perms)):
                    new_perms = current_perms + [tech["grants"]]
                    key = frozenset(new_perms)
                    if key not in visited:
                        visited.add(key)
                        queue.append((identity, new_perms, path + [tech["name"]]))
        return paths
```

The graph is the IAM permission space. Nodes are permission sets. Edges are escalation techniques that transition from one permission set to a more powerful one. The path-finding searches from the starting identity's permissions to the target permissions (the goal state). The output is the list of escalation chains — the exact sequence of techniques that would take an adversary from initial access to the target.

## Tools: Pacu and Stormspotter

Pacu is the AWS exploitation framework. It implements many of these escalation techniques as modules — `iam__privesc_scan` enumerates the current identity's permissions and identifies available escalation paths. Stormspotter is the Azure equivalent: it builds a graph of Azure identities and resources and visualizes the attack surface. Both produce structured output that the harness consumes.

The harness wraps Pacu/Stormspotter as tools, feeds their output into the privilege graph, and produces a structured escalation-path report. The harness adds what the tools alone do not provide: the chain reasoning (which paths combine), the scope enforcement (every API call is checked), and the evidence schema (every action is logged for the client report).

## Evidence collection for IAM escalation paths

Every escalation path the harness identifies must be backed by evidence — not asserted, demonstrated. The evidence schema captures the API call, the response, the timestamp, the account, the region, and the resource ARN. For an `iam:PassRole` escalation, the evidence is: the GetRole API call showing the identity has PassRole permission, the Lambda creation showing the role was passed, the Lambda invocation showing the escalation succeeded, and the response showing the elevated access worked.

This evidence is what distinguishes a demonstrated escalation path from a theoretical one. The client does not need to trust the harness's assertion that "Role-A can escalate to admin." The evidence shows the exact API calls, in order, that achieve it. Reproducible, verifiable, client-presentable. This is S02.3's evidence chain engineering, applied to the cloud context.

## The difference between demonstrated and theoretical

A theoretical escalation path is a hypothesis: "given these permissions, this technique should work." A demonstrated escalation path is a proof: "these API calls were made, in this order, and the response confirms the escalation succeeded." The difference matters for three reasons.

First, the client's remediation depends on the proof. A theoretical path might not be exploitable in the specific environment — there may be a guardrail (a service control policy, a permissions boundary) that blocks the technique in practice. The demonstration either succeeds (confirming the path is real and the remediation is urgent) or fails (revealing the guardrail, which is itself a finding about defense-in-depth). Second, the auditor needs reproducibility. A compliance review may ask to see the evidence months after the engagement. The hash-chained evidence log, with exact API calls and responses, is reproducible — anyone with the credentials can re-run the sequence and confirm the result. Third, the engineering team needs to verify the fix. After remediation (removing the over-permissive PassRole permission), the team re-runs the evidence sequence to confirm the escalation no longer works. The fix is verified against the same evidence that demonstrated the vulnerability.

---

# S10.3 — Findings, Evidence, and Client Deliverables

The cloud red team engagement produces findings — demonstrated paths from initial access to impact. Each finding must be structured, evidenced, and mapped to compliance frameworks for the client deliverable. The evidence schema and the compliance mapping are what make the findings actionable for the client's auditor, not just interesting to the client's security team.

## The cloud evidence schema

Every finding is backed by a chain of evidence records. The cloud evidence schema extends S02.3's hash-chained evidence log with cloud-specific fields:

```typescript
interface CloudEvidenceRecord {
  // Identification
  id: string;
  trace_id: string;
  session_id: string;

  // What happened (cloud-specific)
  timestamp: string;          // UTC ISO 8601
  cloud_provider: "aws" | "azure" | "gcp";
  account_id: string;
  region: string;
  api_call: string;           // e.g. "iam:GetRole", "s3:GetObject"
  resource_arn: string;       // the specific resource acted upon
  actor_arn: string;          // which identity made the call

  // What was sent and received
  request: string;            // exact API request (parameters)
  response: string;           // exact API response
  http_status: number;

  // Legal anchor
  scope_ref: string;          // which scope entry authorized this call

  // Finding linkage
  finding_id: string | null;
  impact_assessment: string | null;

  // Tamper-evidence
  previous_hash: string;
  record_hash: string;

  // Retention
  retention_class: "public" | "redacted" | "restricted";
  retention_expires: string | null;
}
```

The `account_id`, `region`, `api_call`, and `resource_arn` fields are the cloud-specific additions. They make the evidence precise: not just "a call was made," but "the call `s3:GetObject` was made against `arn:aws:s3:::client-sensitive-data` in `us-east-1` from account `123456789012` at this exact timestamp, authorized by this scope entry, producing this exact response." The hash chain (from S02.3) ensures tamper-evidence — no record can be altered without breaking the chain.

## Mapping cloud findings to compliance frameworks

The client's auditor does not care about `iam:PassRole` chains. The auditor cares whether the organization meets SOC 2, ISO 27001, or PCI DSS requirements. The finding-to-framework mapping is what translates the red team's technical findings into the auditor's compliance language:

```python
COMPLIANCE_MAPPING = {
    "iam_over_privilege": {
        "soc2": "CC6.3 — The entity authorizes, modifies, or removes access to data",
        "iso27001": "A.9.2.5 — Review of user access rights",
        "pci_dss": "7.2.1 — Establish an access control system for systems components",
    },
    "public_exposure": {
        "soc2": "CC6.1 — The entity implements logical access controls",
        "iso27001": "A.13.1.1 — Network controls",
        "pci_dss": "1.2.1 — Restrict inbound/outbound traffic",
    },
    "privilege_escalation_path": {
        "soc2": "CC6.3 — Authorization of access (escalation path violates least privilege)",
        "iso27001": "A.9.4.4 — Use of privileged utility programs",
        "pci_dss": "7.1.1 — Define access needs for each role (escalation path exceeds defined needs)",
    },
    "missing_encryption": {
        "soc2": "CC6.7 — The entity restricts physical access to data (transmission protection)",
        "iso27001": "A.10.1.1 — Policy on the use of cryptographic controls",
        "pci_dss": "3.4 — Render PAN unreadable wherever it is stored",
    },
}

def map_finding_to_compliance(finding_type: str) -> dict:
    return COMPLIANCE_MAPPING.get(finding_type, {
        "soc2": "Review required — no direct control mapping",
        "iso27001": "Review required — no direct control mapping",
        "pci_dss": "Review required — no direct control mapping",
    })
```

Each finding type maps to specific controls in each framework. An over-privileged IAM role is not just "a misconfiguration" — it is a violation of SOC 2 CC6.3 (access authorization), ISO 27001 A.9.2.5 (access rights review), and PCI DSS 7.2.1 (access control system). This mapping makes the finding immediately actionable for the compliance team: they know which control is at risk and what the remediation satisfies.

## Client report structure

The cloud red team client deliverable follows a structure that serves both technical and executive audiences:

1. **Executive summary.** The overall risk assessment: what was tested, what was found, the business impact, and the prioritized remediation roadmap. One page, non-technical language, framed in risk and compliance terms.
2. **Finding table.** Each finding: ID, title, severity, affected resource, compliance mapping, status. The structured overview the technical team uses to track remediation.
3. **Attack narrative.** For each significant finding, the step-by-step story: how the initial access was obtained, how the escalation chain proceeded, what the impact would be. The narrative is backed by the evidence chain — each step references the specific evidence records that demonstrate it.
4. **Remediation roadmap.** Prioritized actions, mapped to the finding table and compliance frameworks. What to fix first (critical paths), what to fix next (medium findings), and what to accept as residual risk.

The report is generated from the structured findings and evidence store — not written by hand. The evidence chain ensures every claim in the narrative is backed by a reproducible API call sequence. The compliance mapping ensures every finding speaks the auditor's language. This is what makes the deliverable client-ready: technical depth for the engineers, executive framing for the CISO, and compliance language for the auditors.

---

## Anti-Patterns

### The network-pentest-in-the-cloud
Running nmap against cloud infrastructure. The cloud is not a network — it is an API. Port scanning finds nothing useful and wastes engagement time. Cure: API-first, identity-first offensive architecture (S10.1).

### The unscooped cloud engagement
Running enumeration and exploitation without account boundaries enforced. The harness touches a production account or a denied region. Cure: scope enforcement middleware on every API call, with account boundaries and service exclusions (S10.1).

### The theoretical escalation path
Reporting "Role-A could escalate to admin" without demonstrating it. The client cannot verify the claim; the auditor cannot use it. Cure: evidence-collected escalation paths with exact API call sequences (S10.2, S10.3).

### The compliance-unmapped finding
A finding described technically ("iam:PassRole chain allows S3 access") with no compliance mapping. The auditor does not know which control is at risk. Cure: the finding-to-framework mapping (S10.3) — every finding speaks SOC 2, ISO 27001, and PCI DSS.

---

## Key Terms

| Term | Definition |
| --- | --- |
| **API-first** | Cloud offensive architecture where every action is an API call against the control plane, not a network packet |
| **Identity-first** | The IAM layer (users, roles, policies, trust relationships) is the primary attack surface in cloud environments |
| **Cloud kill chain** | Recon → Initial Access → Privilege Escalation → Lateral Movement → Impact; executed via API, not network |
| **IAM escalation path** | A chain of IAM permission abuses that transitions from low privilege to high privilege (e.g., PassRole + Lambda) |
| **Privilege graph** | Graph of permission sets (nodes) and escalation techniques (edges); BFS finds paths from start to target |
| **Cloud evidence schema** | Hash-chained evidence records with account_id, region, api_call, resource_arn — reproducible and verifiable |
| **Compliance mapping** | Translation of technical findings to SOC 2, ISO 27001, and PCI DSS control references for the auditor |

---

## Lab Exercise

See `07-lab-spec.md`. Three labs: (1) cloud offensive harness configuration with scope enforcement and full kill chain enumeration; (2) IAM privilege escalation path-finder; (3) client-ready report generation with evidence schema and compliance mapping.

---

## References

1. **Pacu** — the AWS exploitation framework. IAM escalation modules, post-exploitation.
2. **Stormspotter** — Azure attack graph builder. Maps identity and resource relationships.
3. **Prowler, ScoutSuite** — cloud configuration auditing across AWS, Azure, GCP.
4. **Rhino Security Labs — AWS IAM Privilege Escalation methods.** The canonical documentation of IAM escalation techniques.
5. **S02.2 — Harness tool wrapping.** Pacu/Stormspotter are wrapped with the same Pydantic-schema + scope-check pattern.
6. **S02.3 — Evidence chain engineering.** The hash-chained evidence log; S10 extends it with cloud-specific fields.
7. **S09.2 — Attack path analysis.** The graph-based path-finding technique; S10.2 applies it to the IAM layer.