Query Details

RULE 30 M365 Data Exfiltration USB Endpoint DLP

Query

// Rule     : M365 - Data Exfiltration to USB / Removable Media via Endpoint DLP
// Severity : High
// Tactics  : Exfiltration, Collection
// MITRE    : T1052.001 (Exfiltration over Physical Medium: Exfiltration over USB),
//            T1074.001 (Data Staged: Local Data Staging)
// Freq     : PT30M  /  Period: PT1H
// Purpose  : Detect when Microsoft Purview Endpoint DLP records a copy, move, or print
//            of sensitive data to a removable/USB storage device. Requires Endpoint DLP
//            enabled in Microsoft Purview with policies covering removable media.
//            RecordType = ComplianceDLPEndpoint covers the Defender for Endpoint (MDE)
//            DLP telemetry forwarded to the Unified Audit Log.
//==========================================================================================

let LookbackWindow = 1h;

// Sensitive information type names that warrant immediate High severity
let HighSensitivityTypes = dynamic([
    "Credit Card Number",
    "U.S. Social Security Number",
    "U.S. / U.K. Passport Number",
    "U.S. Bank Account Number",
    "SWIFT Code",
    "International Banking Account Number (IBAN)",
    "Azure DocumentDB Auth Key",
    "Azure SAS",
    "Azure Service Bus Shared Access Signature",
    "ABA Routing Number"]);

OfficeActivity
| where TimeGenerated > ago(LookbackWindow)
| where RecordType == "ComplianceDLPEndpoint"
// USB / removable media activities
| where PolicyDetails has_any (
    "CopyToUsbDrive",
    "CopyToRemovableMedia",
    "RemovableStorage",
    "PrintToLocalPrinter",
    "CopyToNetworkShare",
    "CopyToClipboard")
    or SensitiveInfoTypeData has_any (
        "CopyToUsbDrive",
        "RemovableStorage",
        "CopyToRemovableMedia")
| extend
    // Parse policy JSON
    PolicyDetailsJson  = todynamic(PolicyDetails),
    SensitiveInfoJson  = todynamic(SensitiveInfoTypeData),
    DeviceName         = tostring(DeviceName),
    ObjectPath         = tostring(ObjectId),
    ProcessName        = tostring(parse_json(AuditData).ProcessName)
| extend
    PolicyName         = tostring(PolicyDetailsJson[0].PolicyName),
    SensitiveTypeName  = tostring(SensitiveInfoJson[0].SensitiveInfoTypeName),
    ActionType         = tostring(PolicyDetailsJson[0].Actions[0])
| extend
    IsHighSensitivity  = SensitiveTypeName in (HighSensitivityTypes),
    IsGuest            = UserId has "#EXT#",
    AlertSeverity      = case(
        SensitiveTypeName in (HighSensitivityTypes), "High",
        ActionType has_any ("Block","BlockOverride"), "High",
        "Medium")
// Aggregate by user+device within window
| summarize
    IncidentCount      = count(),
    PolicyNames        = make_set(PolicyName, 5),
    SensitiveTypes     = make_set(SensitiveTypeName, 10),
    AffectedFiles      = make_set(ObjectPath, 15),
    ActionTypes        = make_set(ActionType, 5),
    HighSensCount      = countif(IsHighSensitivity),
    FirstObserved      = min(TimeGenerated),
    LastObserved       = max(TimeGenerated)
    by UserId, DeviceName, ClientIP, IsGuest
| extend FinalSeverity = case(
    HighSensCount > 0,    "High",
    IncidentCount >= 5,   "High",
    "Medium")
| project
    UserId,
    DeviceName,
    ClientIP,
    IsGuest,
    FirstObserved,
    LastObserved,
    IncidentCount,
    HighSensCount,
    SensitiveTypes,
    PolicyNames,
    ActionTypes,
    FinalSeverity,
    AffectedFiles
| sort by HighSensCount desc, IncidentCount desc

Explanation

This query is designed to detect and analyze potential data exfiltration activities involving sensitive information being copied, moved, or printed to USB or other removable media devices. Here's a simplified breakdown of what the query does:

  1. Time Frame: It looks at activities from the past hour.

  2. Sensitive Information: It focuses on specific types of sensitive information, such as credit card numbers, social security numbers, and other critical data types.

  3. Activity Monitoring: It checks for activities related to copying or moving data to USB drives, removable media, local printers, network shares, or the clipboard.

  4. Data Parsing: It extracts and processes details from the activity logs, such as the device name, file paths, process names, policy names, and types of sensitive information involved.

  5. Severity Assessment: It determines the severity of each incident based on the type of sensitive information and the actions taken (e.g., blocking actions are considered high severity).

  6. Aggregation: It groups the data by user and device, summarizing the number of incidents, types of sensitive information involved, and actions taken.

  7. Final Severity: It assigns a final severity level to each group based on the number of high-sensitivity incidents and the total incident count.

  8. Output: It presents a sorted list of incidents, highlighting users, devices, IP addresses, and other relevant details, with the most severe incidents listed first.

Overall, this query helps security teams identify and prioritize potential data exfiltration threats involving removable media, enabling them to take appropriate action to protect sensitive information.

Details

David Alonso profile picture

David Alonso

Released: March 18, 2026

Tables

OfficeActivity

Keywords

Devices

Operators

letdynamicagohas_anyextendtodynamictostringparse_jsoncaseinsummarizecountmake_setcountifminmaxbyprojectsortdesc

Actions