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

TI Map Domain Entity to DeviceNetworkEvents

Back
Id1546f3b3-de8a-4e62-bfea-815422154981
RulenameTI Map Domain Entity to DeviceNetworkEvents
DescriptionThis query identifies any Domain indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in DeviceNetworkEvents.
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 Intelligence (NEW)/Analytic Rules/DomainEntity_DeviceNetworkEvents_Updated.yaml
Version1.0.4
Arm template1546f3b3-de8a-4e62-bfea-815422154981.json
Deploy To Azure
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let DeviceNetworkEvents_ = DeviceNetworkEvents
  | where isnotempty(RemoteUrl)
  | where TimeGenerated >= ago(dt_lookBack)
  | where ActionType !has "ConnectionFailed"
  | extend Domain = tostring(parse_url(tolower(RemoteUrl)).Host)
  | where isnotempty(Domain)
  | project-rename DeviceNetworkEvents_TimeGenerated = TimeGenerated;
let DeviceNetworkEventDomains = DeviceNetworkEvents_
  | distinct Domain
  | summarize make_list(Domain);
ThreatIntelIndicators
| extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
| where IndicatorType == "domain-name"
| extend DomainName = tolower(ObservableValue)
| where TimeGenerated >= ago(ioc_lookBack)
| extend IndicatorId = tostring(split(Id, "--")[2])
| where DomainName in (DeviceNetworkEventDomains)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue
| where IsActive and (ValidUntil > now() or isempty(ValidUntil))
| extend Description = tostring(parse_json(Data).description)
| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
| where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
| project-reorder *, IsActive, Tags, TrafficLightProtocolLevel, DomainName, Type
| join kind=innerunique (DeviceNetworkEvents_) on $left.DomainName == $right.Domain
| where DeviceNetworkEvents_TimeGenerated < ValidUntil
| summarize DeviceNetworkEvents_TimeGenerated = arg_max(DeviceNetworkEvents_TimeGenerated, *) by IndicatorId
| project DeviceNetworkEvents_TimeGenerated, IndicatorId, Url = RemoteUrl, Confidence, Description, Tags, TrafficLightProtocolLevel, ActionType, DeviceId, DeviceName, InitiatingProcessAccountUpn, InitiatingProcessCommandLine, RemoteIP, RemotePort
| extend Name = tostring(split(InitiatingProcessAccountUpn, '@', 0)[0]), UPNSuffix = tostring(split(InitiatingProcessAccountUpn, '@', 1)[0])
| extend timestamp = DeviceNetworkEvents_TimeGenerated, UserPrincipalName = InitiatingProcessAccountUpn
kind: Scheduled
tactics:
- CommandAndControl
name: TI Map Domain Entity to DeviceNetworkEvents
id: 1546f3b3-de8a-4e62-bfea-815422154981
queryFrequency: 1h
severity: Medium
version: 1.0.4
triggerThreshold: 0
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/DomainEntity_DeviceNetworkEvents_Updated.yaml
queryPeriod: 14d
description: |
    'This query identifies any Domain indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in DeviceNetworkEvents.'
triggerOperator: gt
requiredDataConnectors:
- dataTypes:
  - DeviceNetworkEvents
  connectorId: MicrosoftThreatProtection
- dataTypes:
  - ThreatIntelIndicators
  connectorId: ThreatIntelligence
- dataTypes:
  - ThreatIntelIndicators
  connectorId: ThreatIntelligenceTaxii
- dataTypes:
  - ThreatIntelIndicators
  connectorId: MicrosoftDefenderThreatIntelligence
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let DeviceNetworkEvents_ = DeviceNetworkEvents
    | where isnotempty(RemoteUrl)
    | where TimeGenerated >= ago(dt_lookBack)
    | where ActionType !has "ConnectionFailed"
    | extend Domain = tostring(parse_url(tolower(RemoteUrl)).Host)
    | where isnotempty(Domain)
    | project-rename DeviceNetworkEvents_TimeGenerated = TimeGenerated;
  let DeviceNetworkEventDomains = DeviceNetworkEvents_
    | distinct Domain
    | summarize make_list(Domain);
  ThreatIntelIndicators
  | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
  | where IndicatorType == "domain-name"
  | extend DomainName = tolower(ObservableValue)
  | where TimeGenerated >= ago(ioc_lookBack)
  | extend IndicatorId = tostring(split(Id, "--")[2])
  | where DomainName in (DeviceNetworkEventDomains)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue
  | where IsActive and (ValidUntil > now() or isempty(ValidUntil))
  | extend Description = tostring(parse_json(Data).description)
  | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
  | where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;"
  | project-reorder *, IsActive, Tags, TrafficLightProtocolLevel, DomainName, Type
  | join kind=innerunique (DeviceNetworkEvents_) on $left.DomainName == $right.Domain
  | where DeviceNetworkEvents_TimeGenerated < ValidUntil
  | summarize DeviceNetworkEvents_TimeGenerated = arg_max(DeviceNetworkEvents_TimeGenerated, *) by IndicatorId
  | project DeviceNetworkEvents_TimeGenerated, IndicatorId, Url = RemoteUrl, Confidence, Description, Tags, TrafficLightProtocolLevel, ActionType, DeviceId, DeviceName, InitiatingProcessAccountUpn, InitiatingProcessCommandLine, RemoteIP, RemotePort
  | extend Name = tostring(split(InitiatingProcessAccountUpn, '@', 0)[0]), UPNSuffix = tostring(split(InitiatingProcessAccountUpn, '@', 1)[0])
  | extend timestamp = DeviceNetworkEvents_TimeGenerated, UserPrincipalName = InitiatingProcessAccountUpn  
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: Name
    identifier: Name
  - columnName: UPNSuffix
    identifier: UPNSuffix
