Tuesday, September 18, 2018

A practical guide to testing the security of Amazon Web Services (Part 2: AWS EC2)

This is Part 2 of 3 on our practical guide to testing the security of Amazon Web Services. We are tackling the main services provided by Amazon for its cloud-based platform to support web applications and we started by discussing AWS S3 buckets and their security. You can get a little overview of AWS and catch up on important aspects of testing AWS S3 by reading our previous post.

In this second part, we describe another important AWS service used on a daily basis by many users: Elastic Compute Cloud or, more commonly, EC2.

AWS EC2

Elastic Compute Cloud (EC2) is another widely used service offered by Amazon. It allows to rent virtual computers that can be used to run arbitrary applications. AWS EC2 provides a scalable solution to deploy a new computer, which in AWS terminology is called an "instance", and mange its status via a web-based user interface. The user can manage every aspect of an EC2 instance from the creation and execution to the definition of access policies. It's undeniable that AWS EC2 constitutes a powerful tool that, if not properly configured and protected, will inevitably result in a security breach. AWS EC2 instances provide many different features. In this post we discuss two features that are particular relevant when from a security perspective: Elastic Block Store and Instance Metadata Service.

AWS EC2 instances can benefit from other AWS services to which they are granted access to. A typical example, that we first introduced in Part 1 and we further explore here, is the synergy between AWS EC2 instances and AWS S3 buckets. When an AWS EC2 instance is created it requires, as all computers do, a persistent storage unit where you can save your data. Amazon thus provides Elastic Block Store (EBS) which is a block-level storage that provides a persistent storage solution that can be attached to an AWS EC2 instance. An EBS block thus constitutes an important part of an AWS EC2 instance as it allows to store data processed by the instance itself. Given its importance, it might be convenient to be able to take snapshots of an EBS block and store it safely so that, in the case of a failure, the AWS EC2 instance can be restored to a safe status. To accomplish this, Amazon gives the possibility of taking EBS snapshots and store them in its storage service AWS S3.




Let's now discuss another interesting feature that AWS EC2 instances have access to called Instance Metadata Service (IMS). IMS allows any AWS EC2 instance to retrieve data about the instance itself that can be used to configure or managing the running instance. The data available from the IMS ranges from the hostname of the instance to the initialization scrip that is executed upon running the instance. All this information can be retrieved only by the AWS EC2 instance by querying a specific API end-point located at  http://169.254.169.254.
As will become clear in the remaining of this post, this end-point provides valuable information an attacker might use to compromise not only the AWS EC2 instance but other services as well. The documentation for the IMS, in fact, states the following:
Although you can only access instance metadata and user data from within the instance itself, the data is not protected by cryptographic methods. Anyone who can access the instance can view its metadata. Therefore, you should take suitable precautions to protect sensitive data (such as long-lived encryption keys). You should not store sensitive data, such as passwords, as user data.
IMS becomes thus a crucial aspects when analyzing the security of AWS EC2 instances.

Publicly accessible EC2 snapshots

As just mentioned, EBS snapshots are, by default, stored in a private AWS S3 bucket that is not directly accessible via the S3 dashboard. However, EBS snapshots are manageable via the AWS EC2 interface and their permissions can be change to be public. Needless to say, you should never do that.
From a security perspective, if you are doing a penetration testing activity and find yourself dealing with possibly open accessible EBS snapshots, you could try to have access to the EBS block by mounting it in an EC2 instance under your control. Think of an EBS block as a virtual disk that you can mount like you would normally do. To mount an EBS block you thus need two things:

  1. an AWS EC2 instance under your control where you can mount the EBS block
  2. the ID that identifies the snapshot

For (1) I recommend you check out the AWS documentation on how to create and launch an EC2 instance. While for (2) you can use the aws command to search for publicity accessible EBS snapshots follows:

aws --profile [PROFILE] ec2 describe-snapshots --filters [FILTERS] --region [REGION]

This command will respond with a JSON listing all the publicly available snapshots that satisfies the values specified by the --filters flag (for a complete description of the kind of filters you can use, check the documentation). The JSON will contain some information about the snapshot along with the corresponding SnapshotId value that we need. For example, let's assume that we want to list all the publicly accessible snapshots containing the word backup in it which are located in the east-us-2 region, this is what we would  do:

aws --profile default ec2 describe-snapshots --filters Name=description,Values="*backup*" --region east-us-2

The result of executing such command would be a JSON listing all the publicly accessible snapshots satisfying our search criteria.



