Amazon Web Services, much like other cloud network providers (e.g. Azure, Google Cloud), has seen a consistent, upward trend in its utilization. Cloud platforms give organizations the ability to offload infrastructure and management costs by moving on-premise data centers, platforms, and applications to a fully managed environment, complete with an exhaustive catalog of services that help with the complexitites of running critical hardware, software, and network environments.
During traditional adversarial tests, the standard operating procedure entails attacking high-value or privileged users on the network. Often this means shelling the user's workstations, extracting credentials using something like Mimikatz, and pilfering file shares and document repositories. With any luck, this access will then afford the attacker an opportunity to perform additional, privileged post-exploitation actions. Perhaps this means database access, source code or intellectual property exfiltration, lateral network movement, or extended persistence. The techniques may require some creativity, but are fairly well documented. However, as organizations continue to shift resources to the cloud, an adversary must take a slightly different approach to go from "corporate network" access, to "cloud provider network" access. In this post, I'll explore some techniques that can help bridge that gap. Specifically, we'll focus on ways to gain initial access to AWS during an adversarial engagement, such as a penetration test or Red Team assessment.
Of course, the scenarious are numerous here and highly dependant on how an organization utilizes their AWS environment. For example, it's possible for enterprises to seamlessly bridge the local and AWS networks through Direct Connect/VPN functionality, or extending Active Directory for federated access. Something like the following:
In cases such as these, it's possible that gaining access to the AWS private network is no different than a traditional, on-premise network environment. PtH, psexec, PowerShell remoting, WMI, etc. could all be viable attack patterns. Of course, there are factors that influence the practicality of this. These factors are similar as those for attacking traditional segmented networks - Is the VPN MFA? Is there a jumpbox/bastion host through which access must traverse? What ports are allowed through the virtual firewall? Is the AWS VPC tied to a different domain? Do you have creds for that domain? And so on, and so on. The answers to the questions will certainly influence an adversary's techniques, but these techniques should be familiar to most experienced pentesters. Instead, let's look at what we can do when we don't have the luxury of using some of these familiar techniques.
First off, Amazon has developed SDKs for most major, modern programming languages such that anything you do through the AWS online webapp, you can also do programmatically. Powerful stuff. Also, Amazon has created commandline interface (CLI) tools for use on OSX, Windows, and Linux. This is great for sysadmins and dev folks who prefer to manipulate their AWS environments from a remote terminal window, rather than a GUI of some sort.
Since the CLI (and SDKs) are an extension of AWS' management capability, authentication and authorization are crucial. To handle that, AWS, through it's Identity and Access Management (IAM) service, issues newly provisioned users a unique Access Key ID and Secret Access Key. The combination of these two data items allows Amazon to identify a user and determine their permissions. Needless to say, these values are of interest to an attacker and, therefore, should be protected appropriately.
When using the AWS CLI for the first time, you must register your Access Key ID and Secret Access Key. You do this by running the subcommand 'configure' like so:
$ aws configure
AWS Access Key ID [None]: *your access key id*
AWS Secret Access Key [None]: *your secret access key*
Default region name [None]: us-east-2
Default output format [None]:
This will save your Access Key ID and Secret Access Key, in an unencrypted fashion, to one of the following locations:
~/.aws/credentials
(OSX, Linux, and Unix)C:\Users\USERNAME\.aws\credentials
(Windows)
So, by compromising the workstation as an admin/root user or as the owner (perhaps a non-privileged user) of the credentials
file, you can steal the user's Access Key ID and Secret Access Key data. As this data is no way tied to the user's workstation, you can reuse it on an attacking workstation outside the compromised network if desired. The CLI even has a nice profile
feature that allows us to explicitly name our credential set and configuration so we don't get it confused with other sets of stolen creds. Just run aws configure --profile haxxor
to save your stolen credentials locally under an arbitrarily named profile of "haxxor."
Here I'm using the stolen credentials locally (with our named profile) to query AWS for a list of organization users.
$ aws iam list-users --profile haxxor
{
"Users": [
{
"Path": "/",
"UserName": "papabear",
"UserId": "AIDAIKO2GFYEEEEEEEEEE",
"Arn": "arn:aws:iam::086626666666:user/papabear",
"CreateDate": "2017-11-03T16:23:15Z"
},
{
"Path": "/",
"UserName": "fathertime",
"UserId": "AIDAIKO2GFYFFFFFFFFFF",
"Arn": "arn:aws:iam::086626666666:user/fathertime",
"CreateDate": "2017-12-07T14:56:37Z",
"PasswordLastUsed": "2017-12-13T00:05:38Z"
},
/* Snipped for brevity */
]
}
The effort needed to steal AWS credentials from a file (or, alternatively, credentials from a user's environment variables) is about the same as stealing an SSH private key or password hash. Generally, it's just a matter of compromising the correct user or device before it can be obtained. However, unlike the SSH private key, password, or hash, the AWS credentials can't be used to authenticate to things like ec2 instances. Depending on the compromised user's IAM permissions, there are a number of malicious things that can be done. We'll explore some of those in future blog posts.
In the next post, however, we'll demonstrate a scenario where the AWS credentials and ec2 private keys are encrypted by Visual Studio's AWS Toolkit plugin. We'll look at how we can decrypt them to gain access to AWS and an ec2 instance.