Skip to content

SQS and SNS Enumeration

4 min read Created May 24, 2026 Last updated May 24, 2026

SQS queues and SNS topics often carry application data: order records, user events, internal messages. Overpermissive access policies allow any IAM principal (or even anonymous users) to read or publish. Start by listing all queues and topics in the region. SQS and SNS are regional services, so repeat enumeration for each region where the account operates. Queue and topic names often reveal application function before you read a single message. Names like orders-prod, auth-events, or payment-processing tell you what data flows through them.

SQS

List Queues

┌──(kali㉿kali)-[~]
└─$ aws sqs list-queues --profile $PROFILE --region $REGION

Get Queue Attributes

Reveals the queue ARN, approximate message count, and access policy. A high ApproximateNumberOfMessages on a production queue is worth noting. An empty KmsMasterKeyId means message bodies are stored unencrypted at rest. Check RedrivePolicy too: it names a dead-letter queue, which accumulates failed messages and may hold sensitive data longer than the main queue.

┌──(kali㉿kali)-[~]
└─$ aws sqs get-queue-attributes --queue-url $QUEUE_URL --attribute-names All --profile $PROFILE --region $REGION

Read Messages

If you have sqs:ReceiveMessage, pull up to 10 messages at a time. Messages may contain serialized objects, JWT tokens, internal API payloads, or cleartext credentials passed between services. Look for fields named token, secret, password, or key, and decode any base64-encoded blobs.

┌──(kali㉿kali)-[~]
└─$ aws sqs receive-message --queue-url $QUEUE_URL --max-number-of-messages 10 --profile $PROFILE --region $REGION

Messages are not deleted by receiving them unless you explicitly delete them. Read safely without disrupting the queue. The visibility timeout hides a received message from other consumers for a short window (default 30 seconds), then it reappears. Pull messages, inspect the content, and let the timeout expire. Multiple reads of the same message from different sessions are fine.

Queue Access Policy

Extract and parse the policy JSON to check who can access the queue.

┌──(kali㉿kali)-[~]
└─$ aws sqs get-queue-attributes --queue-url $QUEUE_URL --attribute-names Policy --profile $PROFILE --region $REGION | jq -r '.Attributes.Policy | fromjson'

"Principal": "*" with "Effect": "Allow" on sqs:SendMessage or sqs:ReceiveMessage means anyone can read or write the queue. Check the condition block: some policies pair a wildcard principal with aws:SourceArn or aws:SourceAccount conditions that restrict callers. No condition alongside a wildcard principal is a confirmed misconfiguration. Note the queue ARN and accessible actions for your findings.

SNS

List Topics

┌──(kali㉿kali)-[~]
└─$ aws sns list-topics --profile $PROFILE --region $REGION --query 'Topics[*].TopicArn' --output table

Get Topic Attributes

Pulls the access policy, subscription counts, and delivery settings for a topic.

┌──(kali㉿kali)-[~]
└─$ aws sns get-topic-attributes --topic-arn $TOPIC_ARN --profile $PROFILE --region $REGION

Check Policy for "Principal": "*" entries. Also note SubscriptionsConfirmed and SubscriptionsPending. A pending subscription you control lets you confirm it and receive all future published messages. The DisplayName field reveals the topic's intended audience from email and SMS notifications.

List Subscriptions

┌──(kali㉿kali)-[~]
└─$ aws sns list-subscriptions-by-topic --topic-arn $TOPIC_ARN --profile $PROFILE --region $REGION --query 'Subscriptions[*].{Protocol:Protocol,Endpoint:Endpoint,Status:SubscriptionArn}' --output table

Subscriptions expose:

  • https endpoints receiving event data (internal webhook URLs, microservice endpoints)

  • email addresses (internal team aliases)

  • lambda ARNs (Lambda functions triggered by this topic)

  • sqs ARNs (cross-topic fan-out)

  • http endpoints (unencrypted: look for internal IPs)

HTTP (not HTTPS) endpoints receive message bodies over cleartext. Lambda ARNs expose the function name and account ID. SQS ARNs in subscriptions let you correlate which queues receive events from this topic.

Cross-Account Subscriptions

┌──(kali㉿kali)-[~]
└─$ aws sns list-subscriptions --profile $PROFILE --region $REGION | jq '.Subscriptions[] | select(.TopicArn | split(":")[4] != (.Endpoint | split(":")[4] // ""))'

Cross-account subscriptions mean messages from this topic flow to a different AWS account. The external account ID is field 5 in the subscription ARN. If you have access to that account, enumerate what receives those messages. Cross-account SNS delivery can also bypass per-account logging: messages may arrive in the destination account without triggering data-event entries in the source account's CloudTrail.

Publish to a Topic

If you have sns:Publish, confirm the permission with a minimal test message first. Then craft a payload that matches the subscriber's expected schema.

┌──(kali㉿kali)-[~]
└─$ aws sns publish --topic-arn $TOPIC_ARN --message "test" --profile $PROFILE --region $REGION

Publishing to an SNS topic that triggers Lambda functions or SQS processors can reach application logic and test injection paths. A malformed payload sent to a Lambda subscriber may trigger errors that leak stack traces or internal paths in CloudWatch logs. Unauthenticated publish access to a topic is a critical finding. If the topic fans out to SQS queues, injected messages may also reach those queues and their downstream processors.