Module 24: Enumerating AWS Cloud Infrastructure

About the Public Cloud Labs

  1. 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.

  2. 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.

  3. 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.

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:

We should also keep in mind that the public IP address of the DNS server will change every time we restart the lab, and we'll need to run this configuration again.

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:

Objects inside a bucket can be publicly accessible even if the bucket is not publicly accessible.

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:

  1. 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.

  2. 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.

  3. 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

The get-caller-identity subcommand is a good way to identify the account and identity of the credentials, and this action will never return an AccessDenied error. However, we should be aware that this action is logged in Cloudtrail's event history. As defenders, we should establish alerts for these types of calls as they are typically executed by attackers once they've 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:

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

Resource Type
Name
ARN

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:

  1. Social engineer Alice's credentials -- we know there is no MFA.

  2. Searching for credentials with permission to modify admin-alice's credentials.

    1. In this case, we could look for policies with iam:"*", or iam:CreateAccessKey allowed actions.

  3. Obtaining credentials of another admin user or find a user with permissions to add users to the admin group.

    1. 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