Attacking AWS Part 2: EC2 & EBS Snapshots
This post focuses on methods used to leverage and capture information while targeting EC2 compute resources. We'll cover EC2 and associated AWS service dependencies responsible for maintaining clean security hygiene when leveraging compute on Amazon Web Services. EC2 is also responsible for running the underlying compute for EKS and ECS respectively. This guide will teach you not only how to enumerate, but how to act on intel during EC2 and EBS enumeration. AWS CLI credentials for a target account and required permissions are specified in various scenarios below.
That said, it's important to layout a list of so called dependencies responsible for the protection of data-at-rest with respect to EC2. AWS KMS should always be leveraged in conjunction EBS volumes to provide AES256 encryption at the storage layer for EC2 based VMs or containers. This measure protects from accidental sharing should AWS IAM permissions permit unauthorized sharing of snapshots and/or an AMI. If a 3rd party account were to capture the Snapshot or AMI without the KMS key to decrypt, it renders the data useless. By no means is this acceptable behavior, IAM roles and policy permissions are the core of security with respect to AWS.
EC2 instances can leverage IAM Roles in order to communicate with various services across AWS. For example, let's say you want to leverage object storage within EC2 by mounting shares from an S3. A role can be assigned to your EC2 instances in order to provide very specific S3 access to file names and/or directories. This is far better than installing the AWS CLI on the EC2 instance or setting IAM credentials stored locally on your instance. This method is often leveraged by numerous red team training tools such as Hack the Box and Pwned Labs. IAM credentials can potentially be stored nearly anywhere storage and/or functions exist making them a critical asset and potential threat. Tools such as https://github.com/carnal0wnage/weirdAAL provide impressive insight for attacks. This tool alone can take a set of IAM credentials and scan across all AWS regions/services to determine what permissions have been assigned to the underlying account on the back end.
Here. I'm going to lay out some common EC2 service dependencies. Many of which provide data-in-transit protection methods for EC2 instances. Elastic IPs are far too often interpreted as an easy button to permit public traffic to underlying EC2 resources. However, anyone with a bit of know how knows how dangerous this train of thought can potentially be. Security Groups are great for protecting EC2 at a port level (Layer 3). NACLs are leveraged at a subnet & CIDR level (Layer 7). How you encrypt traffic is a by use case basis. However, native AWS professionals often find ease in leveraging ACM as it provides very straight forward SSL integrations with CloudFront and Application Load Balancers. ALBs can be integrated easily with AWS WAF and utilize IGW for incoming public traffic. As you can see this really is quite an ecosystem of services.
Let's focus on a few example scenarios which focus on EC2 enumeration targeting the relationships between EC2, EBS Volumes and EBS Snapshots. In order for enumeration to work properly, you'll need an IAM AWS CLI user with at minimum "ec2:DescribeVolumes" and "ec2:DescribeSnapshots" assigned. Your IAM user should be configured via the AWS CLI. This allows you to enumerate the name of volume ids attached to an instance by leveraging the AWS CLI:
aws ec2 describe-volumes --region us-east-1 --filters Name=attachment.instance.id,Values-i-instanceidhere
In a valid response you receive the follow info:
As you can see here, the root volume is leveraging AWS KMS encryption. Without KMS actions permitting the user via IAM policy, even if we had the ability to snapshot the volume it would be rendered useless. By default, if an EBS volume has encryption enabled so are the snapshots of that volume. However, it's still info of value when performing a cloud pentest or security assessment. It's also worth noting that EBS encryption can be applied by any AWS account and can be applied as a default behavior within EC2 settings as shown below:
In multi-account scenarios leveraging AWS Organizations, this may be declared as an SCP (Service Control Policy) which is implemented at the OU (Organizational Unit) level.
So let's say this EBS Volume wasn't leveraging KMS and our IAM user had the following permissions assigned:
The permissions above allow the IAM user to run the following via the AWS CLI:
aws ec2 describe-snapshots --region us-east-1 --owner-ids aws-account-id
As you can see we're presented with list of snapshots which belong to the AWS Account Id (OwnerId). Ideally, you should capture a list of each "SnapshotId" with an "Encrypted" value of false. This means the snapshot could potentially be accessed via any AWS account if public sharing were enabled. It's somewhat common for corporate employees to share snapshots when performing migrations in any capacity. It's often seen as an easy button and can lead to substantial consequences. I've outlined what this option looks like within the console below:
As you can see above, there are private sharing options which are a preferred method for snapshot sharing. This ensures the snapshot is designated for use within only specified AWS Account Ids. However, sharing with specified accounts using the AWS Account Id and permitting read access to your KMS key for the target account to then decrypt and utilize those snapshots to create volumes is even better:
https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-modifying-external-accounts.html
Because of the way AWS treats snapshots, they exist within hidden s3 buckets which the account who owns the snapshot does not have direct access to. While it is possible to export ec2 instances to snapshots and store them in your own s3 buckets to permit local access it requires a multitude of IAM permissions. In order to leverage the snapshot pictured and publicly shared above, we'll use the "SnapshotId" to create an EBS volume from that snapshot on any AWS account. This requires an EC2 instance, root volume, EC2 key pair and AWS CLI access to the underlying AWS account. Mounting the snapshot as a secondary drive makes sure we don't have issues connecting to our EC2 instance via SSH. If you don't have an existing EC2 instance, create one with a Public IP and filter SSH on the Security Group to permit inbound traffic from the IP (/32) you'll use to access it. This example leverages Amazon Linux on a t2.micro instance. You'll also need a key pair specified for connecting over SSH, you can create one ahead of time or during the EC2 creation process. We'll use our key pair to authenticate to our EC2 instance once running and attach the created volume from the public snapshot listed above. You'll want to create the snapshot in the same Availability Zone as your newly provisions EC2 instance to avoid any AZ-to-AZ traffic charges on your account. We'll create the volume now using the following command over the AWS CLI using our own AWS account and IAM credentials:
aws ec2 create-volume --region us-east-1 --availability-zone us-east-1c --volume-type gp3 --snapshot-id snap-0f1363f3cb7145bd7
We can check the status of the volume within our AWS GUI over the browser. If ready to be attached, you'll see a status of Available.
Now we'll attach our new volume to our EC2 instance:
aws ec2 attach-volume --region us-east-1 --volume-id vol-0daa8984cbbd162aa --instance-id i-021575afcabf95171 --device /dev/xvdf
Now we'll SSH into our EC2 instance using the Public IP and our downloaded key pair "*.pem" in this instance:
ssh -i .pem [email protected]
From here we'll connect the EBS volume created from the public facing snapshot by running the following:
sudo su
cd /mnt
mkdir ec2snapvol
mount -o nouuid /dev/xvdf1 ec2volsnap
cd ec2volsnap
ls*
Now you'll be able to fully enumerate the drive contents. Don't forget to clean up your mess by terminating your instance and deleting the volumes/snapshots to avoid any additional charges.