guides keyboard image

What you'll need to follow this guide

  • AWS admin (or at least permissions to manage IAM policies and enforce for all users)
  • AWSCLI

Concept

The AWS instance metadata service (IDMS) version 1 service has been found to produce sensitive information that can be far too easily accssed. We will disable the ability to launch instances with IDMSv1 going forward and use a simple bash script to modify the instance metadata service to version 2 for running instances.

The basic issue here is IDMSv1 is quite easy to query and certain endpoints can return sensitive information. You will see here that all one has to do from an EC2 instance is a simple curl:


$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
codedeploy-ec2

What's this? Looks like there is an IAM role attached to my instance called codedeploy-ec2, so let's curl that:

$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/codedeploy-ec2/
{
  "Code" : "Success",
  "LastUpdated" : "2022-04-18T00:14:51Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIPISCSD35PKIEWADG4",
  "SecretAccessKey" : "alkvjacvzvbioewfad920234edlkfjslkdnzzdc",
  "Token" : "IADSFPBAOFAFB123adfgakcvkjzcdr3wef9d8uvlkjxblkjdslkfjlccx98vclbkjsd,fmsdfoiaDFJLKJVKNVLASKNASLKCZDS9ACLKAJDJCzy9GguAlzPPu9qzyaoG1fcOQOg4/E6YsVUR3aVRjceirWJUmxUvbtWtPKup/3FR1clmDONuc904RMLQUlFCkb6h8trHbLRRPgLKfZWpl1o420MJX3qXviZULI9SXz6oA8D3KgrTxwKh3wxMtwF+fJznpdYaq/hvjd/pQeeTDk2vKSBjqlAShffydgNjn6H/0ddfIgMhRxmg1x1+nMqgwQIyf//////////ARAAGgw2MDM0NDczNTY0MDIiDBTVjWLUzytIFaD1nCrXA1cqatlTjMW3Ai5/i4as23fs8GOZPyBEmEuHkn1XpH+xiC4A2SBUcXV+ZV34HovebgUnnR3cwoXI0Y0vfBvMUW4e5KdDlaGJdaoIqnR7WE7FkqzmZzEIgEzCG+/MMyXLn+QjAon7Bs0qIYJy/eE2FxP4X7+KOpTXr66WmCJTSndvLTHnorLH78NWK7CxFOwUGjGmFeUGsBSriyTnLNjAj+yb7V3/EABj1LIWOTBlaIEMNYAtVjEddYuDGuOKf9jS7GXwAhgyeusDJMsCf1HZyF5GVHjMzjY7yFTyf639uZTQrmrGd+huRnP",
  "Expiration" : "2022-04-18T06:36:31Z"

And there you have it – security credentials handed over with little effort. Now you can see why this is not so fantastic to leave running..


Benefits

Disabling IDMSv1 in favor of going IDMSv2 only will provide better security for your EC2 instances.


Implementation Guide

The solution to this problem is two-fold, as we will need to fix the currently running instances as well as prevent future instances from launching with IDMSv1 enabled.

Dealing with already running EC2 Instances

We can solve this using AWSCLI and a simple bash script. Be mindful of the --region parameter in the command that generates the list of instances and change it as you need:

#!/bin/bash

INSTANCES=`aws ec2 describe-instances --region us-west-2 |grep InstanceId | cut -f2 -d":"| tr -d \"| tr -d \,`

for i in $INSTANCES; do
  aws ec2 modify-instance-metadata-options \
    --instance-id $i \
    --http-tokens required \
    --http-endpoint enabled
done

Preventing future EC2 Instances from launching with IDMSv1 enabled

You will need to create an IAM policy and ensure that it is attached to all IAM users (I suggest organizing users into groups and applying the policy to the group)

The policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RequireImdsV2",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:MetadataHttpTokens": "required"
                }
            }
        }
    ]
}

Once this policy is set on an IAM user, they will receive an Unauthorized error whenever they attempt to launch an instance without explicitly electing IDMSv2. This setting can be found in the Advanced section of launching an EC2 Instance from AWS Console:

idms setting in aws console


Verification

The same curl that worked before should now give an Unauthorized error, if all went well:

$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/codedeploy-ec2/
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 - Unauthorized</title>
 </head>
 <body>
  <h1>401 - Unauthorized</h1>
 </body>
</html>

Conclusion

Retiring IDMSv1 for IDMSv2 is some pretty low-hanging fruit that will quickly improve the overall security posture of your AWS account.


Considerations

Beware as you could be running AWS services that are dependent on a specific version of metadata such as:

  • Codedeploy-Agent
  • Autoscale Groups

Will post some solutions for these at a later date