# SSRF to IMDS Credential Theft

> Exploit SSRF vulnerabilities to query AWS IMDSv1/v2 endpoints, extract IAM role credentials, and escalate privileges within the target AWS environment.

- **URL:** https://hackindex.io/platforms/aws/exploitation/ec2/ec2-ssrf-imds-credential-theft
- **Path:** AWS > Exploitation > EC2
- **Up:** [EC2](https://hackindex.io/platforms/aws/exploitation/ec2.md)
- **Published:** 2026-08-10
- **Updated:** 2026-08-10

IMDSv1 answers metadata requests without a session token, so any code that can make an outbound HTTP request from the instance, including an SSRF in a hosted app, can read IAM role credentials from `169.254.169.254`. IMDSv2 requires a `PUT` token request first, which most SSRF primitives cannot perform. Confirming which mode an instance enforces tells you whether the credential-theft path is open.

The control is `MetadataOptions.HttpTokens`: `optional` means IMDSv1 is still accepted and the instance is exposed, `required` means IMDSv2 only.

Data reachable through IMDSv1 without a token:

- IAM role temporary credentials (`/iam/security-credentials/`)
- Instance identity document and region
- User data scripts, often containing secrets
- Network configuration and MAC addresses

## Check From the AWS API

With credentials that can call EC2, query the metadata options directly. This is the reliable, non-intrusive check.

```bash
aws ec2 describe-instances --profile $PROFILE \
  --query 'Reservations[].Instances[].{Id:InstanceId,Tokens:MetadataOptions.HttpTokens,HopLimit:MetadataOptions.HttpPutResponseHopLimit}' \
  --output table
# -------------------------------------------------
# |                DescribeInstances              |
# +----------+-----------+--------------------------+
# | HopLimit | Id        | Tokens                   |
# +----------+-----------+--------------------------+
# |  1       | i-0abc... | optional                 |
# |  2       | i-0def... | required                 |
# +----------+-----------+--------------------------+
```

`optional` confirms the weakness. A `HttpPutResponseHopLimit` above 1 is a secondary finding: it lets containers a hop away from the host reach IMDS, widening the blast radius even on IMDSv2.

Sweep every region, since the default profile only queries one:

```bash
for region in $(aws ec2 describe-regions --profile $PROFILE --query 'Regions[].RegionName' --output text); do
  echo "== $region =="
  aws ec2 describe-instances --profile $PROFILE --region $region \
    --query 'Reservations[].Instances[?MetadataOptions.HttpTokens==`optional`].InstanceId' --output text
done
```

## Confirm From the Instance

With a shell on the host, a token-less request that returns data proves IMDSv1 is live. A response here means the same request works through an SSRF.

```bash
curl -s -o /dev/null -w '%{http_code}\n' http://169.254.169.254/latest/meta-data/
# 200
```

`200` confirms IMDSv1. If the instance enforces IMDSv2 the same request returns `401`, and you would need a token request first, covered in [EC2 Instance Metadata Service](https://hackindex.io/platforms/aws/enumeration/ec2/ec2-instance-metadata-service).

## Where It Leads

Confirmed IMDSv1 with an attached instance profile is a direct route to role credentials. Turning an application SSRF into stolen credentials is covered in [SSRF to IMDS Credential Theft](https://hackindex.io/platforms/aws/exploitation/ec2/ec2-ssrf-imds-credential-theft).
