# T1074 - Data Staged

## SOC Recommendation
Investigate Data Staged activity in the context of Collection: confirm scope, affected host/identity, and whether it matches expected administrative behaviour before deciding this is benign.

## D3FEND Mappings
| D3FEND Technique | Relationship | Practical SOC Action |
|---|---|---|
| System Call Analysis | Detect | Monitor for System Call Analysis indicators relevant to this technique. |
| File Encryption | Harden | Apply File Encryption to reduce this technique's viability before an incident occurs. |
| File Eviction | Evict | Use File Eviction to remove the adversary's foothold once this technique is confirmed. |
| System Call Filtering | Isolate | Apply System Call Filtering to contain the blast radius once this technique is observed. |

## Investigation Steps
1. Review Defender for Endpoint / Defender XDR alerts and timeline for the affected host or identity.
2. Check Sentinel analytics rules and incidents correlated with this technique.
3. Review Entra ID sign-in and audit logs if the technique involves an identity or cloud resource.

## Evidence to Collect
- Host or resource affected
- Account or identity involved
- Timestamp of the activity
- Related process, file, or network artifact
- Any preceding or follow-on alerts

## Response Actions
| Action | Risk | Automation Safe | Approval Required |
|---|---|---|---|
| Contain the affected host or account | Medium | No | Yes |
| Collect and preserve evidence | Low | Yes | No |

## KQL
```kql
let StagingPaths = dynamic(["Temp", "Downloads", "Desktop", "AppData", "ProgramData", "Public", "Recycle"]);
let ArchiveExtensions = dynamic([".zip", ".7z", ".rar", ".tar", ".gz", ".tar.gz", ".tgz", ".cab"]);
DeviceFileEvents
| where TimeGenerated >= ago(30m)
| where ActionType == "FileCreated"
| where FileName has_any (ArchiveExtensions)
| where FolderPath has_any (StagingPaths)
| summarize
    StartTime = min(TimeGenerated),
    EndTime = max(TimeGenerated),
    ArchiveCount = count(),
    Archives = make_set(FileName, 20)
    by DeviceName, AccountName, InitiatingProcessFileName
| extend timestamp = StartTime,
         HostCustomEntity = DeviceName,
         AccountCustomEntity = AccountName
| order by ArchiveCount desc
```
```kql
let highVolumeThresholdGB = 1;
NetskopeWebTransactions_CL
| where TimeGenerated > ago(1h)
| where isnotempty(CsUsername)
| summarize 
    TotalBytes = sum(Bytes),
    UploadBytes = sum(CsBytes),
    DownloadBytes = sum(ScBytes),
    UniqueApps = dcount(XCsApp),
    Apps = make_set(XCsApp, 20),
    UniqueHosts = dcount(CsHost),
    Activities = make_set(XCsAppActivity),
    Countries = make_set(XCCountry),
    Devices = make_set(XCDevice),
    AccessMethods = make_set(XCsAccessMethod),
    EventCount = count()
    by CsUsername, XCDevice, XCsAccessMethod
| extend 
    TotalGB = round(TotalBytes / 1073741824.0, 3),
    UploadGB = round(UploadBytes / 1073741824.0, 3),
    DownloadGB = round(DownloadBytes / 1073741824.0, 3)
| where TotalGB > highVolumeThresholdGB
| extend IsUnmanagedDevice = XCDevice =~ 'unmanaged' or XCDevice =~ 'BYOD' or XCDevice =~ 'Personal' or XCDevice =~ 'Unknown' or XCsAccessMethod != 'Client'
| where IsUnmanagedDevice or TotalGB > 5 or UniqueApps > 20
| extend RiskIndicators = strcat_array(array_concat(
    iff(IsUnmanagedDevice, dynamic(['Unmanaged Device']), dynamic([])),
    iff(TotalGB > 5, dynamic(['High Data Volume']), dynamic([])),
    iff(UniqueApps > 20, dynamic(['Many Apps Accessed']), dynamic([])),
    iff(array_length(Countries) > 1, dynamic(['Multiple Countries']), dynamic([]))
), ', ')
| project 
    TimeGenerated = now(),
    User = CsUsername,
    Device = XCDevice,
    AccessMethod = XCsAccessMethod,
    TotalDataGB = TotalGB,
    UploadGB,
    DownloadGB,
    UniqueApplications = UniqueApps,
    Applications = Apps,
    UniqueHosts,
    Activities,
    Countries,
    EventCount,
    IsUnmanagedDevice,
    RiskIndicators
```
```kql
let lookbackPeriod = 7d;
let currentPeriod = 1h;
let threshold = 3;
let baseline = NetskopeWebTransactions_CL
    | where TimeGenerated between (ago(lookbackPeriod) .. ago(currentPeriod))
    | where isnotempty(CsUsername)
    | where XCsAppActivity =~ 'Download' or ScBytes > 0
    | summarize 
        BaselineAvgBytes = avg(ScBytes),
        BaselineTotalBytes = sum(ScBytes),
        BaselineCount = count()
        by CsUsername
    | extend BaselineDailyAvg = BaselineTotalBytes / 7;
let current = NetskopeWebTransactions_CL
    | where TimeGenerated > ago(currentPeriod)
    | where isnotempty(CsUsername)
    | where XCsAppActivity =~ 'Download' or ScBytes > 0
    | summarize 
        CurrentTotalBytes = sum(ScBytes),
        CurrentCount = count(),
        Apps = make_set(XCsApp),
        Files = make_set(XCsAppObjectName)
        by CsUsername;
current
| join kind=inner baseline on CsUsername
| where CurrentTotalBytes > (BaselineDailyAvg * threshold)
| extend 
    SpikeMultiplier = round(CurrentTotalBytes / BaselineDailyAvg, 2),
    CurrentTotalMB = round(CurrentTotalBytes / 1048576.0, 2),
    BaselineDailyMB = round(BaselineDailyAvg / 1048576.0, 2)
| project 
    TimeGenerated = now(),
    User = CsUsername,
    CurrentDownloadMB = CurrentTotalMB,
    BaselineDailyAvgMB = BaselineDailyMB,
    SpikeMultiplier,
    DownloadCount = CurrentCount,
    ApplicationsUsed = Apps,
    FilesDownloaded = Files
```

## Escalation Criteria
- Data Staged activity observed on a privileged account or critical system.
- Activity follows or precedes other suspicious behaviour in the same investigation.
- Automated triage cannot confidently rule out malicious intent.

## False Positive Considerations
- Legitimate administrative or maintenance activity matching this pattern.
- Approved security testing or red team exercise.
- Known benign software producing similar telemetry.

Generated by SOC Response Atlas by Basyrix.
