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 SecurityAlert

Back
Id87890d78-3e05-43ec-9ab9-ba32f4e01250
RulenameTI map Domain entity to SecurityAlert
DescriptionIdentifies a match in SecurityAlert table from any Domain IOC from TI
SeverityMedium
TacticsCommandAndControl
TechniquesT1071
Required data connectorsAzureSecurityCenter
MicrosoftCloudAppSecurity
MicrosoftDefenderThreatIntelligence
ThreatIntelligence
ThreatIntelligenceTaxii
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/DomainEntity_SecurityAlert.yaml
Version1.4.3
Arm template87890d78-3e05-43ec-9ab9-ba32f4e01250.json
Deploy To Azure
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let SecurityAlerts = SecurityAlert
| where TimeGenerated > ago(dt_lookBack)
| extend domain = todynamic(dynamic_to_json(extract_all(@"(((xn--)?[a-z0-9\-]+\.)+([a-z]+|(xn--[a-z0-9]+)))", dynamic([1]), tolower(Entities))))
| where isnotempty(domain)
| mv-expand domain
| extend domain = tostring(domain)
| extend EntitiesDynamicArray = parse_json(Entities)
| mv-apply EntitiesDynamicArray on
    (summarize
        HostName = take_anyif(tostring(EntitiesDynamicArray.HostName), EntitiesDynamicArray.Type == "host"),
        IP_addr = take_anyif(tostring(EntitiesDynamicArray.Address), EntitiesDynamicArray.Type == "ip")
    )
