CloudCopy — Stealing hashes from Domain Controllers in the Cloud

TL;DR

I recently tweeted about an attack I used during a Red Team engagement that, at least in my book, blew up on Twitter so I thought I’d write a post about how I found it and to release a tool I built for automating the attack, CloudCopy. CloudCopy creates a Snapshot of a EC2 Volume and mounts it to a new EC2 instance controlled by the attacker to steal credentials, or other sensitive information.

Backstory

During an engagement, I gained remote, low privilege access to a workstation and proceeded to conduct internal enumeration of file shares looking for some quick wins, such as GPP passwords, or plain text credentials within files. I was in luck because I discovered a Python file within a share that contained a set of AWS credentials! I loaded the credentials into the AWS CLI and ran “get-user”, which showed they contained permissions to control all S3 resources. While a great find, these permissions are not what we are after when escalating within the network. Treating access to the AWS account like the initial access to the workstation, I began enumeration of the S3 buckets looking for the same type of quick wins I found within the domain shares. Amongst the S3 data lied a bucket containing an Ubuntu .ova file titled ‘lubuntu’. I was curious about its contents, so I loaded the virtual machine into VMware, booted it up, and to my surprise it was a snapshot of a developer’s workstation! Continuing my game of recursive file enumeration, I searched for files within the development machine that may lead to further access. I struck gold when I discovered the ‘.aws/credentials’ file within the developer’s home directory. I loaded these credentials into the AWS CLI and ran “get-user”, which showed this user was an administrator of the AWS account. Jackpot!

Taking a step back from my Inception level enumeration activities, I pondered what I could gather from my newly found AWS admin access. While looking at the different instances, I thought a Windows 2019 Server instance, titled “Domain Controller”, sounded enticing. I noticed there were regular Snapshots taken against this instance and then a series of ideas suddenly hit me. What are Snapshots but copies of the instance hard drive? Wait, isn’t the entire Shadow Copy abuse attack focused on making a copy of the Domain Controller hard drive to steal hashes? Can’t you mount Snapshots to new instances? Can…can you perform the Shadow Copy attack in AWS without directly interacting with the target machine? The answer, it turns out, is yes!


Introducing CloudCopy

CloudCopy is an attack I developed for performing the Shadow Copy abuse within AWS. What sets this apart from the original attack, other than being in the cloud, is that it requires far lower permissions to execute and does not require any commands to be run against the target instance. If an attacker possesses the CreateSnapshot and ModifySnapshotAttribute permissions, they can create a snapshot of a running instance, mount it to a separate attacker controlled instance, and browse its contents without authentication.

To make matters worse, The AWS Snapshot Documentation mentions:

You can share a snapshot across AWS accounts by modifying its access permissions.

An attacker can use this feature of AWS Snapshots to bypass any restrictions on creating instances within the victim account because they can share the Snapshot with an account where they have full control. From a blue team perspective, only 3 functions, CreateSnapshot, ModifySnapshotAttribute, and DeleteSnapshot (run after CloudCopy completes), would be called and logged in CloudTrail.

The attack follows a simple 5 step process to go from Snapshot to NTLM hashes:

  1. ‘CreateSnapshot’ to perform the Shadow Copy of the target Volume.
  2. ‘ModifySnapshotAttribute’ to share the Snapshot with attacker account.
  3. ‘CreateInstance’ using the shared Snapshot as a second drive.
  4. Mount Snapshot drive, copy ntds.dit and SYSTEM file from instance to attacker machine.
  5. Execute Impacket’s secretsdump python module against ntds.dit and SYSTEM files to retrieve Domain Controller hashes.

To help aid in performing the CloudCopy attack, I released a python tool for automating the 5 step process mentioned above that can be found here: https://static-flow.github.io/CloudCopy/.

The CloudCopy automated tool uses either profiles set in ‘~/.aws/credentials’ or raw ‘AccessKey/SecretKey’ combinations to authenticate to AWS and perform the CloudCopy attack. Additionally, you are required to set an AWS region, which must be the same as the victim instance region, and an AWS account ID to share the Snapshot with.

While the attack works for both unencrypted and encrypted volumes, there is a slight caveat when attacking encrypted volumes. Since encrypted volumes cannot be shared outside the account where they were created, the CloudCopy tool, with your permission, creates the Snapshot then mounts it to an Instance, SecurityGroup, and KeyPair created inside the victim AWS account. This bypasses the restriction of not being able to share the Snapshot by attaching it to an instance within the same victim account. This will obviously create quite a few more log entries in CloudTrail and require 3 more permissions, CreateInstance, CreateKeyPair, and CreateSecurityGroup. Use at your own OPSEC discretion.

Demos

Below are two demos for CloudCopy running against two Domain Controllers, one with an unencrypted Volume, and the other with an Encrypted Volume.


Mitigations against CloudCopy

No good blog or tweet about a new attack is complete, in my opinion, without a section on how to defend against the attack. For this attack in particular, it will come as no surprise that AWS IAM rules coupled with CloudWatch logging alerts and MFA are your best friends here.

If you look through the twitter thread, you’ll see a good discussion on how to defend against this attack. One of the first defenses I proposed was to KMS encrypt the Volume. While this is a good idea, since it keeps the Volume and any derivative Snapshots from leaving the origin AWS account, it does not prevent accounts with the 5 permissions mentioned above from still executing the attack.

Generally, I recommend restricting the ‘CreateSnapshot’ permission on the instance to a MFA protected account or accounts to ensure simply gaining access to an account with correct permissions does not allow for abuse. Additionally, CloudWatch alerts should be placed on any Snapshot events against the instance’s Volume to ensure no rogue attempts and successful Snapshot creations are missed.

Next Steps and Thank You’s

Hopefully this article and the accompanying tool are helpful in your security endeavors, both as a Red team and Blue team member. Please comment below with any comments or suggestions, especially concerning potential mitigations from a Blue Team perspective.

For the CloudCopy tool, I have a few avenues I’d like to explore to make it more well-rounded:

  1. More attack types outside of DC Hashes, like collecting all dot files on the Volume, i.e. “.aws/credentials” file
  2. Live off the land checks to bypass missing permissions like abusing an already existing Security Group to allow us access to attacking instance, using an already created Snapshot, or mounting the CloudCopy Snapshot to an instance we already control.
  3. Creating a version of CloudCopy for the Pacu framework from Rhino Security Labs.

Finally, I’d like to thank my employer, Protiviti, for allowing me to perform this research and develop this tool to help better the security community.

Protiviti’s global IT consulting practice helps CIOs and IT leaders design and implement advanced solutions in IT governance, security, data management, applications and compliance. Protiviti works to address IT security and privacy issues and deploy advanced and customized application and data management structures that not only solve problems, but add value to organizations. Technology will drive your future, with Protiviti you can be confident it takes you where you want to go.