- entityType: Host
  fieldMappings:
  - columnName: DeviceName
    identifier: FullName
- entityType: URL
  fieldMappings:
  - columnName: Url
    identifier: Url
- entityType: Process
  fieldMappings:
  - columnName: InitiatingProcessCommandLine
    identifier: CommandLine
relevantTechniques:
- T1071
{
  "$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/1546f3b3-de8a-4e62-bfea-815422154981')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/1546f3b3-de8a-4e62-bfea-815422154981')]",
      "properties": {
        "alertRuleTemplateName": "1546f3b3-de8a-4e62-bfea-815422154981",
        "customDetails": null,
        "description": "'This query identifies any Domain indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in DeviceNetworkEvents.'\n",
        "displayName": "TI Map Domain Entity to DeviceNetworkEvents",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "Name",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "DeviceName",
                "identifier": "FullName"
              }
            ]
          },
          {
            "entityType": "URL",
            "fieldMappings": [
              {
                "columnName": "Url",
                "identifier": "Url"
              }
            ]
          },
          {
            "entityType": "Process",
            "fieldMappings": [
              {
                "columnName": "InitiatingProcessCommandLine",
                "identifier": "CommandLine"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/DomainEntity_DeviceNetworkEvents_Updated.yaml",
        "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet DeviceNetworkEvents_ = DeviceNetworkEvents\n  | where isnotempty(RemoteUrl)\n  | where TimeGenerated >= ago(dt_lookBack)\n  | where ActionType !has \"ConnectionFailed\"\n  | extend Domain = tostring(parse_url(tolower(RemoteUrl)).Host)\n  | where isnotempty(Domain)\n  | project-rename DeviceNetworkEvents_TimeGenerated = TimeGenerated;\nlet DeviceNetworkEventDomains = DeviceNetworkEvents_\n  | distinct Domain\n  | summarize make_list(Domain);\nThreatIntelIndicators\n| extend IndicatorType = replace(@\"\\[|\\]|\\\"\"\", \"\", tostring(split(ObservableKey, \":\", 0)))\n| where IndicatorType == \"domain-name\"\n| extend DomainName = tolower(ObservableValue)\n| where TimeGenerated >= ago(ioc_lookBack)\n| extend IndicatorId = tostring(split(Id, \"--\")[2])\n| where DomainName in (DeviceNetworkEventDomains)\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| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)\n| where Description !contains_cs \"State: inactive;\" and Description !contains_cs \"State: falsepos;\"\n| project-reorder *, IsActive, Tags, TrafficLightProtocolLevel, DomainName, Type\n| join kind=innerunique (DeviceNetworkEvents_) on $left.DomainName == $right.Domain\n| where DeviceNetworkEvents_TimeGenerated < ValidUntil\n| summarize DeviceNetworkEvents_TimeGenerated = arg_max(DeviceNetworkEvents_TimeGenerated, *) by IndicatorId\n| project DeviceNetworkEvents_TimeGenerated, IndicatorId, Url = RemoteUrl, Confidence, Description, Tags, TrafficLightProtocolLevel, ActionType, DeviceId, DeviceName, InitiatingProcessAccountUpn, InitiatingProcessCommandLine, RemoteIP, RemotePort\n| extend Name = tostring(split(InitiatingProcessAccountUpn, '@', 0)[0]), UPNSuffix = tostring(split(InitiatingProcessAccountUpn, '@', 1)[0])\n| extend timestamp = DeviceNetworkEvents_TimeGenerated, UserPrincipalName = InitiatingProcessAccountUpn\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"
    }
  ]
}