Scheduled Transfer
Adversaries may schedule data exfiltration to be performed only at certain times of day or at certain intervals. This is commonly observed in malware configured to beacon or exfiltrate at fixed intervals (e.g., every 10 minutes, every 8 hours) or only during business hours to blend with normal traffic. Scheduled transfer almost always combines with another exfiltration technique such as Exfiltration Over C2 Channel (T1041) or Exfiltration Over Alternative Protocol (T1048). Real-world examples include ComRAT sleeping outside 9-to-5 Monday–Friday, LightNeuron configuring nighttime-only exfiltration windows, ADVSTORESHELL compressing and exfiltrating every 10 minutes, and Cobalt Strike Beacon using randomized sleep intervals to resist frequency-based detection.
// T1029 Scheduled Transfer — Beaconing pattern detection and scheduled-task-triggered exfiltration
// Part 1: Regular-interval connections from non-browser, non-system processes to public IPs
let ExcludedProcesses = dynamic([
"chrome.exe", "firefox.exe", "msedge.exe", "MicrosoftEdge.exe", "iexplore.exe",
"teams.exe", "outlook.exe", "slack.exe", "zoom.exe", "OneDrive.exe",
"svchost.exe", "MsMpEng.exe", "SecurityHealthService.exe", "SenseIR.exe",
"SearchIndexer.exe", "WerFault.exe", "wuauclt.exe", "msiexec.exe",
"spoolsv.exe", "lsass.exe", "services.exe", "smss.exe"
]);
let ExfiltrationTools = dynamic([
"curl.exe", "certutil.exe", "bitsadmin.exe", "ftp.exe", "tftp.exe",
"rclone.exe", "wget.exe", "nc.exe", "ncat.exe", "robocopy.exe"
]);
// Beaconing pattern: >= 5 connections to same external IP with regular interval
let BeaconingAlerts = DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIPType == "Public"
| where InitiatingProcessFileName !in~ (ExcludedProcesses)
| summarize
ConnectionCount = count(),
EarliestConnection = min(Timestamp),
LatestConnection = max(Timestamp),
BytesSent = sum(SentBytes),
BytesReceived = sum(ReceivedBytes),
Ports = make_set(RemotePort, 10)
by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine,
InitiatingProcessAccountName, RemoteIP
| where ConnectionCount >= 5
| extend TimeSpanMinutes = datetime_diff('minute', LatestConnection, EarliestConnection)
| where TimeSpanMinutes >= 20
| extend AvgIntervalMinutes = toreal(TimeSpanMinutes) / toreal(ConnectionCount - 1)
| where AvgIntervalMinutes between (1.0 .. 120.0)
| extend DetectionType = "Beaconing"
| extend IsHighConfidenceBeacon = (ConnectionCount >= 8 and AvgIntervalMinutes between (5.0 .. 30.0))
| project Timestamp = LatestConnection, DeviceName,
AccountName = InitiatingProcessAccountName,
ProcessName = InitiatingProcessFileName,
CommandLine = InitiatingProcessCommandLine,
RemoteIP, Ports, ConnectionCount,
AvgIntervalMinutes, BytesSent, BytesReceived,
DetectionType, IsHighConfidenceBeacon;
// Scheduled task spawning data transfer tools
let ScheduledTaskExfil = DeviceProcessEvents
| where Timestamp > ago(24h)
| where InitiatingProcessFileName in~ ("taskeng.exe", "taskhostw.exe", "schtasks.exe")
or (InitiatingProcessFileName =~ "svchost.exe"
and InitiatingProcessCommandLine has_any ("-k netsvcs", "Schedule"))
| where FileName in~ (ExfiltrationTools)
or (FileName in~ ("powershell.exe", "pwsh.exe")
and ProcessCommandLine has_any (
"Invoke-WebRequest", "WebClient", "UploadFile", "UploadData",
"FtpWebRequest", "curl", "wget", "SendAsync", "HttpClient"
))
or (FileName =~ "cmd.exe"
and ProcessCommandLine has_any ("curl", "ftp", "certutil", "bitsadmin"))
| extend DetectionType = "ScheduledTaskExfil"
| extend IsHighConfidenceBeacon = false
| project Timestamp, DeviceName, AccountName,
ProcessName = FileName, CommandLine = ProcessCommandLine,
RemoteIP = "", Ports = dynamic([]), ConnectionCount = 1,
AvgIntervalMinutes = toreal(0), BytesSent = long(0), BytesReceived = long(0),
DetectionType, IsHighConfidenceBeacon;
union BeaconingAlerts, ScheduledTaskExfil
| sort by Timestamp desc Data Sources
Required Tables
False Positives
- Monitoring agents (Datadog, SolarWinds, New Relic, PRTG) that make periodic health checks or metric uploads to cloud endpoints at fixed intervals
- Backup software (Veeam, Acronis, Backup Exec) with scheduled upload tasks that invoke transfer utilities from svchost or task context
- Software update services (WSUS clients, antivirus definition updates, patching tools) that poll external servers at regular intervals
- Legitimate IT automation scripts (Ansible, Chef, Puppet) invoked by the Task Scheduler for periodic configuration synchronisation
- Cloud sync clients (Dropbox, Box, Google Drive daemon processes) making regular upload connections that are not yet excluded by the process allowlist
References (10)
- https://attack.mitre.org/techniques/T1029/
- https://www.welivesecurity.com/wp-content/uploads/2019/05/ESET-LightNeuron.pdf
- https://www.welivesecurity.com/2020/05/26/operation-lagtime-it-backdoors-government-networks-eastern-asia/
- https://securelist.com/shadowpad-in-corporate-networks/81432/
- https://cobaltstrike.com/help-beacon
- https://learn.microsoft.com/en-us/windows/win32/taskschd/task-scheduler-start-page
- https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/bitsadmin
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1029/T1029.md
- https://www.mandiant.com/resources/blog/identifying-cobalt-strike-team-servers-in-the-wild
- https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon
Unlock Pro Content
Get the full detection package for T1029 including response playbook, investigation guide, and atomic red team tests.