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

TI Map URL Entity to EmailUrlInfo

Back
Ida0038239-72f4-4f7b-90ff-37f89f7881e0
RulenameTI Map URL Entity to EmailUrlInfo
DescriptionThis query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in EmailUrlInfo.
SeverityMedium
TacticsImpact
Required data connectorsAzureActiveDirectory
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/URLEntity_EmailUrlInfo.yaml
Version1.0.1
Arm templatea0038239-72f4-4f7b-90ff-37f89f7881e0.json
Deploy To Azure
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let EmailUrlInfo_ = materialize(EmailUrlInfo
    | where isnotempty(Url)
    | where TimeGenerated >= ago(dt_lookBack)
    | extend Url = tolower(Url)
    | extend EmailUrlInfo_TimeGenerated = TimeGenerated);
let EmailUrls = EmailUrlInfo_ | distinct Url | summarize make_list(Url);
let EmailUrlDomains = EmailUrlInfo_ | distinct UrlDomain | summarize make_list(UrlDomain);
let EmailEvents_ = materialize(EmailEvents
    | where TimeGenerated >= ago(dt_lookBack));
let TI = materialize(ThreatIntelligenceIndicator
    | where TimeGenerated >= ago(ioc_lookBack)
    | where (isnotempty(Url) or isnotempty(DomainName)) 
    | where tolower(Url) in (EmailUrls) or tolower(DomainName) in (EmailUrlDomains)
    | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
    | where Active == true and ExpirationDateTime > now());
(union
    (TI | join kind=innerunique (EmailUrlInfo_) on Url),
    (TI | join kind=innerunique (EmailUrlInfo_) on $left.DomainName == $right.UrlDomain))
| where EmailUrlInfo_TimeGenerated < ExpirationDateTime
| summarize EmailUrlInfo_TimeGenerated = arg_max(EmailUrlInfo_TimeGenerated, *) by IndicatorId, Url
| project EmailUrlInfo_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Url, UrlDomain, UrlLocation, NetworkMessageId
| extend timestamp = EmailUrlInfo_TimeGenerated
| join kind=inner (EmailEvents_) on NetworkMessageId
| where DeliveryAction !has "Blocked"
| extend Name = tostring(split(RecipientEmailAddress, '@', 0)[0]), UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0])
triggerOperator: gt
queryFrequency: 1h
description: |
    'This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in EmailUrlInfo.'
version: 1.0.1
kind: Scheduled
triggerThreshold: 0
requiredDataConnectors:
- connectorId: AzureActiveDirectory
  dataTypes:
  - EmailUrlInfo
- connectorId: ThreatIntelligence
  dataTypes:
  - ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
  dataTypes:
  - ThreatIntelligenceIndicator
- connectorId: MicrosoftDefenderThreatIntelligence
  dataTypes:
  - ThreatIntelligenceIndicator
queryPeriod: 14d
name: TI Map URL Entity to EmailUrlInfo
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/URLEntity_EmailUrlInfo.yaml
id: a0038239-72f4-4f7b-90ff-37f89f7881e0
tactics:
- Impact
severity: Medium
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: RecipientEmailAddress
  - identifier: Name
    columnName: Name
  - identifier: UPNSuffix
    columnName: UPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Url
    columnName: Url
  entityType: URL
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let EmailUrlInfo_ = materialize(EmailUrlInfo
      | where isnotempty(Url)
      | where TimeGenerated >= ago(dt_lookBack)
      | extend Url = tolower(Url)
      | extend EmailUrlInfo_TimeGenerated = TimeGenerated);
  let EmailUrls = EmailUrlInfo_ | distinct Url | summarize make_list(Url);
  let EmailUrlDomains = EmailUrlInfo_ | distinct UrlDomain | summarize make_list(UrlDomain);
  let EmailEvents_ = materialize(EmailEvents
      | where TimeGenerated >= ago(dt_lookBack));
  let TI = materialize(ThreatIntelligenceIndicator
      | where TimeGenerated >= ago(ioc_lookBack)
      | where (isnotempty(Url) or isnotempty(DomainName)) 
      | where tolower(Url) in (EmailUrls) or tolower(DomainName) in (EmailUrlDomains)
      | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
      | where Active == true and ExpirationDateTime > now());
  (union
      (TI | join kind=innerunique (EmailUrlInfo_) on Url),
      (TI | join kind=innerunique (EmailUrlInfo_) on $left.DomainName == $right.UrlDomain))
  | where EmailUrlInfo_TimeGenerated < ExpirationDateTime
  | summarize EmailUrlInfo_TimeGenerated = arg_max(EmailUrlInfo_TimeGenerated, *) by IndicatorId, Url
  | project EmailUrlInfo_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Url, UrlDomain, UrlLocation, NetworkMessageId
  | extend timestamp = EmailUrlInfo_TimeGenerated
  | join kind=inner (EmailEvents_) on NetworkMessageId
  | where DeliveryAction !has "Blocked"
  | extend Name = tostring(split(RecipientEmailAddress, '@', 0)[0]), UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0])  
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/a0038239-72f4-4f7b-90ff-37f89f7881e0')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/a0038239-72f4-4f7b-90ff-37f89f7881e0')]",
      "properties": {
        "alertRuleTemplateName": "a0038239-72f4-4f7b-90ff-37f89f7881e0",
        "customDetails": null,
        "description": "'This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in EmailUrlInfo.'\n",
        "displayName": "TI Map URL Entity to EmailUrlInfo",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "RecipientEmailAddress",
                "identifier": "FullName"
              },
              {
                "columnName": "Name",
                "identifier": "Name"
              },
              {
                "columnName": "UPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "URL",
            "fieldMappings": [
              {
                "columnName": "Url",
                "identifier": "Url"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/URLEntity_EmailUrlInfo.yaml",
        "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet EmailUrlInfo_ = materialize(EmailUrlInfo\n    | where isnotempty(Url)\n    | where TimeGenerated >= ago(dt_lookBack)\n    | extend Url = tolower(Url)\n    | extend EmailUrlInfo_TimeGenerated = TimeGenerated);\nlet EmailUrls = EmailUrlInfo_ | distinct Url | summarize make_list(Url);\nlet EmailUrlDomains = EmailUrlInfo_ | distinct UrlDomain | summarize make_list(UrlDomain);\nlet EmailEvents_ = materialize(EmailEvents\n    | where TimeGenerated >= ago(dt_lookBack));\nlet TI = materialize(ThreatIntelligenceIndicator\n    | where TimeGenerated >= ago(ioc_lookBack)\n    | where (isnotempty(Url) or isnotempty(DomainName)) \n    | where tolower(Url) in (EmailUrls) or tolower(DomainName) in (EmailUrlDomains)\n    | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n    | where Active == true and ExpirationDateTime > now());\n(union\n    (TI | join kind=innerunique (EmailUrlInfo_) on Url),\n    (TI | join kind=innerunique (EmailUrlInfo_) on $left.DomainName == $right.UrlDomain))\n| where EmailUrlInfo_TimeGenerated < ExpirationDateTime\n| summarize EmailUrlInfo_TimeGenerated = arg_max(EmailUrlInfo_TimeGenerated, *) by IndicatorId, Url\n| project EmailUrlInfo_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Url, UrlDomain, UrlLocation, NetworkMessageId\n| extend timestamp = EmailUrlInfo_TimeGenerated\n| join kind=inner (EmailEvents_) on NetworkMessageId\n| where DeliveryAction !has \"Blocked\"\n| extend Name = tostring(split(RecipientEmailAddress, '@', 0)[0]), UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0])\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Impact"
        ],
        "templateVersion": "1.0.1",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}