Module 24: Enumerating AWS Cloud Infrastructure
About the Public Cloud Labs
The lab environment should not be used for activities not described or requested in the learning materials you encounter. It is not designed to serve as a playground to test additional items that are out of the scope of the Learning Module.
The lab environment should not be used to take action against any asset external to the lab. This is specifically noteworthy because some Modules may describe or even demonstrate attacks against vulnerable cloud deployments for the purpose of describing how those deployments can be secured.
Existing rules and requirements against sharing OffSec training materials still apply. Credentials and other details of the lab are not meant to be shared. OffSec monitors activity in the Public Cloud Labs (including resource usage) and monitors for abnormal events that are not related to activities described in the learning modules.
Activities that are flagged as suspicious will result in an investigation. If the investigation determines that a student acted outside of the guidelines described above, or otherwise intentionally abused the OffSec Public Cloud Labs, OffSec may choose to rescind that learner's access to the OffSec Public Cloud Labs and/or terminate the learner's account.
Reconnaissance of Cloud Resources on the Internet
Accessing the Lab
Deployment will take a few minutes to complete and, once complete, the additional services might take 5-10 minutes to start.
Once the lab finishes its deployment, we'll receive some pieces of information we'll need later while working in the lab.
Public DNS IP Address
Domain name of the target
Credentials for the IAM user attacker
ACCESS_KEY_ID
SECRET_ACCESS_KEY
We must configure the DNS in our local environment to use the public DNS set for this lab:
Domain and Subdomain Reconnaissance
Querying the authoritative DNS servers for the offseclab.io domain:
Validating who owns the domains found:
Querying the public IP address of our target:
Performing a reverse DNS lookup:
Using dnsenum to auomate some of this dns reconnaissance:
Service-specific Domains
Not much to add, of note Amazon ec2 instances tend to have a URL beginning with ec2. Same goes for s3 buckets.
cloud-enum is a useful tool to perform OSINT across multiple CSPs. The cloud-enum tool will search through several public CSPs for resources containing a keyword specified using the --keyword KEYWORD (-k KEYWORD) parameter. We can specify multiple keyword arguments, or we can specify a list with the --keyfile KEYFILE (-kf KEYFILE) parameter.
We can also use the --mutations (-m) option to specify a file to add extra words to the keyword. If we don't specify any file, the /usr/lib/cloud-enum/enum_tools/fuzz.txt file is used by default. We can disable this option using the --quickscan (-qs) parameter.
Using cloud-enum to search for more buckets belonging to offseclab.io:
Using a custom keyfile for cloud-enum:
Reconnaissance via Cloud Service Provider's API
Preparing the Lab - Configure AWS CLI
Configuring awscli:
Publicly Shared Resources
Listing all AMIs that our account can read, that are provided by Amazon that are public, including self-owned public AMIs:
Filtering for AMIs with a name including "Offseclab":
Obtaining Account IDs from S3 Buckets
Steps to find the account ID from a publicly available S3 bucket:
Create an IAM user with a policy that only allows them to ls the S3 bucket if the account ID begins with x where x is 0-9.
As that user, attempt to ls the S3 bucket. If it's able to, then move to the next digit. Otherwise change the first digit for the account ID in teh policy and reapply.
Rinse & repeat.
There are also tools like s3-account-search to do this, however that tool uses roles rather than users to link the policy to the condition.
Example policy:
Enumerating IAM Users in Other Accounts
Similar to the last section, we can use policies to determine if IAM accounts exist when we know an account ID. In this case we would assign the policy to our own private bucket. If no error returns after running the command to apply the policy, that means that the cloudadmin user exists in the target account.
Creating a dummy private bucket:
Example policy:
Applying the policy to our private bucket:
Applying a policy where the user does not exist:
We can automate this process using pacu and a prebuilt list of users we'd like to test:
Now that we were able to assume the role, let's set environment variable and query the environment:
Initial IAM Reconnaissance
Accessing the Lab
Credentials for access as the target user.
Target ACCESS KEY ID
Target SECRET ACCESS KEY
Credentials for access as the challenge user.
Challenge ACCESS KEY ID
Challenge SECRET ACCESS KEY
Credentials for access as the monitor user.
Management Console login URL
Username
Password
Examining Compromised Credentials
Getting details about our compromised account:
The more stealthy command to gather information, this results in logs of our attacker's account rather than the target's:
Getting information in a stealthy way from error messages via a lambda function:
Scoping IAM permissions
Listing inline policies:
Listing policies associated with the user specified:
Listing groups that the specified user is attached to:
Checking inline and managed policies for the group discovered:
While AWS Managed Policies offer flexibility for IAM management, they tend to be overly-permissive and there is an inherent security risk when they are used alone.
Determining the version of the AWS managed policy applied to the support group:
Retrieving the most recent version document:
IAM Resources Enumeration
Choosing Between a Manual or Automated Enumeration Approach
Enumerating IAM Resources
IAM::User
clouddesk-plove
arn:aws:iam::123456789012:user/support/clouddesk-plove
IAM:Group
support
arn:aws:iam::123456789012:group/support/support
IAM::Policy
SupportUser
arn:aws:iam::aws:policy/job-function/SupportUser
Checking the actions our policy grants us the ability to us:
Filter command via the aws help to show what all we can do:
Getting a summary of the IAM-related information in the account, tee'ing it to avoid interacting with the AWS API again:
Enumerating all the IAM identities:
Listing policies attached to IAM identities, only displaying the Customer Managed Policies and omitting the AWS Managed Policies:
Getting the inline policies for every identity:
list-user-policies
get-user-policy
list-group-policies
get-group-policy
list-role-policies
get-role-policy
Checking for all managed policies:
list-attached-user-policies
list-attached-group-policies
list-attached-role-policies
Then we can run the get-policy-version subcommand to read the policy document for each managed policy found.
Alternatively, if we have Get* permissions, we can just run get-account-authorization-details to gather the same information of all the previous commands.
Processing API Response data with JMESPath
Example querying all user information via get-account-authorization-details:
Now using JMESPath expression to query just the UserName field:
Additional examples:
Listing all IAM Users with a username containing the word 'admin' via Filter Projections:
More examples with Filter Projections:
Running Automated Enumeration with Pacu
Similar to get-account-authorization-details w/ pacu:
Listing data in the Pacu database:
Extracting Insights from Enumeration Data
Analyzing admin-alice's IAM user data:
Querying the information about the two groups the user belongs to:
Paths to go from here:
Social engineer Alice's credentials -- we know there is no MFA.
Searching for credentials with permission to modify admin-alice's credentials.
In this case, we could look for policies with iam:"*", or iam:CreateAccessKey allowed actions.
Obtaining credentials of another admin user or find a user with permissions to add users to the admin group.
In this case we'd be looking for policies with iam:"*", or iam:AddUserToGroup allowed actions.
Displaying policies associated with the amethyst_admin group:
Userful search listing Users, groups, and attached managed policies:
Last updated