Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

TI map File Hash to Security Event

Back
Ida7427ed7-04b4-4e3b-b323-08b981b9b4bf
RulenameTI map File Hash to Security Event
DescriptionIdentifies a match in Security Event data from any File Hash IOC from TI
SeverityMedium
TacticsCommandAndControl
TechniquesT1071
Required data connectorsMicrosoftDefenderThreatIntelligence
SecurityEvents
ThreatIntelligence
ThreatIntelligenceTaxii
WindowsForwardedEvents
WindowsSecurityEvents
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/FileHashEntity_SecurityEvent.yaml
Version1.4.6
Arm templatea7427ed7-04b4-4e3b-b323-08b981b9b4bf.json
Deploy To Azure
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
ThreatIntelligenceIndicator
| where isnotempty(FileHashValue)
| where TimeGenerated >= ago(ioc_lookBack)
| extend FileHashValue = toupper(FileHashValue)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true and ExpirationDateTime > now()
// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
| join kind=innerunique ( union isfuzzy=true
  (SecurityEvent | where TimeGenerated >= ago(dt_lookBack)
      | where EventID in ("8003","8002","8005")
      | where isnotempty(FileHash)
      | extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID, FileHash = toupper(FileHash)
  ),
  (WindowsEvent | where TimeGenerated >= ago(dt_lookBack)
      | where EventID in ("8003","8002","8005")
      | where isnotempty(EventData.FileHash)
      | extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID, FileHash = toupper(EventData.FileHash)
  )
)
on $left.FileHashValue == $right.FileHash
| where SecurityEvent_TimeGenerated < ExpirationDateTime
| summarize SecurityEvent_TimeGenerated = arg_max(SecurityEvent_TimeGenerated, *) by IndicatorId, FileHash
| project SecurityEvent_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,
Process, FileHash, Computer, Account, Event, FileHashValue, FileHashType
| extend NTDomain = tostring(split(Account, '\\', 0)[0]), Name = tostring(split(Account, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.')) 
| extend timestamp = SecurityEvent_TimeGenerated
id: a7427ed7-04b4-4e3b-b323-08b981b9b4bf
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  ThreatIntelligenceIndicator
  | where isnotempty(FileHashValue)
  | where TimeGenerated >= ago(ioc_lookBack)
  | extend FileHashValue = toupper(FileHashValue)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
  | where Active == true and ExpirationDateTime > now()
  // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
  | join kind=innerunique ( union isfuzzy=true
    (SecurityEvent | where TimeGenerated >= ago(dt_lookBack)
        | where EventID in ("8003","8002","8005")
        | where isnotempty(FileHash)
        | extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID, FileHash = toupper(FileHash)
    ),
    (WindowsEvent | where TimeGenerated >= ago(dt_lookBack)
        | where EventID in ("8003","8002","8005")
        | where isnotempty(EventData.FileHash)
        | extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID, FileHash = toupper(EventData.FileHash)
    )
  )
  on $left.FileHashValue == $right.FileHash
  | where SecurityEvent_TimeGenerated < ExpirationDateTime
  | summarize SecurityEvent_TimeGenerated = arg_max(SecurityEvent_TimeGenerated, *) by IndicatorId, FileHash
  | project SecurityEvent_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,
  Process, FileHash, Computer, Account, Event, FileHashValue, FileHashType
  | extend NTDomain = tostring(split(Account, '\\', 0)[0]), Name = tostring(split(Account, '\\', 1)[0])
  | extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.')) 
  | extend timestamp = SecurityEvent_TimeGenerated  
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/FileHashEntity_SecurityEvent.yaml
description: |
    'Identifies a match in Security Event data from any File Hash IOC from TI'
name: TI map File Hash to Security Event
relevantTechniques:
- T1071
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: Account
  - identifier: Name
    columnName: Name
  - identifier: NTDomain
    columnName: NTDomain
- entityType: Host
  fieldMappings:
  - identifier: FullName
    columnName: Computer
  - identifier: HostName
    columnName: HostName
  - identifier: DnsDomain
    columnName: DnsDomain
- entityType: URL
  fieldMappings:
  - identifier: Url
    columnName: Url
- entityType: FileHash
  fieldMappings:
  - identifier: Value
    columnName: FileHashValue
  - identifier: Algorithm
    columnName: FileHashType
triggerThreshold: 0
severity: Medium
requiredDataConnectors:
- dataTypes:
  - SecurityEvent
  connectorId: SecurityEvents
- dataTypes:
  - SecurityEvents
  connectorId: WindowsSecurityEvents
- dataTypes:
  - WindowsEvent
  connectorId: WindowsForwardedEvents
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: ThreatIntelligence
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: ThreatIntelligenceTaxii
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: MicrosoftDefenderThreatIntelligence
queryFrequency: 1h
queryPeriod: 14d
version: 1.4.6
kind: Scheduled
tactics:
- CommandAndControl
triggerOperator: gt
{
  "$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/a7427ed7-04b4-4e3b-b323-08b981b9b4bf')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/a7427ed7-04b4-4e3b-b323-08b981b9b4bf')]",
      "properties": {
        "alertRuleTemplateName": "a7427ed7-04b4-4e3b-b323-08b981b9b4bf",
        "customDetails": null,
        "description": "'Identifies a match in Security Event data from any File Hash IOC from TI'\n",
        "displayName": "TI map File Hash to Security Event",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "Account",
                "identifier": "FullName"
              },
              {
                "columnName": "Name",
                "identifier": "Name"
              },
              {
                "columnName": "NTDomain",
                "identifier": "NTDomain"
              }
            ]
          },
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "Computer",
                "identifier": "FullName"
              },
              {
                "columnName": "HostName",
                "identifier": "HostName"
              },
              {
                "columnName": "DnsDomain",
                "identifier": "DnsDomain"
              }
            ]
          },
          {
            "entityType": "URL",
            "fieldMappings": [
              {
                "columnName": "Url",
                "identifier": "Url"
              }
            ]
          },
          {
            "entityType": "FileHash",
            "fieldMappings": [
              {
                "columnName": "FileHashValue",
                "identifier": "Value"
              },
              {
                "columnName": "FileHashType",
                "identifier": "Algorithm"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/FileHashEntity_SecurityEvent.yaml",
        "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where isnotempty(FileHashValue)\n| where TimeGenerated >= ago(ioc_lookBack)\n| extend FileHashValue = toupper(FileHashValue)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true and ExpirationDateTime > now()\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique ( union isfuzzy=true\n  (SecurityEvent | where TimeGenerated >= ago(dt_lookBack)\n      | where EventID in (\"8003\",\"8002\",\"8005\")\n      | where isnotempty(FileHash)\n      | extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID, FileHash = toupper(FileHash)\n  ),\n  (WindowsEvent | where TimeGenerated >= ago(dt_lookBack)\n      | where EventID in (\"8003\",\"8002\",\"8005\")\n      | where isnotempty(EventData.FileHash)\n      | extend SecurityEvent_TimeGenerated = TimeGenerated, Event = EventID, FileHash = toupper(EventData.FileHash)\n  )\n)\non $left.FileHashValue == $right.FileHash\n| where SecurityEvent_TimeGenerated < ExpirationDateTime\n| summarize SecurityEvent_TimeGenerated = arg_max(SecurityEvent_TimeGenerated, *) by IndicatorId, FileHash\n| project SecurityEvent_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\nProcess, FileHash, Computer, Account, Event, FileHashValue, FileHashType\n| extend NTDomain = tostring(split(Account, '\\\\', 0)[0]), Name = tostring(split(Account, '\\\\', 1)[0])\n| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.')) \n| extend timestamp = SecurityEvent_TimeGenerated\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1071"
        ],
        "templateVersion": "1.4.6",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}