Automated Exfiltration
Adversaries may exfiltrate data through the use of automated processing after being gathered during collection. Automated exfiltration commonly involves scripted or programmatic transfer of collected files to attacker-controlled infrastructure on a schedule or triggered basis. This technique is frequently combined with T1041 (Exfiltration Over C2 Channel) or T1048 (Exfiltration Over Alternative Protocol) to move data out of the network. Real-world examples include StrongPity automatically uploading collected documents, Rover scanning local drives on a 60-minute cycle, Raccoon Stealer acting on received configuration files, and Ke3chang performing frequent scheduled exfiltration from compromised networks.
// Branch 1: Scripting engines performing bulk file enumeration followed by network activity
let ExfilProcesses = dynamic(["powershell.exe", "pwsh.exe", "python.exe", "python3.exe", "wscript.exe", "cscript.exe", "cmd.exe"]);
let TransferTools = dynamic(["curl.exe", "wget.exe", "certutil.exe", "bitsadmin.exe", "ftp.exe", "sftp.exe", "scp.exe", "robocopy.exe"]);
let ArchiveTools = dynamic(["7z.exe", "7za.exe", "winrar.exe", "rar.exe", "zip.exe", "tar.exe"]);
let SensitivePaths = dynamic(["\\Documents\\", "\\Desktop\\", "\\Downloads\\", "\\AppData\\", "\\Users\\", "\\ProgramData\\", "\\temp\\", "\\tmp\\"]);
// Detect scripting engines with exfil-relevant command patterns
DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ (ExfilProcesses)
| where ProcessCommandLine has_any ([
// PowerShell upload/transfer patterns
"UploadFile", "UploadData", "UploadString",
"Invoke-WebRequest", "Invoke-RestMethod",
"Net.WebClient", "Net.FtpWebRequest",
"Start-BitsTransfer",
// Recursive file collection patterns
"Get-ChildItem", "gci ", "ls -r", "dir /s",
"Get-Content", "[IO.File]::",
// Archive creation
"Compress-Archive", "-CompressionLevel",
// Curl/wget in scripts
"curl ", "wget ",
// FTP commands in scripts
"ftp -", "sftp "
])
| extend HasUpload = ProcessCommandLine has_any (["UploadFile", "UploadData", "UploadString", "Start-BitsTransfer", "Net.FtpWebRequest"])
| extend HasCollection = ProcessCommandLine has_any (["Get-ChildItem", "gci ", "dir /s", "Get-Content", "[IO.File]::", "Compress-Archive"])
| extend HasTransferTool = ProcessCommandLine has_any (["curl ", "wget ", "ftp -", "sftp "])
| extend SensitivePath = ProcessCommandLine has_any (SensitivePaths)
| where HasUpload or (HasCollection and HasTransferTool) or (HasCollection and SensitivePath)
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine,
HasUpload, HasCollection, HasTransferTool, SensitivePath
| sort by Timestamp desc
| union (
// Branch 2: Known transfer tools spawned shortly after archive creation or file collection
DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ (TransferTools)
| where ProcessCommandLine has_any ([
// Upload/POST indicators
"-T ", "--upload-file", "-d @", "--data-binary @",
"PUT ", "POST ",
"ftp://", "sftp://", "ftps://",
// Certutil exfil
"-urlcache", "-encode", "-decode",
// BitsAdmin upload
"/transfer", "/upload",
// SCP/SFTP file push
"scp ", "-r "
])
| extend IsExternalDest = ProcessCommandLine matches regex @"(ftp|sftp|ftps|http|https)://(?!10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.)"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine, IsExternalDest
| sort by Timestamp desc
)
| union (
// Branch 3: Archive tools creating archives in temp/staging paths — common exfil prep
DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ (ArchiveTools)
| where ProcessCommandLine has_any (SensitivePaths)
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine
| join kind=inner (
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where RemoteIPType == "Public"
| project NetTimestamp=Timestamp, DeviceName, RemoteIP, RemotePort, InitiatingProcessFileName
) on DeviceName
| where NetTimestamp between (Timestamp .. (Timestamp + 5m))
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, RemoteIP, RemotePort
| sort by Timestamp desc
) Data Sources
Required Tables
False Positives
- Backup software agents (Veeam, Acronis, Windows Server Backup) running scheduled backup jobs that compress and transfer files to remote storage
- Cloud sync clients (OneDrive sync engine, Dropbox, Google Drive File Stream) automatically uploading files in monitored user directories
- Log and telemetry collection agents (Splunk Universal Forwarder, Filebeat, NXLog) that regularly collect and ship log files to SIEM infrastructure
- IT automation tools (Ansible, SCCM) that push collected inventory or configuration data back to management servers via scripted transfer
- Developer CI/CD pipelines that use curl or similar tools to upload build artifacts or test results to artifact repositories
References (10)
- https://attack.mitre.org/techniques/T1020/
- https://www.welivesecurity.com/2020/06/11/gamaredon-group-grows-its-game/
- https://blog.talosintelligence.com/2020/06/promethium-extends-with-strongpity3.html
- https://www.bitdefender.com/files/News/CaseStudies/study/353/Bitdefender-Whitepaper-StrongPity-APT.pdf
- https://www.welivesecurity.com/2019/05/07/turla-lightneuron-email-too-far/
- https://attack.mitre.org/software/S0409/
- https://unit42.paloaltonetworks.com/ukraine-targeted-outsteel-saintbot/
- https://learn.microsoft.com/en-us/defender-endpoint/advanced-hunting-devicenetworkevents-table
- https://learn.microsoft.com/en-us/defender-endpoint/advanced-hunting-devicefileevents-table
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1020/T1020.md
Unlock Pro Content
Get the full detection package for T1020 including response playbook, investigation guide, and atomic red team tests.