Detect Serverless in Microsoft Sentinel
Adversaries may compromise serverless cloud infrastructure, such as Cloudflare Workers, AWS Lambda functions, or Google Apps Scripts, to proxy command-and-control (C2) communications between implants on victim systems and adversary-controlled backend servers. Because traffic destined for compromised serverless functions originates from subdomains of trusted cloud providers (e.g., *.workers.dev, *.execute-api.amazonaws.com, script.google.com), network-layer defenses relying on domain or IP reputation are largely ineffective. Detection pivots to behavioral analysis of victim-side telemetry: identifying processes on endpoints communicating with serverless platforms in patterns consistent with C2 beaconing (periodic connections, low-variance timing, small symmetric payloads), correlating process context with destination domains, and monitoring cloud audit logs for unauthorized modifications to serverless functions within environments the defender controls.
MITRE ATT&CK
- Tactic
- Resource Development
- Technique
- T1584 Compromise Infrastructure
- Sub-technique
- T1584.007 Serverless
- Canonical reference
- https://attack.mitre.org/techniques/T1584/007/
KQL Detection Query
let BeaconLookback = 24h;
let MinHourlyBuckets = 3;
let MinTotalConnections = 12;
let ServerlessDomains = dynamic([
"workers.dev",
"cloudflareworkers.com",
"execute-api.amazonaws.com",
"lambda-url",
"script.google.com",
"cloudfunctions.net",
"run.app",
"azurewebsites.net",
"pages.dev",
"netlify.app",
"vercel.app",
"supabase.co",
"deno.dev"
]);
let SuspiciousParents = dynamic([
"cmd.exe", "powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe",
"mshta.exe", "rundll32.exe", "regsvr32.exe", "svchost.exe"
]);
DeviceNetworkEvents
| where Timestamp > ago(BeaconLookback)
| where RemoteUrl has_any (ServerlessDomains)
| where ActionType == "ConnectionSuccess"
| extend HourBucket = bin(Timestamp, 1h)
| summarize
TotalConnections = count(),
HourlyBuckets = dcount(HourBucket),
TotalBytesSent = sum(SentBytes),
TotalBytesReceived = sum(ReceivedBytes),
RemotePorts = make_set(RemotePort, 10),
FirstSeen = min(Timestamp),
LastSeen = max(Timestamp)
by DeviceName, RemoteUrl, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
| where TotalConnections >= MinTotalConnections
| where HourlyBuckets >= MinHourlyBuckets
| extend AvgConnectionsPerHour = round(toreal(TotalConnections) / toreal(HourlyBuckets), 1)
| extend AvgBytesSentPerConn = iif(TotalConnections > 0, TotalBytesSent / TotalConnections, 0)
| extend AvgBytesReceivedPerConn = iif(TotalConnections > 0, TotalBytesReceived / TotalConnections, 0)
// Beaconing signature: high frequency, small symmetric payloads
| extend BeaconingLikely = (AvgBytesSentPerConn < 4096 and AvgBytesReceivedPerConn < 16384 and AvgConnectionsPerHour >= 2)
| extend SuspiciousInitiator = InitiatingProcessFileName has_any (SuspiciousParents)
| where BeaconingLikely or SuspiciousInitiator
| project
FirstSeen,
LastSeen,
DeviceName,
InitiatingProcessAccountName,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
RemoteUrl,
TotalConnections,
HourlyBuckets,
AvgConnectionsPerHour,
AvgBytesSentPerConn,
AvgBytesReceivedPerConn,
BeaconingLikely,
SuspiciousInitiator,
RemotePorts
| sort by TotalConnections desc Detects potential C2 beaconing through compromised serverless platform infrastructure using Microsoft Defender for Endpoint DeviceNetworkEvents. The query identifies endpoints making frequent, periodic connections to known serverless hosting domains (Cloudflare Workers, AWS Lambda URLs, Google Cloud Functions, Azure Functions, etc.) with characteristics consistent with automated beaconing: connections spread across multiple hourly time buckets, low per-connection byte counts suggesting heartbeat-style payloads rather than content delivery, and high average connection frequency. Additional weight is given when the initiating process is a scripting host or LOLBin. The domain list covers the primary serverless platforms documented in threat intelligence as being abused for C2 proxying.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate SaaS applications with serverless backends making regular telemetry or heartbeat calls (e.g., Datadog agents, monitoring tools with serverless collectors)
- Developer workstations running applications that actively use serverless functions for legitimate business logic (API calls, webhook endpoints)
- Browser-based applications using Cloudflare Workers or Vercel edge functions for content delivery, API proxying, or authentication flows
- IT automation tools and deployment pipelines (GitHub Actions, CI/CD runners) communicating with serverless orchestration backends
- Security tools and EDR agents that may communicate with cloud-hosted processing functions for telemetry or rule updates
Other platforms for T1584.007
Testing Methodology
Validate this detection against 4 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.
- Test 1Simulate C2 Beacon to Cloudflare Workers Domain
Expected signal: DeviceNetworkEvents: 15 ConnectionSuccess events from PowerShell.exe to httpbin.org, spaced ~30 seconds apart. Sysmon Event ID 3: Network connections with consistent DestinationPort=443 and DestinationHostname=httpbin.org. Inter-arrival time analysis will show MeanInterval ~30 seconds with low standard deviation (JitterCoefficient < 0.05).
- Test 2Non-Browser Process Connecting to AWS Lambda URL
Expected signal: Sysmon Event ID 3: Network connections with Image=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe making POST requests to httpbin.org:443. DeviceNetworkEvents: InitiatingProcessFileName=powershell.exe, connection count=5 with small SentBytes values. Sysmon Event ID 22: DNS query for httpbin.org from powershell.exe.
- Test 3Enumerate and Test Unauthorized AWS Lambda Function (Controlled Lab)
Expected signal: AWS CloudTrail: ListFunctions and InvokeFunction API calls logged in CloudTrail with sourceIPAddress of the calling machine, userAgent=aws-cli, and requestParameters including the function name. If forwarded to a SIEM via CloudWatch/Kinesis, these appear in your cloud audit log index. EventName=InvokeFunction with errorCode absent indicates successful invocation.
- Test 4Deploy Test Cloudflare Worker via wrangler CLI (Simulates Infrastructure Compromise Foothold)
Expected signal: Cloudflare Audit Log: Worker script deployment event with actor email, source IP, and timestamp. If Cloudflare Logpush is configured to forward audit logs to your SIEM, the event appears as audit_log.action.type=deploy with resources referencing the worker name. Process telemetry: node.exe or cmd.exe spawning wrangler commands visible in Sysmon Event ID 1.
References (9)
- https://attack.mitre.org/techniques/T1584/007/
- https://www.bleepingcomputer.com/news/security/blackwater-malware-abuses-cloudflare-workers-for-c2-communication/
- https://blog.xpnsec.com/aws-lambda-redirector/
- https://awakesecurity.com/blog/threat-hunting-series-detecting-command-control-in-the-cloud/
- https://www.bleepingcomputer.com/news/security/hackers-abuse-google-apps-script-to-steal-credit-cards-bypass-csp/
- https://docs.aws.amazon.com/lambda/latest/dg/logging-using-cloudtrail.html
- https://developers.cloudflare.com/workers/observability/logging/
- https://cloud.google.com/logging/docs/audit/understanding-audit-logs
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1584.007/T1584.007.md
Unlock Pro Content
Get the full detection package for T1584.007 including response playbook, investigation guide, and atomic red team tests.