# Enumerate AWS Public Resources

## Dangers of Public Resources

* Many AWS resources can become public whether intentionally or not and these resources may contain sensitive data and/or credentials that may lead to a compromised environment&#x20;
* There are legitimate use cases for exposing resources publicly (such as providing customers with easy access) but due diligence should be performed to ensure sensitive data and credentials are not contained in these resources&#x20;

***

### S3 Buckets

* Since all S3 buckets have a unique URL, they can automatically be discovered
* [cloudenum](/cloud-security/tools/cloudenum.md)works by brute-forcing bucket names and informing if the bucket is real or not based on HTTP status codes. If a bucket is discovered, it attempts to list its contents `s3:ListBucket`

{% tabs %}
{% tab title="Discover S3 Buckets" %}
{% code overflow="wrap" %}

```bash
# python3 ./cloud_enum.py -k tylerexposedbucket234 --disable-gcp --disable-azure

[+] Checking for S3 buckets
  OPEN S3 BUCKET: http://tylerexposedbucket234.s3.amazonaws.com/
      FILES:
      ->http://tylerexposedbucket234.s3.amazonaws.com/tylerexposedbucket234
      ->http://tylerexposedbucket234.s3.amazonaws.com/dogs.txt
      ->http://tylerexposedbucket234.s3.amazonaws.com/secrets.txt
  Protected S3 Bucket: http://tyler.s3.amazonaws.com/
  Protected S3 Bucket: http://tyler1.s3.amazonaws.com/
  Protected S3 Bucket: http://tyler-1.s3.amazonaws.com/
  Protected S3 Bucket: http://tyler2.s3.amazonaws.com/
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

### EBS Snapshots

* EBS Snapshots are backups of EC2 instances
* [dsnap](/cloud-security/tools/dsnap.md) is a useful tool for downloading snapshots for local inspection otherwise you can [create an EC2 in your AWS account with the snapshot](https://docs.aws.amazon.com/prescriptive-guidance/latest/backup-recovery/restore.html#instance-from-snapshot)

{% tabs %}
{% tab title="Find All Public Snapshots" %}

```javascript
aws ec2 describe-snapshots --restorable-by-user-ids all
```

{% endtab %}

{% tab title="Find Public Snapshots by Owner" %}
{% code overflow="wrap" %}

```bash
aws ec2 describe-snapshots --owner-ids 222222222222 --restorable-by-user-ids all
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Bash" %}
{% code overflow="wrap" %}

```bash
#!/bin/bash

# Description: Finds all public ebs snapshots in all regions for a given aws account

# account to check
account='111111111111'

# needed to correctly parse regions
IFS=$'\n'

echo "Checking all regions in AWS account $account"

# get all available aws regions
regions=$(aws ec2 describe-regions --region us-east-1 | jq -r '.Regions[].RegionName')

# iterate through regions
for region in $regions; do
    # check for public snapshots
    echo "Checking for Public EBS snapshots in region: $region"
    
    # check for snapshots in region
    aws ec2 describe-snapshots --owner-ids $account --restorable-by-user-ids all --region "$region" | jq -r '.Snapshots[]'
done

# reset IFS
unset IFS
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

### RDS Snapshots

* RDS Snapshots are backups of RDS Databases

{% tabs %}
{% tab title="Find All Public Snapshots" %}
{% code overflow="wrap" %}

```bash
aws rds describe-db-snapshots --include-public
```

{% endcode %}
{% endtab %}

{% tab title="Find Public Snapshots by Owner" %}
{% code overflow="wrap" %}

```bash
export account='111111111111'

aws rds describe-db-snapshots --include-public | jq -r --arg aws_account "$account" '.DBSnapshots[] | select(.DBSnapshotIdentifier | contains($aws_account))'
```

{% endcode %}
{% endtab %}

{% tab title="Find Your Public Snapshots" %}
{% code overflow="wrap" %}

```bash
aws rds describe-db-snapshots --snapshot-type Public
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="Bash" %}
{% code overflow="wrap" %}

```bash
#!/bin/bash

# Description: Finds all public rds snapshots in all regions for a given aws account

# account to check
account='111111111111'

# needed to correctly parse regions
IFS=$'\n'

echo "Checking all regions in AWS account $account"

# get all available aws regions
regions=$(aws ec2 describe-regions --region us-east-1 | jq -r '.Regions[].RegionName')

# iterate through regions
for region in $regions; do
    # check for public snapshots
    echo "Checking for Public RDS snapshots in region: $region"
    
    # check for snapshots in region
    aws rds describe-db-snapshots --include-public --region $region | jq -r --arg aws_account "$account" '.DBSnapshots[] | select(.DBSnapshotIdentifier | contains($aws_account))'
done

# reset IFS
unset IFS
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

### SSM Documents

* SSM Documents allow for running commands and automation
* These may contain sensitive information&#x20;

{% tabs %}
{% tab title="Find Public Documents" %}
{% code overflow="wrap" %}

```bash
#/bin/bash

# Variables
RED="\033[31m"
RESET="\033[0m"

my_ssm_docs=$(aws ssm list-documents | jq -r '.DocumentIdentifiers[] | select(.Owner | contains("111111111111")) | (.Name)')

for doc in $(echo $my_ssm_docs); do
    status=$(aws ssm describe-document-permission --name $doc --permission-type Share | jq -r '.AccountIds[]')

    if [ "$status" != "all" ]; then
        echo "The $doc is not public."
    else
        echo "${RED}The $doc is PUBLIC.${RESET}"
    fi
done
```

{% endcode %}
{% endtab %}

{% tab title="Check Document Contents" %}
{% code overflow="wrap" %}

```bash
 aws ssm get-document --name <documentName> | jq -r '.Content'
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.techwithtyler.dev/cloud-security/aws/aws-offensive-security/aws-attacks-and-techniques/enumerate-aws-public-resources.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
