Exfiltration Over C2 Channel
Adversaries may steal data by exfiltrating it over an existing command and control channel. Stolen data is encoded into the normal communications channel using the same protocol as command and control communications. This technique is particularly challenging to detect because exfiltration traffic is indistinguishable from regular C2 beaconing — adversaries embed collected data inside HTTP POST bodies, DNS query labels, custom binary protocol frames, or other C2 protocol fields. Detection requires correlating large outbound data volumes, repeated connection patterns, and sensitive file access rather than inspecting payload content. Real-world actors observed using this technique include Scattered Spider (VMware vCenter via Teleport), OilRig/APT34 (OneDrive-based C2), and malware families PoetRAT, Machete, Shark, StrelaStealer, BeaverTail, SLOTHFULMEDIA, Sagerunex, and Bandook. The technique spans Windows, Linux, macOS, and ESXi platforms and commonly exploits encrypted C2 channels (HTTPS, DNS-over-HTTPS) to blend with legitimate traffic.
let TimeWindow = 24h;
let MinBytesSent = 1048576; // 1 MB threshold — tune up for high-data environments
let MinConnectionCount = 20; // Repeated connections indicating active C2 with embedded data
let SuspiciousProcesses = dynamic([
"powershell.exe", "pwsh.exe", "cmd.exe", "wscript.exe", "cscript.exe",
"mshta.exe", "rundll32.exe", "regsvr32.exe", "certutil.exe",
"python.exe", "python3.exe", "ruby.exe", "perl.exe",
"curl.exe", "wget.exe", "bitsadmin.exe", "nc.exe"
]);
// Step 1: Identify processes with high outbound byte volume or high connection frequency to public IPs
let HighVolumeOutbound = DeviceNetworkEvents
| where Timestamp > ago(TimeWindow)
| where ActionType == "ConnectionSuccess"
| where RemoteIPType == "Public"
| where InitiatingProcessFileName has_any (SuspiciousProcesses)
or BytesSent > MinBytesSent
| summarize
TotalBytesSent = sum(BytesSent),
TotalBytesReceived = sum(BytesReceived),
ConnectionCount = count(),
UniqueRemoteIPs = dcount(RemoteIP),
RemoteIPs = make_set(RemoteIP, 5),
RemotePorts = make_set(RemotePort, 5),
FirstSeen = min(Timestamp),
LastSeen = max(Timestamp)
by DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessId, InitiatingProcessCommandLine
| where TotalBytesSent > MinBytesSent or ConnectionCount > MinConnectionCount;
// Step 2: Correlate with sensitive file reads (collect-then-exfil pattern)
let SensitiveFileReads = DeviceFileEvents
| where Timestamp > ago(TimeWindow)
| where ActionType == "FileRead"
| where FileName has_any (dynamic([".doc", ".docx", ".pdf", ".xlsx", ".xls", ".csv",
".zip", ".7z", ".tar", ".gz", ".kdbx", ".pfx", ".pem", ".key",
".db", ".sqlite", ".rdp", ".config", ".conf"]))
| summarize FilesRead = count(), SensitiveFileNames = make_set(FileName, 10)
by DeviceName, InitiatingProcessId;
// Step 3: Join and score
HighVolumeOutbound
| join kind=leftouter SensitiveFileReads on DeviceName, InitiatingProcessId
| extend ExfilRatio = iff(TotalBytesReceived > 0,
round(todouble(TotalBytesSent) / todouble(TotalBytesReceived), 2), 999.0)
| extend IsHighVolume = TotalBytesSent > MinBytesSent
| extend IsHighFrequency = ConnectionCount > MinConnectionCount
| extend IsSingleDestination = UniqueRemoteIPs == 1
| extend HasSensitiveFileAccess = isnotnull(FilesRead) and FilesRead > 0
| extend HighExfilRatio = ExfilRatio > 5.0
| extend ExfilScore = tolong(IsHighVolume) + tolong(IsHighFrequency)
+ tolong(IsSingleDestination) + tolong(HasSensitiveFileAccess) + tolong(HighExfilRatio)
| where ExfilScore >= 2
| project
Timestamp = LastSeen,
DeviceName,
AccountName,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
TotalBytesSent,
TotalBytesReceived,
ExfilRatio,
ConnectionCount,
UniqueRemoteIPs,
RemoteIPs,
RemotePorts,
FilesRead,
SensitiveFileNames,
IsHighVolume,
IsHighFrequency,
IsSingleDestination,
HasSensitiveFileAccess,
ExfilScore
| sort by ExfilScore desc, TotalBytesSent desc Data Sources
Required Tables
False Positives
- Backup agents (Veeam, Backup Exec, Azure Backup) performing scheduled backups generate large outbound transfers to cloud storage endpoints
- Log shippers and telemetry agents (Splunk Universal Forwarder, Elastic Agent, Datadog) make frequent high-volume connections to their ingestion endpoints
- Cloud sync clients (OneDrive, Dropbox, Google Drive) continuously upload large volumes of data using common scripting engines on managed endpoints
- Software update and patch management clients (SCCM, Intune, WSUS) sending device inventory telemetry over HTTPS to Microsoft infrastructure
- Security scanners and vulnerability assessment tools (Qualys, Nessus agent) making high-frequency outbound connections during scan cycles
References (12)
- https://attack.mitre.org/techniques/T1041/
- https://www.mandiant.com/resources/blog/scattered-spider-vmware-vsphere
- https://www.welivesecurity.com/2023/12/14/eset-apt-activity-report-t22023/
- https://blog.talosintelligence.com/talos-poet-rat/
- https://www.clearskysec.com/siamesekitten/
- 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/T1041/T1041.md
- https://github.com/SigmaHQ/sigma/tree/master/rules/windows/network_connection
- https://arxiv.org/ftp/arxiv/papers/1408/1408.1136.pdf
- https://www.cisa.gov/sites/default/files/publications/MAR-10303405-1.v1.WHITE.pdf
- https://unit42.paloaltonetworks.com/mechaFlounder/
Unlock Pro Content
Get the full detection package for T1041 including response playbook, investigation guide, and atomic red team tests.