Exfiltration Over Webhook
Adversaries may exfiltrate data to a webhook endpoint rather than over their primary command and control channel. Webhooks are simple HTTP/S push mechanisms supported by collaboration platforms such as Discord, Slack, Microsoft Teams, and generic services like webhook.site. Adversaries exploit these endpoints by either linking an adversary-controlled webhook to a victim-owned SaaS service for automated repeated exfiltration of emails or chat messages, or by manually posting staged data directly to a webhook URL via scripting tools. Because webhook traffic is HTTPS and destined for widely-trusted SaaS domains, it blends with normal enterprise traffic and often bypasses data loss prevention controls. Observed real-world usage includes Discord webhooks for credential and token exfiltration from malicious npm packages, Slack webhooks used by insider threats, and Microsoft Teams webhooks abused via SQL Server xp_cmdshell lateral movement chains.
let WebhookDomains = dynamic([
"discord.com", "discordapp.com",
"hooks.slack.com", "slack.com",
"webhook.site", "webhooks.site",
"outlook.office.com", "outlook.office365.com",
"pipedream.net", "requestbin.com", "requestcatcher.com",
"hookbin.com", "beeceptor.com", "smee.io",
"ntfy.sh", "pushover.net"
]);
let SuspiciousInitiators = dynamic([
"powershell.exe", "pwsh.exe", "cmd.exe",
"python.exe", "python3", "node.exe",
"curl.exe", "wget.exe", "wscript.exe", "cscript.exe",
"mshta.exe", "rundll32.exe", "regsvr32.exe",
"bitsadmin.exe", "certutil.exe"
]);
// Signal 1: Network connections to webhook domains from suspicious processes
let WebhookNetworkHits = DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteUrl has_any (WebhookDomains)
or RemoteUrl matches regex @"/api/webhooks/\d+/"
or RemoteUrl has "/services/T"
| where InitiatingProcessFileName in~ (SuspiciousInitiators)
| extend Signal = "WebhookNetConn"
| extend WebhookDomain = RemoteUrl
| project Timestamp, DeviceName, AccountName, Signal,
InitiatingProcessFileName, InitiatingProcessCommandLine,
RemoteUrl, RemoteIP, RemotePort, BytesSent, BytesReceived,
WebhookDomain;
// Signal 2: Large outbound transfers to webhook domains (any process, high volume)
let WebhookLargeTransfer = DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteUrl has_any (WebhookDomains)
or RemoteUrl matches regex @"/api/webhooks/\d+/"
or RemoteUrl has "/services/T"
| where BytesSent > 1048576 // > 1MB sent
| extend Signal = "WebhookLargeTransfer"
| extend WebhookDomain = RemoteUrl
| project Timestamp, DeviceName, AccountName, Signal,
InitiatingProcessFileName, InitiatingProcessCommandLine,
RemoteUrl, RemoteIP, RemotePort, BytesSent, BytesReceived,
WebhookDomain;
// Signal 3: Process command lines containing webhook URL patterns
let WebhookCmdLine = DeviceProcessEvents
| where Timestamp > ago(24h)
| where ProcessCommandLine matches regex @"(discord\.com/api/webhooks|hooks\.slack\.com/services|webhook\.site|outlook\.office(\.com|365\.com)/webhook|pipedream\.net|requestbin\.com|hookbin\.com|beeceptor\.com|ntfy\.sh)"
| extend Signal = "WebhookCmdLine"
| extend WebhookDomain = extract(@"https?://([^/]+)", 1, ProcessCommandLine)
| project Timestamp, DeviceName, AccountName, Signal,
FileName as InitiatingProcessFileName, ProcessCommandLine as InitiatingProcessCommandLine,
RemoteUrl="(from cmdline)", RemoteIP="", RemotePort=0, BytesSent=0, BytesReceived=0,
WebhookDomain;
union WebhookNetworkHits, WebhookLargeTransfer, WebhookCmdLine
| summarize
Signals=make_set(Signal),
SignalCount=dcount(Signal),
TotalBytesSent=sum(BytesSent),
WebhookTargets=make_set(WebhookDomain),
CommandLines=make_set(InitiatingProcessCommandLine),
FirstSeen=min(Timestamp),
LastSeen=max(Timestamp),
EventCount=count()
by DeviceName, AccountName, InitiatingProcessFileName
| extend MultiSignal = SignalCount > 1
| sort by SignalCount desc, TotalBytesSent desc Data Sources
Required Tables
False Positives
- Legitimate DevOps and CI/CD pipelines posting build status notifications to Slack or Teams webhooks via scripts or pipeline agents
- IT monitoring and alerting tools (PagerDuty integrations, Grafana alerting, custom scripts) sending operational alerts to collaboration webhooks
- Developer workstations testing webhook integrations during application development, especially when using webhook.site or requestbin as debug targets
- Authorized security tools performing phishing simulations or red team exercises that post results to team notification webhooks
- Business automation scripts (Zapier alternatives, custom workflow tools) that legitimately transfer structured data to webhooks
References (11)
- https://attack.mitre.org/techniques/T1567/004/
- https://medium.com/checkmarx-security/webhook-party-malicious-packages-caught-exfiltrating-data-via-legit-webhook-services-6e046b07d191
- https://www.cyberark.com/resources/threat-research-blog/the-not-so-secret-war-on-discord
- https://blog.talosintelligence.com/collab-app-abuse/
- https://github.com/pushsecurity/saas-attacks/blob/main/techniques/webhooks/description.md
- https://www.microsoft.com/security/blog/2023/10/03/defending-new-vectors-threat-actors-attempt-sql-server-to-cloud-lateral-movement/
- https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
- https://www.redhat.com/en/topics/automation/what-is-a-webhook
- https://learn.microsoft.com/en-us/defender-endpoint/advanced-hunting-devicenetworkevents-table
- https://learn.microsoft.com/en-us/defender-endpoint/advanced-hunting-deviceprocessevents-table
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1567.004/T1567.004.md
Unlock Pro Content
Get the full detection package for T1567.004 including response playbook, investigation guide, and atomic red team tests.