Detection rules › Kusto

Netskope - Large Outbound Data Transfer / Sensitive Upload (DLP)

Status
available
Severity
high
Time window
1h
Group by
CsUsername, XCCountry, XCDevice
Source
github.com/Azure/Azure-Sentinel

Detects large outbound data transfers and sensitive file uploads. Monitors for potential data exfiltration via cloud applications.

MITRE ATT&CK coverage

Rule body kusto

id: 71e6586e-0d3f-4e33-b390-faa50b5e08fa
name: Netskope - Large Outbound Data Transfer / Sensitive Upload (DLP)
description: |
  Detects large outbound data transfers and sensitive file uploads. Monitors for potential data exfiltration via cloud applications.
severity: High
status: Available
requiredDataConnectors:
  - connectorId: NetskopeWebTxConnector
    dataTypes:
      - NetskopeWebTransactions_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Exfiltration
relevantTechniques:
  - T1567
  - T1048
query: |
  let uploadThresholdMB = 100;
  NetskopeWebTransactions_CL
  | where TimeGenerated > ago(1h)
  | where isnotempty(CsUsername)
  | where XCsAppActivity =~ 'Upload' or XCsAppActivity =~ 'Post' or XCsAppActivity =~ 'Share' 
      or CsMethod =~ 'POST' or CsMethod =~ 'PUT'
  | where CsBytes > 0 or XRsFileSize > 0
  | extend UploadBytes = coalesce(CsBytes, XRsFileSize, 0)
  | summarize 
      TotalUploadBytes = sum(UploadBytes),
      FileCount = dcount(XCsAppObjectName),
      Files = make_set(XCsAppObjectName, 10),
      FileTypes = make_set(XRsFileType),
      Apps = make_set(XCsApp),
      Destinations = make_set(XCsAppInstanceName),
      Countries = make_set(XSCountry)
      by CsUsername, XCDevice, XCCountry, bin(TimeGenerated, 1h)
  | extend TotalUploadMB = round(TotalUploadBytes / 1048576.0, 2)
  | where TotalUploadMB > uploadThresholdMB
  | extend AlertSeverity = case(
      TotalUploadMB > 1000, 'Critical',
      TotalUploadMB > 500, 'High',
      TotalUploadMB > 100, 'Medium',
      'Low')
  | project 
      TimeGenerated,
      User = CsUsername,
      UploadVolumeMB = TotalUploadMB,
      FileCount,
      Files,
      FileTypes,
      Applications = Apps,
      DestinationInstances = Destinations,
      SourceCountry = XCCountry,
      DestinationCountries = Countries,
      Device = XCDevice,
      AlertSeverity
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: User
version: 1.0.0
kind: Scheduled

Stages and Predicates

Parameters

let uploadThresholdMB = 100;

Stage 1: source

NetskopeWebTransactions_CL

Stage 2: where

| where TimeGenerated > ago(1h)

Stage 3: where

| where isnotempty(CsUsername)

Stage 4: where

| where XCsAppActivity =~ 'Upload' or XCsAppActivity =~ 'Post' or XCsAppActivity =~ 'Share' 
    or CsMethod =~ 'POST' or CsMethod =~ 'PUT'

Stage 5: where

| where CsBytes > 0 or XRsFileSize > 0

Stage 6: extend

| extend UploadBytes = coalesce(CsBytes, XRsFileSize, 0)

Stage 7: summarize

| summarize 
    TotalUploadBytes = sum(UploadBytes),
    FileCount = dcount(XCsAppObjectName),
    Files = make_set(XCsAppObjectName, 10),
    FileTypes = make_set(XRsFileType),
    Apps = make_set(XCsApp),
    Destinations = make_set(XCsAppInstanceName),
    Countries = make_set(XSCountry)
    by CsUsername, XCDevice, XCCountry, bin(TimeGenerated, 1h)

Stage 8: extend

| extend TotalUploadMB = round(TotalUploadBytes / 1048576.0, 2)

Stage 9: where

| where TotalUploadMB > uploadThresholdMB

Stage 10: extend

| extend AlertSeverity = case(
    TotalUploadMB > 1000, 'Critical',
    TotalUploadMB > 500, 'High',
    TotalUploadMB > 100, 'Medium',
    'Low')
AlertSeverity =
ifTotalUploadMB > 1000'Critical'
elifTotalUploadMB > 500'High'
elifTotalUploadMB > 100'Medium'
else'Low'

Stage 11: project

| project 
    TimeGenerated,
    User = CsUsername,
    UploadVolumeMB = TotalUploadMB,
    FileCount,
    Files,
    FileTypes,
    Applications = Apps,
    DestinationInstances = Destinations,
    SourceCountry = XCCountry,
    DestinationCountries = Countries,
    Device = XCDevice,
    AlertSeverity

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
CsBytesgt
  • 0 transforms: cased
CsMethodeq
  • POST
  • PUT
CsUsernameis_not_null
  • (no value, null check)
TotalUploadMBgt
  • 100 transforms: cased
XCsAppActivityeq
  • Post
  • Share
  • Upload
XRsFileSizegt
  • 0 transforms: cased

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
AlertSeverityproject
Applicationsproject
DestinationCountriesproject
DestinationInstancesproject
Deviceproject
FileCountproject
FileTypesproject
Filesproject
SourceCountryproject
TimeGeneratedproject
UploadVolumeMBproject
Userproject