Office 365 - Sharepoint File Transfer Above Threshold
Id | abd6976d-8f71-4851-98c4-4d086201319c |
Rulename | Office 365 - Sharepoint File Transfer Above Threshold |
Description | Identifies Office365 Sharepoint File Transfers with a distinct folder count above a certain threshold in a 15-minute time period. Please note that entity mapping for arrays is not supported, so when there is a single value in an array, we will pull that value from the array as a single string to populate the entity to support entity mapping features within Sentinel. Additionally, if the array is multivalued, we will input a string to indicate this with a unique hash so that matching will not occur. |
Severity | Medium |
Tactics | Exfiltration |
Techniques | T1020 |
Required data connectors | AzureActiveDirectory |
Kind | Scheduled |
Query frequency | 15m |
Query period | 15m |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - sharepoint_file_transfer_folders_above_threshold.yaml |
Version | 1.0.5 |
Arm template | abd6976d-8f71-4851-98c4-4d086201319c.json |
let threshold = 500;
EnrichedMicrosoft365AuditLogs
| where Workload has_any("SharePoint", "OneDrive") and Operation has_any("FileDownloaded", "FileSyncDownloadedFull", "FileSyncUploadedFull", "FileUploaded")
| extend EventSource = tostring(parse_json(tostring(AdditionalProperties)).EventSource)
| extend UserAgent = tostring(parse_json(tostring(AdditionalProperties)).UserAgent)
| summarize count_distinct_ObjectId = dcount(ObjectId), dirlist = make_set(ObjectId, 10000) by UserId, ClientIp, UserAgent, bin(TimeGenerated, 15m)
| where count_distinct_ObjectId >= threshold
| extend DirSample = iff(array_length(dirlist) == 1, tostring(dirlist[0]), strcat("SeeDirListField","_", tostring(hash(tostring(dirlist)))))
| extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1])
queryPeriod: 15m
version: 1.0.5
tactics:
- Exfiltration
queryFrequency: 15m
id: abd6976d-8f71-4851-98c4-4d086201319c
triggerOperator: gt
requiredDataConnectors:
- dataTypes:
- EnrichedMicrosoft365AuditLogs
connectorId: AzureActiveDirectory
severity: Medium
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - sharepoint_file_transfer_folders_above_threshold.yaml
entityMappings:
- entityType: Account
fieldMappings:
- columnName: UserId
identifier: FullName
- columnName: AccountName
identifier: Name
- columnName: AccountUPNSuffix
identifier: UPNSuffix
- entityType: IP
fieldMappings:
- columnName: ClientIp
identifier: Address
- entityType: File
fieldMappings:
- columnName: DirSample
identifier: Name
triggerThreshold: 0
relevantTechniques:
- T1020
query: |
let threshold = 500;
EnrichedMicrosoft365AuditLogs
| where Workload has_any("SharePoint", "OneDrive") and Operation has_any("FileDownloaded", "FileSyncDownloadedFull", "FileSyncUploadedFull", "FileUploaded")
| extend EventSource = tostring(parse_json(tostring(AdditionalProperties)).EventSource)
| extend UserAgent = tostring(parse_json(tostring(AdditionalProperties)).UserAgent)
| summarize count_distinct_ObjectId = dcount(ObjectId), dirlist = make_set(ObjectId, 10000) by UserId, ClientIp, UserAgent, bin(TimeGenerated, 15m)
| where count_distinct_ObjectId >= threshold
| extend DirSample = iff(array_length(dirlist) == 1, tostring(dirlist[0]), strcat("SeeDirListField","_", tostring(hash(tostring(dirlist)))))
| extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1])
kind: Scheduled
name: Office 365 - Sharepoint File Transfer Above Threshold
customDetails:
TransferCount: count_distinct_ObjectId
FilesList: dirlist
description: |
Identifies Office365 Sharepoint File Transfers with a distinct folder count above a certain threshold in a 15-minute time period.
Please note that entity mapping for arrays is not supported, so when there is a single value in an array, we will pull that value from the array as a single string to populate the entity to support entity mapping features within Sentinel. Additionally, if the array is multivalued, we will input a string to indicate this with a unique hash so that matching will not occur.
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
matchingMethod: Selected
groupByCustomDetails: []
groupByAlertDetails: []
lookbackDuration: 5h
groupByEntities:
- Account
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/abd6976d-8f71-4851-98c4-4d086201319c')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/abd6976d-8f71-4851-98c4-4d086201319c')]",
"properties": {
"alertRuleTemplateName": "abd6976d-8f71-4851-98c4-4d086201319c",
"customDetails": {
"FilesList": "dirlist",
"TransferCount": "count_distinct_ObjectId"
},
"description": "Identifies Office365 Sharepoint File Transfers with a distinct folder count above a certain threshold in a 15-minute time period.\nPlease note that entity mapping for arrays is not supported, so when there is a single value in an array, we will pull that value from the array as a single string to populate the entity to support entity mapping features within Sentinel. Additionally, if the array is multivalued, we will input a string to indicate this with a unique hash so that matching will not occur.\n",
"displayName": "Office 365 - Sharepoint File Transfer Above Threshold",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "UserId",
"identifier": "FullName"
},
{
"columnName": "AccountName",
"identifier": "Name"
},
{
"columnName": "AccountUPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "ClientIp",
"identifier": "Address"
}
]
},
{
"entityType": "File",
"fieldMappings": [
{
"columnName": "DirSample",
"identifier": "Name"
}
]
}
],
"incidentConfiguration": {
"createIncident": true,
"groupingConfiguration": {
"enabled": true,
"groupByAlertDetails": [],
"groupByCustomDetails": [],
"groupByEntities": [
"Account"
],
"lookbackDuration": "PT5H",
"matchingMethod": "Selected",
"reopenClosedIncident": false
}
},
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - sharepoint_file_transfer_folders_above_threshold.yaml",
"query": "let threshold = 500;\nEnrichedMicrosoft365AuditLogs\n| where Workload has_any(\"SharePoint\", \"OneDrive\") and Operation has_any(\"FileDownloaded\", \"FileSyncDownloadedFull\", \"FileSyncUploadedFull\", \"FileUploaded\")\n| extend EventSource = tostring(parse_json(tostring(AdditionalProperties)).EventSource)\n| extend UserAgent = tostring(parse_json(tostring(AdditionalProperties)).UserAgent)\n| summarize count_distinct_ObjectId = dcount(ObjectId), dirlist = make_set(ObjectId, 10000) by UserId, ClientIp, UserAgent, bin(TimeGenerated, 15m)\n| where count_distinct_ObjectId >= threshold\n| extend DirSample = iff(array_length(dirlist) == 1, tostring(dirlist[0]), strcat(\"SeeDirListField\",\"_\", tostring(hash(tostring(dirlist)))))\n| extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1])\n",
"queryFrequency": "PT15M",
"queryPeriod": "PT15M",
"severity": "Medium",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"Exfiltration"
],
"techniques": [
"T1020"
],
"templateVersion": "1.0.5",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}