{
    "Snapshots": [
        {
            "Description": "Phoenix_competitor_analysis_backup_set",
            "Encrypted": false,
            "VolumeId": "vol-ffffffff",
            "State": "completed",
            "VolumeSize": 100,
            "StartTime": "2017-08-30T05:24:48.000Z",
            "Progress": "100%",
            "OwnerId": "234190327268",
            "SnapshotId": "snap-0dc716aaf28921496"
        },
        {
            "Description": "backup",
            "Encrypted": false,
            "VolumeId": "vol-0b21c8a6c158367fc",
            "State": "completed",
            "VolumeSize": 8,
            "StartTime": "2018-05-21T13:01:49.000Z",
            "Progress": "100%",
            "OwnerId": "388304843501",
            "SnapshotId": "snap-041c06c0c3658323c"
        },
        {
            "Description": "backup",
            "Encrypted": false,
            "VolumeId": "vol-0ee056a878d9dfdb1",
            "State": "completed",
            "VolumeSize": 30,
            "StartTime": "2018-01-07T13:52:56.000Z",
            "Progress": "100%",
            "OwnerId": "682345607706",
            "SnapshotId": "snap-0e793674b08737e95"
        },
        {
            "Description": "copy of backup sprerdda - BAckup-17-8-2018",
            "Encrypted": false,
            "VolumeId": "vol-ffffffff",
            "State": "completed",
            "VolumeSize": 30,
            "StartTime": "2018-08-22T15:03:48.179Z",
            "Progress": "100%",
            "OwnerId": "869858413856",
            "SnapshotId": "snap-02326682d84d3aedd"
        }
    ]
}

Once you have identified the snapshot of your interest, you have to create an EBS volume from that snapshot in order to be able to mount it. The following command will do just that and create an EBS volume in your account.

aws  ec2 create-volume --availability-zone us-west-2a --region us-west-2  --snapshot-id [SNAPSHOT_ID]

Finally, from your AWS console, create an EC2 instance and mount the newly created EBS volume in it.

Metadata leakage 

At the beginning of this we discussed of a peculiar feature of AWS EC2 instances called Instance Metadata Service (IMS). Recall that IMS allows any AWS EC2 instance to retrieve data about the instance itself that can be used to configure or managing the running instance and is accessible from within the instance itself by querying the end-point located at http://169.254.169.254.
As already mentioned, many juice information can be retrieved from querying that end-point. The following table summarizes some of the most interesting one however, many more are available.

http://169.254.169.254/latest/meta-data/ami-id The AMI ID used to launch the instance.
http://169.254.169.254/latest/meta-data/iam/security-credentials/ If there is an IAM role associated it returns its name (which can be used in the next handler).
http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name If there is an IAM role associated with the instance, role-name is the name of the role, and role-name contains the temporary security credentials associated with the role (for more information, see Retrieving Security Credentials from Instance Metadata). Otherwise, not present.
http://169.254.169.254/latest/user-data Returns a user-defined script which is run every time a new EC2 instance is launched for the first time.

Usage example are described in the following:

Result:
ami-336b4456

Result:
IAM_TEST_S3_READ

Result:
{
 "Code" : "Success",
 "LastUpdated" : "2018-08-27T15:23:14Z",
 "Type" : "AWS-HMAC",
 "AccessKeyId" : "AS[REDACTED]TEM",
 "SecretAccessKey" : "EgKirlp[REDACTED]hkYp",
 "Token" : "FQoGZXIvYXdzEJH//////////wE[REDACTED]=",
 "Expiration" : "2018-08-27T21:36:24Z"
}

Result:
#!/bin/bash -xe
sudo apt-get update
# install coturn
apt-get install -y coturn
# install kms
sudo apt-get update
sudo apt-get install -y wget
echo "deb http://ubuntu.kurento.org xenial kms6" | sudo tee /etc/apt/sources.list.d/kurento.list
wget -O - http://ubuntu.kurento.org/kurento.gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install -y kurento-media-server-6.0
systemctl enable kurento-media-server-6.0
# enable coturn
sudo echo TURNSERVER_ENABLED=1 > /etc/default/coturn
# turn config file
sudo cat >/etc/turnserver.conf<<-EOF
[...]

sudo /usr/local/bin/cfn-signal -e $? --stack arn:aws:cloudformation:us-east-2:118366151276:stack/KurentoMinded/3cbb23a0-3d77-11e8-953d-503f3157b035 --resource WaitCondition --region us-east-2

To take advantage of such juice information, the attacker has to find a way to query http://169.254.169.254 from within the EC2 instance itself. There are many ways in which this can be accomplished from being able to find a Server Side Request Forgery (SSRF) vulnerability, or exploit a proxy setup on the EC2 instance all the way to DNS rebinding as described by Alexandre Kaskasoli.

Conclusion of Part 2

AWS EC2 is undeniably a powerful service that many companies are taking advantage of. As described above, the security of an AWS EC2 instance is crucial to keep a company safe from malicious attackers. This post wrapped up the main security issues related to AWS EC2 instances and how security experts can test the presence of such issues during an assessment.

No comments :

Post a Comment