Exes with double file extension and access summary
Id | d12580c2-1474-4125-a8a3-553f50d91215 |
Rulename | Exes with double file extension and access summary |
Description | Provides a summary of executable files with double file extensions in SharePoint and the users and IP addresses that have accessed them. |
Tactics | DefenseEvasion |
Techniques | T1036 |
Required data connectors | AzureActiveDirectory |
Kind | Scheduled |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Hunting Queries/double_file_ext_exes.yaml |
Version | 2.0.1 |
Arm template | d12580c2-1474-4125-a8a3-553f50d91215.json |
let known_ext = dynamic(["lnk", "log", "option", "config", "manifest", "partial"]);
let excluded_users = dynamic(["app@sharepoint"]);
EnrichedMicrosoft365AuditLogs
| where RecordType == "SharePointFileOperation" and isnotempty(ObjectId)
| where ObjectId has ".exe."
and not(ObjectId endswith ".lnk")
and not(ObjectId endswith ".log")
and not(ObjectId endswith ".option")
and not(ObjectId endswith ".config")
and not(ObjectId endswith ".manifest")
and not(ObjectId endswith ".partial")
| extend Extension = extract("[^.]*\\.[^.]*$", 0, ObjectId)
| extend SourceFileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)
| join kind=leftouter (
EnrichedMicrosoft365AuditLogs
| where RecordType == "SharePointFileOperation" and (Operation == "FileDownloaded" or Operation == "FileAccessed")
| where not(ObjectId endswith ".lnk")
and not(ObjectId endswith ".log")
and not(ObjectId endswith ".option")
and not(ObjectId endswith ".config")
and not(ObjectId endswith ".manifest")
and not(ObjectId endswith ".partial")
) on ObjectId
| where UserId1 !in (excluded_users)
| extend userBag = bag_pack("UserId", UserId1, "ClientIp", ClientIp1)
| summarize make_set(UserId1, 10000), userBag = make_bag(userBag), UploadTime = max(TimeGenerated) by UserId, ObjectId, SourceFileName, Extension
| extend NumberOfUsers = array_length(bag_keys(userBag))
| project UploadTime, Uploader = UserId, FileLocation = ObjectId, FileName = SourceFileName, AccessedBy = userBag, Extension, NumberOfUsers
| extend UploaderName = tostring(split(Uploader, "@")[0]), UploaderUPNSuffix = tostring(split(Uploader, "@")[1])
tactics:
- DefenseEvasion
id: d12580c2-1474-4125-a8a3-553f50d91215
description: |
'Provides a summary of executable files with double file extensions in SharePoint
and the users and IP addresses that have accessed them.'
query: |
let known_ext = dynamic(["lnk", "log", "option", "config", "manifest", "partial"]);
let excluded_users = dynamic(["app@sharepoint"]);
EnrichedMicrosoft365AuditLogs
| where RecordType == "SharePointFileOperation" and isnotempty(ObjectId)
| where ObjectId has ".exe."
and not(ObjectId endswith ".lnk")
and not(ObjectId endswith ".log")
and not(ObjectId endswith ".option")
and not(ObjectId endswith ".config")
and not(ObjectId endswith ".manifest")
and not(ObjectId endswith ".partial")
| extend Extension = extract("[^.]*\\.[^.]*$", 0, ObjectId)
| extend SourceFileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)
| join kind=leftouter (
EnrichedMicrosoft365AuditLogs
| where RecordType == "SharePointFileOperation" and (Operation == "FileDownloaded" or Operation == "FileAccessed")
| where not(ObjectId endswith ".lnk")
and not(ObjectId endswith ".log")
and not(ObjectId endswith ".option")
and not(ObjectId endswith ".config")
and not(ObjectId endswith ".manifest")
and not(ObjectId endswith ".partial")
) on ObjectId
| where UserId1 !in (excluded_users)
| extend userBag = bag_pack("UserId", UserId1, "ClientIp", ClientIp1)
| summarize make_set(UserId1, 10000), userBag = make_bag(userBag), UploadTime = max(TimeGenerated) by UserId, ObjectId, SourceFileName, Extension
| extend NumberOfUsers = array_length(bag_keys(userBag))
| project UploadTime, Uploader = UserId, FileLocation = ObjectId, FileName = SourceFileName, AccessedBy = userBag, Extension, NumberOfUsers
| extend UploaderName = tostring(split(Uploader, "@")[0]), UploaderUPNSuffix = tostring(split(Uploader, "@")[1])
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- EnrichedMicrosoft365AuditLogs
kind: Scheduled
entityMappings:
- entityType: Account
fieldMappings:
- columnName: UploaderName
identifier: Name
- columnName: UploaderUPNSuffix
identifier: UPNSuffix
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Hunting Queries/double_file_ext_exes.yaml
relevantTechniques:
- T1036
name: Exes with double file extension and access summary
version: 2.0.1
{
"$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/d12580c2-1474-4125-a8a3-553f50d91215')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/d12580c2-1474-4125-a8a3-553f50d91215')]",
"properties": {
"alertRuleTemplateName": "d12580c2-1474-4125-a8a3-553f50d91215",
"customDetails": null,
"description": "'Provides a summary of executable files with double file extensions in SharePoint \n and the users and IP addresses that have accessed them.'\n",
"displayName": "Exes with double file extension and access summary",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "UploaderName",
"identifier": "Name"
},
{
"columnName": "UploaderUPNSuffix",
"identifier": "UPNSuffix"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Hunting Queries/double_file_ext_exes.yaml",
"query": "let known_ext = dynamic([\"lnk\", \"log\", \"option\", \"config\", \"manifest\", \"partial\"]);\nlet excluded_users = dynamic([\"app@sharepoint\"]);\nEnrichedMicrosoft365AuditLogs\n| where RecordType == \"SharePointFileOperation\" and isnotempty(ObjectId)\n| where ObjectId has \".exe.\" \n and not(ObjectId endswith \".lnk\") \n and not(ObjectId endswith \".log\") \n and not(ObjectId endswith \".option\") \n and not(ObjectId endswith \".config\") \n and not(ObjectId endswith \".manifest\") \n and not(ObjectId endswith \".partial\")\n| extend Extension = extract(\"[^.]*\\\\.[^.]*$\", 0, ObjectId)\n| extend SourceFileName = tostring(parse_json(tostring(AdditionalProperties)).SourceFileName)\n| join kind=leftouter (\n EnrichedMicrosoft365AuditLogs\n | where RecordType == \"SharePointFileOperation\" and (Operation == \"FileDownloaded\" or Operation == \"FileAccessed\")\n | where not(ObjectId endswith \".lnk\") \n and not(ObjectId endswith \".log\") \n and not(ObjectId endswith \".option\") \n and not(ObjectId endswith \".config\") \n and not(ObjectId endswith \".manifest\") \n and not(ObjectId endswith \".partial\")\n) on ObjectId\n| where UserId1 !in (excluded_users)\n| extend userBag = bag_pack(\"UserId\", UserId1, \"ClientIp\", ClientIp1)\n| summarize make_set(UserId1, 10000), userBag = make_bag(userBag), UploadTime = max(TimeGenerated) by UserId, ObjectId, SourceFileName, Extension\n| extend NumberOfUsers = array_length(bag_keys(userBag))\n| project UploadTime, Uploader = UserId, FileLocation = ObjectId, FileName = SourceFileName, AccessedBy = userBag, Extension, NumberOfUsers\n| extend UploaderName = tostring(split(Uploader, \"@\")[0]), UploaderUPNSuffix = tostring(split(Uploader, \"@\")[1])\n",
"subTechniques": [],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"DefenseEvasion"
],
"techniques": [
"T1036"
],
"templateVersion": "2.0.1"
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}