| extend Alert_TimeGenerated = TimeGenerated
| extend Alert_Description = Description;
let AlertDomains = SecurityAlerts
| distinct domain
| summarize make_list(domain);
let Domain_Indicators = materialize(ThreatIntelligenceIndicator
| where isnotempty(DomainName)
| where TimeGenerated >= ago(ioc_lookBack)
| extend TI_DomainEntity = tolower(DomainName)
| where TI_DomainEntity in (AlertDomains)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true and ExpirationDateTime > now()
| where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;");
Domain_Indicators
// Using innerunique to keep performance fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
| join kind=innerunique (SecurityAlerts) on $left.TI_DomainEntity == $right.domain
| where Alert_TimeGenerated < ExpirationDateTime
| summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by IndicatorId, AlertName
| project Alert_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DomainName, AlertName, Alert_Description, ProviderName, AlertSeverity, ConfidenceLevel, HostName, IP_addr, Url, Entities, Type, TI_DomainEntity
| extend timestamp = Alert_TimeGenerated
relevantTechniques:
- T1071
name: TI map Domain entity to SecurityAlert
requiredDataConnectors:
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: ThreatIntelligence
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: ThreatIntelligenceTaxii
- dataTypes:
  - SecurityAlert
  connectorId: MicrosoftCloudAppSecurity
- dataTypes:
  - SecurityAlert
  connectorId: AzureSecurityCenter
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: MicrosoftDefenderThreatIntelligence
entityMappings:
- fieldMappings:
  - identifier: HostName
    columnName: HostName
  entityType: Host
- fieldMappings:
  - identifier: Address
    columnName: IP_addr
  entityType: IP
- fieldMappings:
  - identifier: Url
    columnName: Url
  entityType: URL
triggerThreshold: 0
id: 87890d78-3e05-43ec-9ab9-ba32f4e01250
tactics:
- CommandAndControl
version: 1.4.3
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/DomainEntity_SecurityAlert.yaml
queryPeriod: 14d
kind: Scheduled
queryFrequency: 1h
severity: Medium
description: |
    'Identifies a match in SecurityAlert table from any Domain IOC from TI'
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let SecurityAlerts = SecurityAlert
  | where TimeGenerated > ago(dt_lookBack)
  | extend domain = todynamic(dynamic_to_json(extract_all(@"(((xn--)?[a-z0-9\-]+\.)+([a-z]+|(xn--[a-z0-9]+)))", dynamic([1]), tolower(Entities))))
  | where isnotempty(domain)
  | mv-expand domain
  | extend domain = tostring(domain)
  | extend EntitiesDynamicArray = parse_json(Entities)
  | mv-apply EntitiesDynamicArray on
      (summarize
          HostName = take_anyif(tostring(EntitiesDynamicArray.HostName), EntitiesDynamicArray.Type == "host"),
          IP_addr = take_anyif(tostring(EntitiesDynamicArray.Address), EntitiesDynamicArray.Type == "ip")
      )
  | extend Alert_TimeGenerated = TimeGenerated
  | extend Alert_Description = Description;
  let AlertDomains = SecurityAlerts
  | distinct domain
  | summarize make_list(domain);
  let Domain_Indicators = materialize(ThreatIntelligenceIndicator
  | where isnotempty(DomainName)
  | where TimeGenerated >= ago(ioc_lookBack)
  | extend TI_DomainEntity = tolower(DomainName)
  | where TI_DomainEntity in (AlertDomains)
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
  | where Active == true and ExpirationDateTime > now()
  | where Description !contains_cs "State: inactive;" and Description !contains_cs "State: falsepos;");
  Domain_Indicators
  // Using innerunique to keep performance fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
  | join kind=innerunique (SecurityAlerts) on $left.TI_DomainEntity == $right.domain
  | where Alert_TimeGenerated < ExpirationDateTime
  | summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by IndicatorId, AlertName
  | project Alert_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DomainName, AlertName, Alert_Description, ProviderName, AlertSeverity, ConfidenceLevel, HostName, IP_addr, Url, Entities, Type, TI_DomainEntity
  | extend timestamp = Alert_TimeGenerated  
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/87890d78-3e05-43ec-9ab9-ba32f4e01250')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/87890d78-3e05-43ec-9ab9-ba32f4e01250')]",
      "properties": {
        "alertRuleTemplateName": "87890d78-3e05-43ec-9ab9-ba32f4e01250",
        "customDetails": null,
        "description": "'Identifies a match in SecurityAlert table from any Domain IOC from TI'\n",
        "displayName": "TI map Domain entity to SecurityAlert",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Host",
            "fieldMappings": [
              {
                "columnName": "HostName",
                "identifier": "HostName"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IP_addr",
                "identifier": "Address"
              }
            ]
          },
          {
            "entityType": "URL",
            "fieldMappings": [
              {
                "columnName": "Url",
                "identifier": "Url"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/DomainEntity_SecurityAlert.yaml",
        "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet SecurityAlerts = SecurityAlert\n| where TimeGenerated > ago(dt_lookBack)\n| extend domain = todynamic(dynamic_to_json(extract_all(@\"(((xn--)?[a-z0-9\\-]+\\.)+([a-z]+|(xn--[a-z0-9]+)))\", dynamic([1]), tolower(Entities))))\n| where isnotempty(domain)\n| mv-expand domain\n| extend domain = tostring(domain)\n| extend EntitiesDynamicArray = parse_json(Entities)\n| mv-apply EntitiesDynamicArray on\n    (summarize\n        HostName = take_anyif(tostring(EntitiesDynamicArray.HostName), EntitiesDynamicArray.Type == \"host\"),\n        IP_addr = take_anyif(tostring(EntitiesDynamicArray.Address), EntitiesDynamicArray.Type == \"ip\")\n    )\n| extend Alert_TimeGenerated = TimeGenerated\n| extend Alert_Description = Description;\nlet AlertDomains = SecurityAlerts\n| distinct domain\n| summarize make_list(domain);\nlet Domain_Indicators = materialize(ThreatIntelligenceIndicator\n| where isnotempty(DomainName)\n| where TimeGenerated >= ago(ioc_lookBack)\n| extend TI_DomainEntity = tolower(DomainName)\n| where TI_DomainEntity in (AlertDomains)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true and ExpirationDateTime > now()\n| where Description !contains_cs \"State: inactive;\" and Description !contains_cs \"State: falsepos;\");\nDomain_Indicators\n// Using innerunique to keep performance fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (SecurityAlerts) on $left.TI_DomainEntity == $right.domain\n| where Alert_TimeGenerated < ExpirationDateTime\n| summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by IndicatorId, AlertName\n| project Alert_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DomainName, AlertName, Alert_Description, ProviderName, AlertSeverity, ConfidenceLevel, HostName, IP_addr, Url, Entities, Type, TI_DomainEntity\n| extend timestamp = Alert_TimeGenerated\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1071"
        ],
        "templateVersion": "1.4.3",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}