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
- Enumeration: Used
s3scannerwith a custom wordlist based on target names.
python3 s3scanner.py --bucket-wordlist targets.txt --out-file buckets.txt
Found: dev-app-backups.examplecorp.com.
- Inspection: The bucket had
ListandGetpermissions for "Any Authenticated AWS User."
aws s3 ls s3://dev-app-backups.examplecorp.com --no-sign-request
# Found: `application.tar.gz`, `config-backup.zip`
- Exfiltration & Analysis: Downloaded the
config-backup.zipfile. It contained a.envfile 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 theus-east-1region. - Fix: Used the AWS CLI's
--regionflag to enumerate all commercial regions. The keys were active inap-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 policyAmazonS3FullAccess. This allowed us to write a malicious Lambda function and trigger it, effectively moving from storage to compute. - Unexpected Finding: The
.envfile 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