Article by Nick Frichette.
Steal EC2 Metadata Credentials via SSRF
This is a common and well known attack in AWS environments. Mandiant has identified attackers performing automated scanning of vulnerabilities to harvest IAM credentials from publicly-facing web applications. To mitigate the risks of this for your organization, it would be beneficial to enforce IMDSv2 for all EC2 instances which has additional security benefits. IMDSv2 would significantly reduce the risk of an adversary stealing IAM credentials via SSRF or XXE attacks.
One of the most common techniques in AWS exploitation is abusing the Instance Metadata Service (IMDS) associated with a target EC2 instance.
Most EC2 instances can access their IMDS at 169.254.169.254. This service is only accessible from the specific EC2 instance it is associated with. The instance metadata service contains useful information about the instance, such as its IP address, its instance type, the name of the security groups associated with it, etc.
If an EC2 instance has an IAM role attached to it, IAM credentials associated with that role can be retrieved from the metadata service. Because of this, attackers will frequently target the IMDS to steal those credentials.
Stealing IAM Credentials from the Instance Metadata Service
If the EC2 instance is configured to use the default instance metadata service version 1, it is possible to steal IAM credentials from the instance without getting code execution on it.
This can be done by abusing existing applications running on the host. By exploiting common vulnerabilities such as server side request forgery (SSRF) or XML external entity (XXE) flaws, an adversary can coerce an application running on the host to retrieve those IAM credentials.
To demonstrate this, in the following 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
To determine if the EC2 instance has an IAM role associated with it, we can make a request to
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 we can steal, we can make a request to
http://169.254.169.254/latest/meta-data/iam/security-credentials/. This will return the name of the IAM role associated with the credentials. In the example below we see that the role name is 'ec2-default-ssm'.
To retrieve the credentials, we can append the role name to the previous query. For example, with the role name shown previously, the query would be
These credentials can then be used in the AWS CLI to make calls to the API. To learn more about using stolen IAM credentials, check out this comprehensive guide.
An adversary who has gained code execution on the EC2 instance can retrieve credentials from the IMDS regardless of the version being used. Therefore, it is important to continually monitor your environment for suspicious activities.
For an example of this technique being used in the wild along with additional information, please see Kevin Fang's excellent video on the 2019 Capital One breach.