SMS Pumping
Adversaries may leverage messaging services for SMS pumping, a telecommunications fraud technique where the attacker first obtains a block of phone numbers from a carrier, then abuses a victim's SMS infrastructure to generate large volumes of messages to those numbers. The adversary earns per-message payments from the carrier proportional to traffic volume. Attack vectors typically target public-facing web forms — OTP verification, account confirmation, password reset — backed by services such as Twilio, AWS SNS, or Amazon Cognito. Indicators include a spike in SMS API calls from a small set of source IPs, sequential or numerically adjacent destination phone numbers, destination numbers concentrated in high-fraud carrier prefixes, and a sharp increase in SMS-related cloud spend. Unlike volumetric DoS, SMS pumping is financially motivated: the attacker profits directly from the victim's messaging bill.
let SMSFormThreshold = 50;
let OTPPatterns = dynamic(["otp", "verify", "verification", "confirm", "sms", "phone", "mobile", "2fa", "mfa", "passcode", "one-time", "send-code"]);
// Branch 1: Application Insights — spike in requests to OTP/phone-verification endpoints
let Branch1 = AppRequests
| where TimeGenerated > ago(1h)
| where Url has_any (OTPPatterns) or Name has_any (OTPPatterns)
| where ResultCode == "200" or ResultCode == "429"
| summarize
RequestCount = count(),
SuccessCount = countif(ResultCode == "200"),
ThrottledCount = countif(ResultCode == "429"),
UniqueURLs = dcount(Url),
SampleURL = any(Url)
by bin(TimeGenerated, 5m), ClientIP, AppRoleName
| where RequestCount >= SMSFormThreshold
| extend DetectionSource = "AppRequests-OTPSpike"
| project TimeGenerated, SourceIP = ClientIP, Service = AppRoleName, RequestCount, UniqueTargets = UniqueURLs, DetectionSource;
// Branch 2: Azure Communication Services diagnostics — abnormal SMS send volume
let Branch2 = AzureDiagnostics
| where TimeGenerated > ago(1h)
| where ResourceType =~ "MICROSOFT.COMMUNICATION/COMMUNICATIONSERVICES"
| where OperationName =~ "SmsSend" or OperationName =~ "SmsDelivery"
| extend RecipientPhone = tostring(column_ifexists("recipientPhoneNumber_s", ""))
| summarize
RequestCount = count(),
UniqueTargets = dcount(RecipientPhone),
FailedCount = countif(ResultType =~ "Failed")
by bin(TimeGenerated, 5m), SourceIP = tostring(callerIpAddress_s), Service = ResourceGroup
| where RequestCount > 100
| extend DetectionSource = "AzureDiagnostics-SMSSpike";
// Combine detection branches
union Branch1, Branch2
| sort by TimeGenerated desc Data Sources
Required Tables
False Positives
- Legitimate bulk SMS marketing or promotional campaigns sending high volume through the same Communication Services resource
- Load testing or security testing of OTP endpoints by internal teams without prior SOC notification
- A viral product launch or viral marketing event driving a legitimate spike in new-user OTP verification requests
- Misconfigured health-check or synthetic monitoring scripts repeatedly hitting verification form endpoints
References (10)
- https://attack.mitre.org/techniques/T1496/003/
- https://www.twilio.com/en-us/blog/sms-pumping-fraud-solutions
- https://www.twilio.com/docs/glossary/what-is-sms-pumping-fraud
- https://reinforce.awsevents.com/content/dam/reinforce/2024/slides/TDR432_New-tactics-and-techniques-for-proactive-threat-detection.pdf
- https://docs.aws.amazon.com/sns/latest/dg/sms_stats_cloudwatch.html
- https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-mfa.html
- https://docs.microsoft.com/en-us/azure/communication-services/concepts/analytics/logs/sms-logs
- https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net
- https://owasp.org/www-community/attacks/SMS_OTP_Bypass
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1496/T1496.md
Unlock Pro Content
Get the full detection package for T1496.003 including response playbook, investigation guide, and atomic red team tests.