Back
Idd6f04915-4471-4cb3-b163-a8b72997cf72
RulenameTI Map File Hash to DeviceFileEvents Event
DescriptionIdentifies a match in DeviceFileEvents Event data from any FileHash IOC from TI
SeverityMedium
TacticsCommandAndControl
TechniquesT1071
Required data connectorsMicrosoftDefenderThreatIntelligence
MicrosoftThreatProtection
ThreatIntelligence
ThreatIntelligenceTaxii
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat%20Intelligence%20%28NEW%29/Analytic%20Rules/FileHashEntity_DeviceFileEvents_Updated.yaml
Version1.0.4
Arm templated6f04915-4471-4cb3-b163-a8b72997cf72.json
Deploy To Azure
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let DeviceFileEvents_ = (union
(DeviceFileEvents | where TimeGenerated > ago(dt_lookBack) | where isnotempty(SHA1) | extend FileHashValue = SHA1),
(DeviceFileEvents | where TimeGenerated > ago(dt_lookBack) | where isnotempty(SHA256) | extend FileHashValue = SHA256));
let Hashes = DeviceFileEvents_ | distinct FileHashValue;
ThreatIntelIndicators
//extract key part of kv pair
      | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
      | where IndicatorType == "file"
      | extend FileHashType = replace("'", "", substring(ObservableKey, indexof(ObservableKey, "hashes.") + 7, strlen(ObservableKey) - indexof(ObservableKey, "hashes.") - 7))
      | extend FileHashValue = ObservableValue
      | extend IndicatorId = tostring(split(Id, "--")[2])
| where isnotempty(FileHashValue)
| where TimeGenerated > ago(ioc_lookBack)
//  | where FileHashValue in (Hashes)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue
| where IsActive and (ValidUntil > now() or isempty(ValidUntil))
| extend Description = tostring(parse_json(Data).description)
| where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
  | project-reorder *, FileHashType, FileHashValue, Type
| join kind=innerunique (DeviceFileEvents_) on $left.FileHashValue == $right.FileHashValue
| where TimeGenerated < ValidUntil
| summarize TimeGenerated = arg_max(TimeGenerated, *) by  IndicatorId, DeviceId
| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
| extend Description = tostring(parse_json(Data).description)
| extend ActivityGroupNames = extract(@"ActivityGroup:(\S+)", 1, tostring(parse_json(Data).labels))
| project TimeGenerated, TrafficLightProtocolLevel, Description, ActivityGroupNames, IndicatorId, FileHashValue, FileHashType, ValidUntil, Confidence, ActionType, DeviceId, DeviceName, FolderPath, RequestAccountDomain, RequestAccountName, RequestAccountSid, MachineGroup
| extend timestamp = TimeGenerated
name: TI Map File Hash to DeviceFileEvents Event
triggerOperator: gt
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let DeviceFileEvents_ = (union
  (DeviceFileEvents | where TimeGenerated > ago(dt_lookBack) | where isnotempty(SHA1) | extend FileHashValue = SHA1),
  (DeviceFileEvents | where TimeGenerated > ago(dt_lookBack) | where isnotempty(SHA256) | extend FileHashValue = SHA256));
  let Hashes = DeviceFileEvents_ | distinct FileHashValue;
  ThreatIntelIndicators
  //extract key part of kv pair
        | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
        | where IndicatorType == "file"
        | extend FileHashType = replace("'", "", substring(ObservableKey, indexof(ObservableKey, "hashes.") + 7, strlen(ObservableKey) - indexof(ObservableKey, "hashes.") - 7))
        | extend FileHashValue = ObservableValue
        | extend IndicatorId = tostring(split(Id, "--")[2])
  | where isnotempty(FileHashValue)
  | where TimeGenerated > ago(ioc_lookBack)
  //  | where FileHashValue in (Hashes)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue
  | where IsActive and (ValidUntil > now() or isempty(ValidUntil))
  | extend Description = tostring(parse_json(Data).description)
  | where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
    | project-reorder *, FileHashType, FileHashValue, Type
  | join kind=innerunique (DeviceFileEvents_) on $left.FileHashValue == $right.FileHashValue
  | where TimeGenerated < ValidUntil
  | summarize TimeGenerated = arg_max(TimeGenerated, *) by  IndicatorId, DeviceId
  | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
  | extend Description = tostring(parse_json(Data).description)
  | extend ActivityGroupNames = extract(@"ActivityGroup:(\S+)", 1, tostring(parse_json(Data).labels))
  | project TimeGenerated, TrafficLightProtocolLevel, Description, ActivityGroupNames, IndicatorId, FileHashValue, FileHashType, ValidUntil, Confidence, ActionType, DeviceId, DeviceName, FolderPath, RequestAccountDomain, RequestAccountName, RequestAccountSid, MachineGroup
  | extend timestamp = TimeGenerated
