Steal EC2 Metadata Credentials via SSRF

One of the most commonly taught tactics in AWS exploitation is the use of Server Side Request Forgery (SSRF) to access the EC2 metadata service.

All EC2 Instances have access to the metadata service at 169.254.169.254. This contains useful information about the instance such as it’s IP address, the name of the security group, etc. On EC2 instances that have an IAM role attached the metadata service will also contain IAM credentials to authenticate as this role. Depending on what version of IMDS is in place, and what capabilities the SSRF has we can steal those credentials.

It is also worth noting that shell access to the EC2 instance would also allow an adversary to gather these credentials.

The attack as described here will not work with IMDSv2. For more information and options please refer to the documentation. IMDSv1 is still the default for EC2, so it is worth identifying what version is in place.

In this example there is a web server running on port 80 of the EC2 instance. This web server has a simple SSRF vulnerability, allowing us to make GET requests to arbitrary addresses. We can leverage this to make a request to http://169.254.169.254.

Showing SSRF

To determine if the EC2 instance has an IAM role associated with it, look for http://169.254.169.254/latest/meta-data/iam/. A 404 response indicates there is no IAM role associated. You may also get a 200 response that is empty, this indicates that there was an IAM Role however it has since been revoked.

If there is a valid role you can steal, make a request to http://169.254.169.254/latest/meta-data/iam/security-credentials/. This will return the name of the IAM role the credentials represent. In the example below we see that the role name is ‘ec2-default-ssm’.

Role Name

To steal the credentials, append the role name to your previous query. For example, with the name above we’d query http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-default-ssm/.

Stolen Keys

These credentials can then be used in the AWS CLI or other means to make API calls as the IAM role.