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
Iddf88b403-1cb9-49ea-a43d-b6613051cf7f
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 (NEW)/Analytic Rules/DomainEntity_SecurityAlert.yaml
Version1.4.5
Arm templatedf88b403-1cb9-49ea-a43d-b6613051cf7f.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(ThreatIntelIndicators
| extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
| where IndicatorType == "domain-name"
| extend DomainName = tolower(ObservableValue)
| where TimeGenerated >= ago(ioc_lookBack)
| where DomainName in (AlertDomains)
| 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;");
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.DomainName == $right.domain
| where Alert_TimeGenerated < ValidUntil
| summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by Id, AlertName
| extend ActivityGroupNames = extract("ActivityGroup:([^,]+)", 1, tostring(parse_json(Data).labels))
| extend Url = DomainName
| project Alert_TimeGenerated, Description, ActivityGroupNames, Id, ValidUntil, ConfidenceScore, DomainName, AlertName, Alert_Description, ProviderName, AlertSeverity, ConfidenceLevel, HostName, IP_addr, Url, Entities, Type
| extend timestamp = Alert_TimeGenerated
| project-reorder *, ConfidenceScore, DomainName, AlertName, Alert_TimeGenerated, ProviderName, AlertSeverity, Entities, Type, timestamp
description: |
    'Identifies a match in SecurityAlert table from any Domain IOC from TI'
triggerThreshold: 0
queryPeriod: 14d
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(ThreatIntelIndicators
  | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
  | where IndicatorType == "domain-name"
  | extend DomainName = tolower(ObservableValue)
  | where TimeGenerated >= ago(ioc_lookBack)
  | where DomainName in (AlertDomains)
  | 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;");
  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.DomainName == $right.domain
  | where Alert_TimeGenerated < ValidUntil
  | summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by Id, AlertName
  | extend ActivityGroupNames = extract("ActivityGroup:([^,]+)", 1, tostring(parse_json(Data).labels))
  | extend Url = DomainName
  | project Alert_TimeGenerated, Description, ActivityGroupNames, Id, ValidUntil, ConfidenceScore, DomainName, AlertName, Alert_Description, ProviderName, AlertSeverity, ConfidenceLevel, HostName, IP_addr, Url, Entities, Type
  | extend timestamp = Alert_TimeGenerated
  | project-reorder *, ConfidenceScore, DomainName, AlertName, Alert_TimeGenerated, ProviderName, AlertSeverity, Entities, Type, timestamp  
kind: Scheduled
relevantTechniques:
- T1071
queryFrequency: 1h
requiredDataConnectors:
- connectorId: ThreatIntelligence
  dataTypes:
  - ThreatIntelIndicators
- connectorId: ThreatIntelligenceTaxii
  dataTypes:
  - ThreatIntelIndicators
- connectorId: MicrosoftCloudAppSecurity
  dataTypes:
  - SecurityAlert
- connectorId: AzureSecurityCenter
  dataTypes:
  - SecurityAlert
- connectorId: MicrosoftDefenderThreatIntelligence
  dataTypes:
  - ThreatIntelIndicators
name: TI map Domain entity to SecurityAlert
severity: Medium
entityMappings:
- fieldMappings:
  - identifier: HostName
    columnName: HostName
  entityType: Host
- fieldMappings:
  - identifier: Address
    columnName: IP_addr
  entityType: IP
- fieldMappings:
  - identifier: Url
    columnName: Url
  entityType: URL
version: 1.4.5
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence (NEW)/Analytic Rules/DomainEntity_SecurityAlert.yaml
id: df88b403-1cb9-49ea-a43d-b6613051cf7f
tactics:
- CommandAndControl
triggerOperator: gt