queryFrequency: 1h
description: |
  'Identifies a match in DeviceFileEvents Event data from any FileHash IOC from TI'
id: d6f04915-4471-4cb3-b163-a8b72997cf72
triggerThreshold: 0
queryPeriod: 14d
version: 1.0.4
kind: Scheduled
relevantTechniques:
- T1071
severity: Medium
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - DeviceFileEvents
- connectorId: ThreatIntelligence
  dataTypes:
  - ThreatIntelIndicators
- connectorId: ThreatIntelligenceTaxii
  dataTypes:
  - ThreatIntelIndicators
- connectorId: MicrosoftDefenderThreatIntelligence
  dataTypes:
  - ThreatIntelIndicators
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat%20Intelligence%20%28NEW%29/Analytic%20Rules/FileHashEntity_DeviceFileEvents_Updated.yaml
tactics:
- CommandAndControl
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: RequestAccountName
  - identifier: Sid
    columnName: RequestAccountSid
  - identifier: NTDomain
    columnName: RequestAccountDomain
  entityType: Account
- fieldMappings:
  - identifier: Value
    columnName: FileHashValue
  - identifier: Algorithm
    columnName: FileHashType
  entityType: FileHash
- fieldMappings:
  - identifier: HostName
    columnName: DeviceName
  entityType: Host
{
  "$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/d6f04915-4471-4cb3-b163-a8b72997cf72')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/d6f04915-4471-4cb3-b163-a8b72997cf72')]",
      "properties": {
        "alertRuleTemplateName": "d6f04915-4471-4cb3-b163-a8b72997cf72",
        "customDetails": null,
        "description": "'Identifies a match in DeviceFileEvents Event data from any FileHash IOC from TI'\n",
        "displayName": "TI Map File Hash to DeviceFileEvents Event",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "RequestAccountName",
                "identifier": "Name"
              },
              {
                "columnName": "RequestAccountSid",
                "identifier": "Sid"
              },
              {
                "columnName": "RequestAccountDomain",
                "identifier": "NTDomain"
              }
            ]
          },
          {
            "entityType": "FileHash",
            "fieldMappings": [
              {
                "columnName": "FileHashValue",
                "identifier": "Value"
              },
              {
                "columnName": "FileHashType",
                "identifier": "Algorithm"
              }
            ]
          },
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "DeviceName",
                "identifier": "HostName"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat%20Intelligence%20%28NEW%29/Analytic%20Rules/FileHashEntity_DeviceFileEvents_Updated.yaml",
        "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet DeviceFileEvents_ = (union\n(DeviceFileEvents | where TimeGenerated > ago(dt_lookBack) | where isnotempty(SHA1) | extend FileHashValue = SHA1),\n(DeviceFileEvents | where TimeGenerated > ago(dt_lookBack) | where isnotempty(SHA256) | extend FileHashValue = SHA256));\nlet Hashes = DeviceFileEvents_ | distinct FileHashValue;\nThreatIntelIndicators\n//extract key part of kv pair\n      | extend IndicatorType = replace(@\"\\[|\\]|\\\"\"\", \"\", tostring(split(ObservableKey, \":\", 0)))\n      | where IndicatorType == \"file\"\n      | extend FileHashType = replace(\"'\", \"\", substring(ObservableKey, indexof(ObservableKey, \"hashes.\") + 7, strlen(ObservableKey) - indexof(ObservableKey, \"hashes.\") - 7))\n      | extend FileHashValue = ObservableValue\n      | extend IndicatorId = tostring(split(Id, \"--\")[2])\n| where isnotempty(FileHashValue)\n| where TimeGenerated > ago(ioc_lookBack)\n//  | where FileHashValue in (Hashes)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue\n| where IsActive and (ValidUntil > now() or isempty(ValidUntil))\n| extend Description = tostring(parse_json(Data).description)\n| where Description !contains_cs \"State: inactive;\" and Description !contains_cs \"State: falsepos;\"\n  | project-reorder *, FileHashType, FileHashValue, Type\n| join kind=innerunique (DeviceFileEvents_) on $left.FileHashValue == $right.FileHashValue\n| where TimeGenerated < ValidUntil\n| summarize TimeGenerated = arg_max(TimeGenerated, *) by  IndicatorId, DeviceId\n| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)\n| extend Description = tostring(parse_json(Data).description)\n| extend ActivityGroupNames = extract(@\"ActivityGroup:(\\S+)\", 1, tostring(parse_json(Data).labels))\n| project TimeGenerated, TrafficLightProtocolLevel, Description, ActivityGroupNames, IndicatorId, FileHashValue, FileHashType, ValidUntil, Confidence, ActionType, DeviceId, DeviceName, FolderPath, RequestAccountDomain, RequestAccountName, RequestAccountSid, MachineGroup\n| extend timestamp = TimeGenerated\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1071"
        ],
        "templateVersion": "1.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}