Detection rules › Kusto

Kusto rules: 10

AD FS Abnormal EKU object identifier attribute

#
Severity
high
Time window
1d
Group by
OID
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

This detection uses Security events from the "AD FS Auditing" provider to detect suspicious object identifiers (OIDs) as part EventID 501 and specifically part of the Enhanced Key Usage attributes. This query checks to see if you have any new OIDs in the last hour that have not been seen in the previous day. New OIDs should be validated and OIDs that are very long, as indicated by the OID_Length field, could also be an indicator of malicious activity. In order to use this query you need to enable AD FS auditing on the AD FS Server. References: https://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/ https://docs.microsoft.com/windows-server/identity/ad-fs/troubleshooting/ad-fs-tshoot-logging

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

Telemetry Coverage

ProviderRecord / event type
AD-FS-AuditingEvent ID 501

Rule Body

id: cfc1ae62-db63-4a3e-b88b-dc04030c2257
name: AD FS Abnormal EKU object identifier attribute
description: |
  'This detection uses Security events from the "AD FS Auditing" provider to detect suspicious object identifiers (OIDs) as part EventID 501 and specifically part of the Enhanced Key Usage attributes.
  This query checks to see if you have any new OIDs in the last hour that have not been seen in the previous day. New OIDs should be validated and OIDs that are very long, as indicated
  by the OID_Length field, could also be an indicator of malicious activity.
  In order to use this query you need to enable AD FS auditing on the AD FS Server.
  References:
  https://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/
  https://docs.microsoft.com/windows-server/identity/ad-fs/troubleshooting/ad-fs-tshoot-logging
  '
severity: High
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CredentialAccess
relevantTechniques:
  - T1552
tags:
  - Nobelium
  - MagicWeb
query: |
  // change the starttime value for a longer period of known OIDs
  let starttime = 1d;
  // change the lookback value for a longer period of lookback for suspicious/abnormal
  let lookback = 1h;
  let OIDList = SecurityEvent
  | where TimeGenerated >= ago(starttime)
  | where EventSourceName == 'AD FS Auditing'
  | where EventID == 501
  | where EventData has '/eku'
  | extend OIDs = extract_all(@"<Data>([\d+\.]+)</Data>", EventData)
  | mv-expand OIDs
  | extend OID = tostring(OIDs)
  | extend OID_Length = strlen(OID)
  | project TimeGenerated, Computer, EventSourceName, EventID, OID, OID_Length, EventData
  ;
  OIDList
  | where TimeGenerated >= ago(lookback)
  | join kind=leftanti (
  OIDList
  | where TimeGenerated between (ago(starttime) .. ago(lookback))
  | summarize by OID
  ) on OID
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
version: 1.0.4
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others", "Identity" ]

Stages and Predicates

Parameters

let starttime = 1d;
let lookback = 1h;

let OIDList is inlined into the numbered stages below.

Stages 1 to 11 define let OIDList as the rule's main pipeline source. Stages 12 to 16 use it.

Stage 1: source

let OIDList

Stage 2: source

SecurityEvent

Stage 3: where

| where TimeGenerated >= ago(starttime)

Stage 4: where

| where EventSourceName == 'AD FS Auditing'

Stage 5: where

| where EventID == 501

Stage 6: where

| where EventData has '/eku'

Stage 7: extend

| extend OIDs = extract_all(@"<Data>([\d+\.]+)</Data>", EventData)

Stage 8: mv-expand

| mv-expand OIDs

Stage 9: extend

| extend OID = tostring(OIDs)

Stage 10: extend

| extend OID_Length = strlen(OID)

Stage 11: project

| project TimeGenerated, Computer, EventSourceName, EventID, OID, OID_Length, EventData

Stage 12: where

OIDList
| where TimeGenerated >= ago(lookback)

Stage 13: join (negated)

join kind=leftanti (OIDList) on OID

Stage 14: extend

extend DomainIndex, HostName

Stage 15: extend

extend HostNameDomain
HostNameDomain =
ifDomainIndex != -1substring(Computer, (DomainIndex + 1))
elseComputer

Stage 16: summarize aggregation inside the join branch

summarize by OID

Indicators

These rows show field, operator, and value matches.

Exclusions

The rule actively suppresses these predicates.

Output Fields

These fields are emitted when the rule matches.

FieldSource
OIDsummarize

Azure secure score role overlap

#
Status
available
Severity
medium
Time window
6h
Source
github.com/Azure/Azure-Sentinel

'This query searches for accounts that have been assigned Global Administrator do not need other roles assigned. Global Administrators have access to all aspects of Azure'

MITRE ATT&CK Coverage

TacticTechniques
Impact

Rule Body

id: 8E6D9A66-F1B0-463D-BA90-11A5AEC0E15A
name: Azure secure score role overlap
description: |
  'This query searches for accounts that have been assigned Global Administrator do not need other roles assigned. 
    Global Administrators have access to all aspects of Azure'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: SenservaPro
    dataTypes:
      - SenservaPro_CL
queryFrequency: 6h
queryPeriod: 6h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Impact
relevantTechniques:
  - T1529
query: |
  SenservaPro_CL
  | where ControlName_s == 'AzureSecureScoreRoleOverlap'
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: ControlName_s
      - identifier: AadTenantId
        columnName: TenantId
      - identifier: DisplayName
        columnName: TenantDisplayName_s 
  - entityType: SecurityGroup
    fieldMappings:
      - identifier: DistinguishedName
        columnName: Group_s
  - entityType: AzureResource
    fieldMappings:
      - identifier: ResourceId
        columnName: SourceSystem 
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

SenservaPro_CL

Stage 2: where

| where ControlName_s == 'AzureSecureScoreRoleOverlap'

Indicators

These rows show field, operator, and value matches.

BloodHound Attack Path Finding - User Access Admin Role on Tier Zero Resource

#

This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.

Status
available
Severity
medium
Time window
1h
Source
github.com/Azure/Azure-Sentinel

BloodHound Attack Path Finding - User Access Admin Role on Tier Zero Resource

Rule Body

id: ccd94d43-3d74-4928-93bf-eb9bfe7924ca
name: BloodHound Attack Path Finding - User Access Admin Role on Tier Zero Resource
description: BloodHound Attack Path Finding - User Access Admin Role on Tier Zero
  Resource
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: BloodHoundEnterprise
    dataTypes:
      - BHEAttackPathsData_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics: []
relevantTechniques: []
query: BHEAttackPathsData_CL | where Finding == "AzureT0UserAccessAdministrator"
entityMappings:
  - entityType: URL
    fieldMappings:
      - identifier: Url
        columnName: domain_name
customDetails:
  Description: ShortDescription
  Remediation: ShortRemediation
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

BHEAttackPathsData_CL

Stage 2: where

| where Finding == "AzureT0UserAccessAdministrator"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Findingeq
  • AzureT0UserAccessAdministrator
field:"Finding" kind:eq value:"AzureT0UserAccessAdministrator"

Cisco Umbrella - Request Allowed to harmful/malicious URI category

#
Severity
medium
Time window
10m
Source
github.com/Azure/Azure-Sentinel

'It is reccomended that these Categories shoud be blocked by policies because they provide harmful/malicious content..'

MITRE ATT&CK Coverage

TacticTechniques
Initial AccessNo specific technique
Command & ControlNo specific technique

Rule Body

id: d6bf1931-b1eb-448d-90b2-de118559c7ce
name: Cisco Umbrella - Request Allowed to harmful/malicious URI category
description: |
  'It is reccomended that these Categories shoud be blocked by policies because they provide harmful/malicious content..'
severity: Medium
requiredDataConnectors:
  - connectorId: CiscoUmbrellaDataConnector
    dataTypes:
      - Cisco_Umbrella_proxy_CL
queryFrequency: 10m
queryPeriod: 10m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CommandAndControl
  - InitialAccess
query: |
  let lbtime = 10m;
  Cisco_Umbrella
  | where TimeGenerated > ago(lbtime)
  | where EventType == 'proxylogs'
  | where DvcAction =~ 'Allowed'
  | where UrlCategory contains 'Adult Themes' or
        UrlCategory contains 'Adware' or
        UrlCategory contains 'Alcohol' or
        UrlCategory contains 'Illegal Downloads' or
        UrlCategory contains 'Drugs' or
        UrlCategory contains 'Child Abuse Content' or
        UrlCategory contains 'Hate/Discrimination' or
        UrlCategory contains 'Nudity' or
        UrlCategory contains 'Pornography' or
        UrlCategory contains 'Proxy/Anonymizer' or
        UrlCategory contains 'Sexuality' or
        UrlCategory contains 'Tasteless' or
        UrlCategory contains 'Terrorism' or
        UrlCategory contains 'Web Spam' or
        UrlCategory contains 'German Youth Protection' or
        UrlCategory contains 'Illegal Activities' or
        UrlCategory contains 'Lingerie/Bikini' or
        UrlCategory contains 'Weapons'
  | project TimeGenerated, SrcIpAddr, Identities
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Identities
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SrcIpAddr
version: 1.1.1
kind: Scheduled

Stages and Predicates

Parameters

let lbtime = 10m;

Stage 1: source

Cisco_Umbrella

Stage 2: where

| where TimeGenerated > ago(lbtime)

Stage 3: where

| where EventType == 'proxylogs'

Stage 4: where

| where DvcAction =~ 'Allowed'

Stage 5: where

| where UrlCategory contains 'Adult Themes' or
      UrlCategory contains 'Adware' or
      UrlCategory contains 'Alcohol' or
      UrlCategory contains 'Illegal Downloads' or
      UrlCategory contains 'Drugs' or
      UrlCategory contains 'Child Abuse Content' or
      UrlCategory contains 'Hate/Discrimination' or
      UrlCategory contains 'Nudity' or
      UrlCategory contains 'Pornography' or
      UrlCategory contains 'Proxy/Anonymizer' or
      UrlCategory contains 'Sexuality' or
      UrlCategory contains 'Tasteless' or
      UrlCategory contains 'Terrorism' or
      UrlCategory contains 'Web Spam' or
      UrlCategory contains 'German Youth Protection' or
      UrlCategory contains 'Illegal Activities' or
      UrlCategory contains 'Lingerie/Bikini' or
      UrlCategory contains 'Weapons'

Stage 6: project

| project TimeGenerated, SrcIpAddr, Identities

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
DvcActioneq
  • Allowed
field:"DvcAction" kind:eq value:"Allowed"
EventTypeeq
  • proxylogs
field:"EventType" kind:eq value:"proxylogs"
UrlCategorycontains
  • Adult Themes
  • Adware
  • Alcohol
  • Child Abuse Content
  • Drugs
  • German Youth Protection
  • Hate/Discrimination
  • Illegal Activities
  • Illegal Downloads
  • Lingerie/Bikini
  • Nudity
  • Pornography
  • Proxy/Anonymizer
  • Sexuality
  • Tasteless
  • Terrorism
  • Weapons
  • Web Spam
field:"UrlCategory" kind:contains

Output Fields

These fields are emitted when the rule matches.

FieldSource
Identitiesproject
SrcIpAddrproject
TimeGeneratedproject

Cisco WSA - Multiple infected files

#
Status
available
Severity
high
Time window
15m
Group by
SrcIpAddr, SrcUserName
Source
github.com/Azure/Azure-Sentinel

'Detects multiple infected files on same source.'

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

id: 93186e3d-5dc2-4a00-a993-fa1448db8734
name: Cisco WSA - Multiple infected files
description: |
  'Detects multiple infected files on same source.'
severity: High
status: Available
requiredDataConnectors:
  - connectorId: SyslogAma
    datatypes:
      - Syslog
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
relevantTechniques:
  - T1189
query: |
  CiscoWSAEvent
  | where isnotempty(AmpFileName)
  | where isnotempty(ThreatName)
  | summarize count() by SrcIpAddr, SrcUserName, bin(TimeGenerated, 15m)
  | where count_ > 1
  | extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = SrcUserName
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPCustomEntity
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: AccountCustomEntity
version: 1.0.3
kind: Scheduled

Stages and Predicates

Stage 1: source

CiscoWSAEvent

Stage 2: where

| where isnotempty(AmpFileName)

Stage 3: where

| where isnotempty(ThreatName)

Stage 4: summarize

| summarize count() by SrcIpAddr, SrcUserName, bin(TimeGenerated, 15m)

Stage 5: where

| where count_ > 1

Stage 6: extend

| extend IPCustomEntity = SrcIpAddr, AccountCustomEntity = SrcUserName

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
AmpFileNameis_not_null
  • (no value, null check)
field:"AmpFileName" kind:is_not_null
ThreatNameis_not_null
  • (no value, null check)
field:"ThreatName" kind:is_not_null
count_gt
  • 1 transforms: number
field:"count_" kind:gt value:"1"

Output Fields

These fields are emitted when the rule matches.

FieldSource
SrcIpAddrsummarize
SrcUserNamesummarize
AccountCustomEntityextend
IPCustomEntityextend

Cyble Vision Alerts Hacktivism

#

This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.

Status
available
Severity
low
Time window
30m
Source
github.com/Azure/Azure-Sentinel

'Detects hacktivist activity (Telegram posts, defacements, site takedowns, etc.) using the Alerts_Hacktivism parser. Extracts post content, attacker/team,domains, links, IPs, media and metadata for triage.'

MITRE ATT&CK Coverage

Rule Body

id: 6649e5a0-0365-452f-84b3-448a0aec7a59
name: Cyble Vision Alerts Hacktivism
description: |
  'Detects hacktivist activity (Telegram posts, defacements, site takedowns, etc.) using the Alerts_Hacktivism parser. Extracts post content, attacker/team,domains, links, IPs, media and metadata for triage.'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: CybleVisionAlerts
  dataTypes:
  - CybleVisionAlerts_CL
enabled: true
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: GreaterThan
triggerThreshold: 0
suppressionDuration: PT5H
eventGroupingSettings:
  aggregationKind: AlertPerResult
tactics:
- Reconnaissance
- Impact
- ResourceDevelopment
relevantTechniques:
- T1595
- T1491
- T1498
- T1585
subTechniques: []
query: |
  Alerts_hacktivism 
  | where Service contains "hacktivism" 
  | extend Mappedseverity = Severity
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: false
    reopenClosedIncident: false
    lookbackDuration: PT5H
    matchingMethod: AllEntities
alertDetailsOverride:
  alertDisplayNameFormat: CybleVision Hacktivism {{HK_ChannelName}} / {{HK_AttackerTeam}}
  alertDescriptionFormat: |
    Hacktivism activity detected. Attacker/Team {{HK_AttackerTeam}} Post excerpt {{HK_PostData}} Domains/Links {{HK_All_Domains}}
  alertDynamicProperties: []
customDetails:
  MappedSeverity: Severity
  Status: Status
  AlertID: AlertID
  Service: Service
  ChannelName: HK_ChannelName
  ChannelLink: HK_ChannelLink
  Source: HK_SourceWebsite
  PostID: HK_PostID
  PostText: HK_PostData
  PostedAt: HK_PostedAt
  Phones: HK_Phones
  Emails: HK_Emails
  Attacker: HK_Attacker
  TargetDomain: HK_Domain
  Server: HK_Server
  SourceWebsite: HK_SourceWebsite
  WebsiteURL: HK_WebsiteURL
  Tags: HK_Tags
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: HK_AttackerTeam
- entityType: URL
  fieldMappings:
  - identifier: Url
    columnName: HK_All_URLs
- entityType: DNS
  fieldMappings:
  - identifier: DomainName
    columnName: HK_All_Domains
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: HK_IP
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

Alerts_hacktivism

Stage 2: where

| where Service contains "hacktivism"

Stage 3: extend

| extend Mappedseverity = Severity

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Servicecontains
  • hacktivism
field:"Service" kind:contains value:"hacktivism"

Output Fields

These fields are emitted when the rule matches.

FieldSource
Mappedseverityextend

Cyble Vision Alerts Website Defacement Keyword

#

This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.

Status
available
Severity
low
Time window
30m
Source
github.com/Azure/Azure-Sentinel

'Triggers when monitored defacement keywords appear on a website, indicating potential early signs of website compromise or defacement-related activity.'

MITRE ATT&CK Coverage

TacticTechniques
Reconnaissance
Impact

Rule Body

id: 754dbb50-8dc2-4b8b-86d8-a890a020ddc3
name: Cyble Vision Alerts Website Defacement Keyword
description: |
  'Triggers when monitored defacement keywords appear on a website, indicating potential early signs of website compromise or defacement-related activity.'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: CybleVisionAlerts
  dataTypes:
  - CybleVisionAlerts_CL
enabled: true
queryfrequency: 30m
queryPeriod: 30m
triggerOperator: GreaterThan
triggerThreshold: 0
eventGroupingSettings:
  aggregationKind: AlertPerResult
tactics:
- Impact
- Reconnaissance
relevantTechniques:
- T1491
- T1598
query: |
  Alerts_defacement_keyword  
  | where Service == "defacement_keyword" 
  | extend MappedSeverity = Severity
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: false
    reopenClosedIncident: false
    lookbackDuration: PT5H
    matchingMethod: AllEntities
  alertDetailsOverride:
  alertDisplayNameFormat: Defacement Keyword Detected {{DK_Keyword}} on {{DK_DomainName}}
  alertDescriptionFormat: |
    A defacement-related keyword was observed on the website. URL {{DK_URL}}. Frequency count {{DK_Frequency}}. This may indicate early-stage defacement activity.
customDetails:
  MappedSeverity: Severity
  Status: Status
  AlertID: AlertID
  Service: Service
  DK_URL: DK_URL
  DK_DomainName: DK_DomainName
  DK_Keyword: DK_Keyword
  DK_Frequency: DK_Frequency
  DK_RecordID: DK_RecordID
entityMappings:
- entityType: Url
  fieldMappings:
  - identifier: Url
    columnName: DK_URL
- entityType: Host
  fieldMappings:
  - identifier: HostName
    columnName: DK_DomainName
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

Alerts_defacement_keyword

Stage 2: where

| where Service == "defacement_keyword"

Stage 3: extend

| extend MappedSeverity = Severity

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Serviceeq
  • defacement_keyword
field:"Service" kind:eq value:"defacement_keyword"

Output Fields

These fields are emitted when the rule matches.

FieldSource
MappedSeverityextend

Empty group with entitlements

#

This is a third-party alert feed, not a detection over modeled telemetry. The vendor product raised the finding; this rule forwards it into the SIEM. It is searchable for reference but is excluded from the detection-rule browse and the ATT&CK coverage matrix.

Status
available
Severity
informational
Time window
30m
Source
github.com/Azure/Azure-Sentinel

The rule detects empty groups with entitlements.

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Privilege Escalation

Rule Body

id: c4d442a8-8227-4735-ac13-d84704e1b371
name: Empty group with entitlements
kind: Scheduled
description: The rule detects empty groups with entitlements.
severity: Informational
status: Available
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - PrivilegeEscalation
  - Persistence
relevantTechniques:
  - T1098
query: |-
  Authomize_v2_CL
  | where ingestion_time() >= ago(30m)
  | extend EventID = id_s, Policy = policy_name_s, Severity = severity_s,Description = description_s,Recommendation = recommendation_s,URL = url_s,Tactics = tactics_s
  | where Policy has "Empty group with entitlements"
  | project  EventID, Policy, Severity, Description, Recommendation, URL, Category, Tactics
entityMappings:
  - entityType: URL
    fieldMappings:
      - identifier: Url
        columnName: URL
requiredDataConnectors:
- connectorId: Authomize
  dataTypes: [ "Authomize_v2_CL" ]
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: 5h
    matchingMethod: AnyAlert
    groupByEntities: []
    groupByAlertDetails: []
    groupByCustomDetails: []
eventGroupingSettings:
  aggregationKind: SingleAlert
alertDetailsOverride:
  alertnameFormat: Alert from Authomize - Empty group with entitlements
  alertDescriptionFormat: Empty group with entitlements. The policy detects empty groups with entitlements
  alertSeverity: Severity
  alertTactics: Tactics 
  alertDynamicProperties:
  - alertProperty: AlertLink
    value: URL
customDetails:
  AuthomizeEventID: EventID
  EventName: Policy
  EventDescription: Description
  EventRecommendation: Recommendation
  ReferencedURL: URL
suppressionDuration: 5h
suppressionEnabled: false
version: 1.0.3

Stages and Predicates

Stage 1: source

Authomize_v2_CL

Stage 2: where

| where ingestion_time() >= ago(30m)

Stage 3: extend

| extend EventID = id_s, Policy = policy_name_s, Severity = severity_s,Description = description_s,Recommendation = recommendation_s,URL = url_s,Tactics = tactics_s

Stage 4: where

| where Policy has "Empty group with entitlements"

Stage 5: project

| project  EventID, Policy, Severity, Description, Recommendation, URL, Category, Tactics

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Policymatch
  • Empty group with entitlements transforms: term
field:"policy_name_s" kind:match value:"Empty group with entitlements"

Output Fields

These fields are emitted when the rule matches.

FieldSource
Categoryproject
Descriptionproject
EventIDproject
Policyproject
Recommendationproject
Severityproject
Tacticsproject
URLproject

KMS Key Rotation Job Finished

#
Status
available
Severity
informational
Time window
1d
Source
github.com/Azure/Azure-Sentinel

Detects when a KMS key rotation job is finished.

Rule Body

id: f11f245e-f77e-4dc5-95f1-ce602c2a36ba
name: KMS Key Rotation Job Finished
description: Detects when a KMS key rotation job is finished.
severity: Informational
status: Available
requiredDataConnectors:
- connectorId: Syslog
  dataTypes:
  - Syslog
- connectorId: SyslogAma
  dataTypes:
  - Syslog
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
  aggregationKind: AlertPerResult
tactics: []
relevantTechniques: []
query: "Veeam_GetSecurityEvents\n| where instanceId == 42500\n| extend ResultMessage\
  \ = extract(\"ResultMessage=\\\"([^\\\"]*)\\\"\", 1, SyslogMessage)\n| project\n\
  \    Date = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),\n    DataSource\
  \ = original_host,\n    EventId = instanceId,\n    UserName = user,\n    [\"StateMessage\"\
  ] = ResultMessage,\n    MessageDetails = Description,\n    Severity = SeverityDescription"
version: 1.0.1
kind: Scheduled
customDetails:
  Date: Date
  VbrHostName: DataSource
  EventId: EventId
  MessageDetails: MessageDetails
  Severity: Severity

Stages and Predicates

Stage 1: source

Veeam_GetSecurityEvents

Stage 2: where

| where instanceId == 42500

Stage 3: extend

| extend ResultMessage = extract("ResultMessage=\"([^\"]*)\"", 1, SyslogMessage)

Stage 4: project

| project
    Date = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),
    DataSource = original_host,
    EventId = instanceId,
    UserName = user,
    ["StateMessage"] = ResultMessage,
    MessageDetails = Description,
    Severity = SeverityDescription

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
DataSourceproject
Dateproject
EventIdproject
MessageDetailsproject
Severityproject
StateMessageproject
UserNameproject

NRT PIM Elevation Request Rejected

#
Status
available
Severity
high
Source
github.com/Azure/Azure-Sentinel

Identifies when a user is rejected for a privileged role elevation via PIM. Monitor rejections for indicators of attacker compromise of the requesting account. Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-privileged-identity-management

MITRE ATT&CK Coverage

TacticTechniques
Persistence

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

id: 5db427b2-f406-4274-b413-e9fcb29412f8
name: NRT PIM Elevation Request Rejected
description: |
  'Identifies when a user is rejected for a privileged role elevation via PIM. Monitor rejections for indicators of attacker compromise of the requesting account.
  Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-privileged-identity-management'
severity: High
status: Available
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AuditLogs
tactics:
  - Persistence
relevantTechniques:
  - T1078.004
tags:
  - AADSecOpsGuide
query: |
  AuditLogs
  | where ActivityDisplayName =~ 'Add member to role request denied (PIM activation)'
  | mv-apply ResourceItem = TargetResources on 
    (
        where ResourceItem.type =~ "Role"
        | extend Role = trim(@'"',tostring(ResourceItem.displayName))
    )
  | mv-apply ResourceItem = TargetResources on 
    (
        where ResourceItem.type =~ "User"
        | extend TargetUserPrincipalName = trim(@'"',tostring(ResourceItem.userPrincipalName))
    )
  | where ResultReason != "RoleAssignmentExists"
  | where isnotempty(InitiatedBy.user)
  | extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
  | extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
  | extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
  | extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
  | extend InitiatingIpAddress = tostring(iff(isnotempty(InitiatedBy.user.ipAddress), InitiatedBy.user.ipAddress, InitiatedBy.app.ipAddress))
  | extend TargetName = tostring(split(TargetUserPrincipalName,'@',0)[0]), TargetUPNSuffix = tostring(split(TargetUserPrincipalName,'@',1)[0])
  | extend InitiatedByName = tostring(split(InitiatingUserPrincipalName,'@',0)[0]), InitiatedByUPNSuffix = tostring(split(InitiatingUserPrincipalName,'@',1)[0])
  | project-reorder TimeGenerated, TargetUserPrincipalName, Role, OperationName, Result, ResultDescription
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: TargetUserPrincipalName
      - identifier: Name
        columnName: TargetName
      - identifier: UPNSuffix
        columnName: TargetUPNSuffix
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: InitiatingUserPrincipalName
      - identifier: Name
        columnName: InitiatedByName
      - identifier: UPNSuffix
        columnName: InitiatedByUPNSuffix
  - entityType: Account
    fieldMappings:
      - identifier: AadUserId
        columnName: InitiatingAadUserId
  - entityType: Account
    fieldMappings:
      - identifier: AadUserId
        columnName: InitiatingAppServicePrincipalId
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: InitiatingIpAddress
version: 1.0.4
kind: NRT

Stages and Predicates

Stage 1: source

AuditLogs

Stage 2: where

| where ActivityDisplayName =~ 'Add member to role request denied (PIM activation)'

Stage 3: kusto:mv-apply

| mv-apply ResourceItem = TargetResources on 
  (
      where ResourceItem.type =~ "Role"
      | extend Role = trim(@'"',tostring(ResourceItem.displayName))
  )

Stage 4: kusto:mv-apply

| mv-apply ResourceItem = TargetResources on 
  (
      where ResourceItem.type =~ "User"
      | extend TargetUserPrincipalName = trim(@'"',tostring(ResourceItem.userPrincipalName))
  )

Stage 5: where

| where ResultReason != "RoleAssignmentExists"

Stage 6: where

| where isnotempty(InitiatedBy.user)

Stage 7: extend (7 consecutive steps)

| extend InitiatingAppName = tostring(InitiatedBy.app.displayName)
| extend InitiatingAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId)
| extend InitiatingUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatingAadUserId = tostring(InitiatedBy.user.id)
| extend InitiatingIpAddress = tostring(iff(isnotempty(InitiatedBy.user.ipAddress), InitiatedBy.user.ipAddress, InitiatedBy.app.ipAddress))
| extend TargetName = tostring(split(TargetUserPrincipalName,'@',0)[0]), TargetUPNSuffix = tostring(split(TargetUserPrincipalName,'@',1)[0])
| extend InitiatedByName = tostring(split(InitiatingUserPrincipalName,'@',0)[0]), InitiatedByUPNSuffix = tostring(split(InitiatingUserPrincipalName,'@',1)[0])

Stage 8: project-reorder

| project-reorder TimeGenerated, TargetUserPrincipalName, Role, OperationName, Result, ResultDescription

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
ActivityDisplayNameeq
  • Add member to role request denied (PIM activation) corpus 3 (kusto 3)
field:"azure_ad::activity_display_name" kind:eq value:"Add member to role request denied (PIM activation)"
InitiatedBy.useris_not_null
  • (no value, null check)
field:"InitiatedBy.user" kind:is_not_null
ResourceItem.typeeq
  • Role transforms: kusto_dynamic_path
  • User transforms: kusto_dynamic_path
field:"ResourceItem.type" kind:eq
ResultReasonne
  • RoleAssignmentExists
field:"ResultReason" kind:ne value:"RoleAssignmentExists"

Output Fields

These fields are emitted when the rule matches.

FieldSource
InitiatingAppNameextend
InitiatingAppServicePrincipalIdextend
InitiatingUserPrincipalNameextend
InitiatingAadUserIdextend
InitiatingIpAddressextend
TargetNameextend
TargetUPNSuffixextend
InitiatedByNameextend
InitiatedByUPNSuffixextend

NRT Security Event log cleared

#
Status
available
Severity
medium
Group by
Account, Activity, Computer, EventID
Source
github.com/Azure/Azure-Sentinel

Checks for event id 1102 which indicates the security event log was cleared. It uses Event Source Name "Microsoft-Windows-Eventlog" to avoid generating false positives from other sources, like AD FS servers for instance.

MITRE ATT&CK Coverage

TacticTechniques
Stealth

Telemetry Coverage

Rule Body

id: 508cef41-2cd8-4d40-a519-b04826a9085f
name: NRT Security Event log cleared
description: |
  'Checks for event id 1102 which indicates the security event log was cleared.
  It uses Event Source Name "Microsoft-Windows-Eventlog" to avoid generating false positives from other sources, like AD FS servers for instance.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsSecurityEvents
    dataTypes:
      - SecurityEvent
tactics:
  - DefenseEvasion
relevantTechniques:
  - T1070
query: |
  SecurityEvent
  | where EventID == 1102 and EventSourceName == "Microsoft-Windows-Eventlog"
  | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), EventCount = count() by Computer, Account, EventID, Activity
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
  | extend AccountName = tostring(split(Account, @'\')[1]), AccountNTDomain = tostring(split(Account, @'\')[0])
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Account
      - identifier: Name
        columnName: AccountName
      - identifier: NTDomain
        columnName: AccountNTDomain
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
version: 1.0.1
kind: NRT

Stages and Predicates

Stage 1: source

SecurityEvent

Stage 2: where

| where EventID == 1102 and EventSourceName == "Microsoft-Windows-Eventlog"

Stage 3: summarize

| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), EventCount = count() by Computer, Account, EventID, Activity

Stage 4: extend (3 consecutive steps)

| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend AccountName = tostring(split(Account, @'\')[1]), AccountNTDomain = tostring(split(Account, @'\')[0])

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
Accountsummarize
Activitysummarize
Computersummarize
EndTimeUtcsummarize
EventCountsummarize
EventIDsummarize
StartTimeUtcsummarize
DomainIndexextend
HostNameextend
HostNameDomainextend
AccountNTDomainextend
AccountNameextend

ProofpointPOD - Multiple large emails to the same recipient

#
Status
available
Severity
medium
Time window
30m
Group by
DstUserUpn, SrcUserUpn
Source
github.com/Azure/Azure-Sentinel

'Detects when multiple emails with large size where sent to the same recipient.'

MITRE ATT&CK Coverage

TacticTechniques
Exfiltration

Rule Body

id: d1aba9a3-5ab1-45ef-8ed4-da57dc3c0d32
name: ProofpointPOD - Multiple large emails to the same recipient
description: |
  'Detects when multiple emails with large size where sent to the same recipient.'
severity: Medium
status: Available 
requiredDataConnectors:
  - connectorId: ProofpointPOD
    dataTypes:
      - ProofpointPOD_message_CL
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Exfiltration
relevantTechniques:
  - T1567
query: |
  let lbtime = 30m;
  let msgthreshold = 3;
  let msgszthreshold = 3000000;
  ProofpointPOD
  | where TimeGenerated > ago(lbtime)
  | where EventType == 'message'
  | where NetworkDirection == 'outbound'
  | where NetworkBytes > msgszthreshold
  | summarize count() by SrcUserUpn, DstUserUpn
  | where count_ > msgthreshold
  | extend AccountCustomEntity = SrcUserUpn
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountCustomEntity
version: 1.0.1
kind: Scheduled

Stages and Predicates

Parameters

let lbtime = 30m;
let msgthreshold = 3;
let msgszthreshold = 3000000;

Stage 1: source

ProofpointPOD

Stage 2: where

| where TimeGenerated > ago(lbtime)

Stage 3: where

| where EventType == 'message'

Stage 4: where

| where NetworkDirection == 'outbound'

Stage 5: where

| where NetworkBytes > msgszthreshold

Stage 6: summarize

| summarize count() by SrcUserUpn, DstUserUpn

Stage 7: where

| where count_ > msgthreshold

Stage 8: extend

| extend AccountCustomEntity = SrcUserUpn

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
DstUserUpnsummarize
SrcUserUpnsummarize
AccountCustomEntityextend

TI Map Email entity to Cloud App Events

#
Severity
medium
Time window
14d
Group by
$left.EmailSenderAddress, $right.User_Id, Id, IndicatorId, ObservableValue, User_Id
Source
github.com/Azure/Azure-Sentinel

Identifies compromises and attacks and detect malicious activities in one's email entity from TI

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Telemetry Coverage

Rule Body

id: 0385e99c-ae45-45f4-aecf-00104485cd6b
name: TI Map Email entity to Cloud App Events
description: |
  'Identifies compromises and attacks and detect malicious activities in one's email entity from TI'
severity: Medium
requiredDataConnectors:
  - connectorId: MicrosoftThreatProtection
    dataTypes:
      - CloudAppEvents
  - connectorId: MicrosoftDefenderThreatIntelligence
    dataTypes:
      - ThreatIntelIndicators
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
relevantTechniques:
  - T1566
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let emailregex = @'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$';
  ThreatIntelIndicators
    | where TimeGenerated >= ago(ioc_lookBack)
    | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue
    | where IsActive and (ValidUntil > now() or isempty(ValidUntil))
  //extract key part of kv pair
    | extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))
    | where IndicatorType == "email-addr"
    | extend EmailSenderAddress = ObservableValue
    | extend EmailSourceDomain = substring(EmailSenderAddress, indexof(EmailSenderAddress, "@") + 1, strlen(EmailSenderAddress) - indexof(EmailSenderAddress, "@") - 1)
    | project-reorder *, EmailSenderAddress, EmailSourceDomain, Type
    | extend IndicatorId = tostring(split(Id, "--")[2])
    | join kind=innerunique (CloudAppEvents
  | extend User_Id = tostring(RawEventData.UserId)
  | where isnotempty(User_Id)
  | where TimeGenerated >= ago(dt_lookBack) and isnotempty(Application)
  | extend CloudAppEvents_TimeGenerated = TimeGenerated 
  | where User_Id matches regex emailregex) on $left.EmailSenderAddress == $right.User_Id
  | where CloudAppEvents_TimeGenerated < ValidUntil
  | summarize CloudAppEvents_TimeGenerated = argmax(CloudAppEvents_TimeGenerated, *) by IndicatorId, User_Id
  | extend Name = tostring(split(User_Id, '@', 0)[0]), UPNSuffix = tostring(split(User_Id, '@', 1)[0])
  | extend timestamp = CloudAppEvents_TimeGenerated
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: DisplayName
        columnName: Name
      - identifier: FullName
        columnName: User_Id
      - identifier: UPNSuffix
        columnName: UPNSuffix
version: 1.0.8
kind: Scheduled

Stages and Predicates

Parameters

let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let emailregex = @'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$';

Stage 1: source

ThreatIntelIndicators

Stage 2: where

| where TimeGenerated >= ago(ioc_lookBack)

Stage 3: summarize

| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by Id, ObservableValue

Stage 4: where

| where IsActive and (ValidUntil > now() or isempty(ValidUntil))

Stage 5: extend

| extend IndicatorType = replace(@"\[|\]|\""", "", tostring(split(ObservableKey, ":", 0)))

Stage 6: where

| where IndicatorType == "email-addr"

Stage 7: extend

| extend EmailSenderAddress = ObservableValue

Stage 8: extend

| extend EmailSourceDomain = substring(EmailSenderAddress, indexof(EmailSenderAddress, "@") + 1, strlen(EmailSenderAddress) - indexof(EmailSenderAddress, "@") - 1)

Stage 9: project-reorder

| project-reorder *, EmailSenderAddress, EmailSourceDomain, Type

Stage 10: extend

| extend IndicatorId = tostring(split(Id, "--")[2])

Stage 11: join

| join kind=innerunique (CloudAppEvents
| extend User_Id = tostring(RawEventData.UserId)
| where isnotempty(User_Id)
| where TimeGenerated >= ago(dt_lookBack) and isnotempty(Application)
| extend CloudAppEvents_TimeGenerated = TimeGenerated 
| where User_Id matches regex emailregex) on $left.EmailSenderAddress == $right.User_Id

Stage 12: where

where CloudAppEvents_TimeGenerated < ValidUntil

Stage 13: summarize

summarize CloudAppEvents_TimeGenerated by IndicatorId, User_Id

Stage 14: extend

extend Name, UPNSuffix

Stage 15: extend

extend timestamp

Indicators

These rows show field, operator, and value matches.

Output Fields

These fields are emitted when the rule matches.

FieldSource
CloudAppEvents_TimeGeneratedsummarize
IndicatorIdsummarize
User_Idsummarize
Nameextend
UPNSuffixextend
timestampextend

Uniqkey - Platform threat detection

#
Severity
high
Time window
1h
Source
github.com/Azure/Azure-Sentinel

Surfaces threat detections generated by the Uniqkey platform itself, such as employee credentials discovered in a data breach, as Microsoft Sentinel alerts. Promoting these vendor-side detections into Microsoft Sentinel lets them be triaged, correlated with other signals and tracked as incidents alongside the rest of the security stack. Each detection is raised as its own alert.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

id: 712f5770-a5a9-4623-8adc-26cda17294a5
name: Uniqkey - Platform threat detection
version: 1.0.0
kind: Scheduled
description: |-
  Surfaces threat detections generated by the Uniqkey platform itself, such as employee credentials discovered in a data breach, as Microsoft Sentinel alerts. Promoting these vendor-side detections into Microsoft Sentinel lets them be triaged, correlated with other signals and tracked as incidents alongside the rest of the security stack. Each detection is raised as its own alert.
severity: High
requiredDataConnectors:
  - connectorId: UniqkeyEventsConnector
    dataTypes:
      - UniqkeyEvents_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- CredentialAccess
relevantTechniques:
- T1078
query: |-
  UniqkeyEvents_CL
  | where Category == "threat_detection"
  | project TimeGenerated, ActorEmail, ActorType, Action, ActionId, TargetType, TargetName, ClientSystem, SrcIpAddr
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: FullName
    columnName: ActorEmail
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: SrcIpAddr
suppressionEnabled: false
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: 5h
    matchingMethod: AllEntities
suppressionDuration: 5h
eventGroupingSettings:
  aggregationKind: AlertPerResult

Stages and Predicates

Stage 1: source

UniqkeyEvents_CL

Stage 2: where

| where Category == "threat_detection"

Stage 3: project

| project TimeGenerated, ActorEmail, ActorType, Action, ActionId, TargetType, TargetName, ClientSystem, SrcIpAddr

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Categoryeq
  • threat_detection
field:"Category" kind:eq value:"threat_detection"

Output Fields

These fields are emitted when the rule matches.

FieldSource
Actionproject
ActionIdproject
ActorEmailproject
ActorTypeproject
ClientSystemproject
SrcIpAddrproject
TargetNameproject
TargetTypeproject
TimeGeneratedproject

VTI - High Severity Domain Collision Detection

#
Severity
high
Time window
1h
Group by
$left.UrlDomain, $right.Value
Source
github.com/Azure/Azure-Sentinel

This will alert when a collision is detected for EmailUrlInfo events with VTI high severity domain IoCs

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Telemetry Coverage

Rule Body

id: 7be47078-657a-43cf-9c93-b4705a9f6134
name: VTI - High Severity Domain Collision Detection
version: 1.0.0
kind: Scheduled
description: |-
  This will alert when a collision is detected for EmailUrlInfo events with VTI high severity domain IoCs
severity: High
requiredDataConnectors:
  - connectorId: VisaThreatIntelligence
    dataTypes:
      - VisaThreatIntelligenceIOC_CL
      - EmailUrlInfo
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |-
  EmailUrlInfo
  | join kind=inner (VisaThreatIntelligenceIOC_CL  | where IOCType == "domain" and SourceSeverity == "High")
  on $left.UrlDomain == $right.Value
suppressionEnabled: false
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: 1h
    matchingMethod: AllEntities
suppressionDuration: 1h
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
- entityType: URL
  fieldMappings:
  - identifier: Url
    columnName: Url
- entityType: DNS
  fieldMappings:
  - identifier: DomainName
    columnName: UrlDomain

Stages and Predicates

Stage 1: source

EmailUrlInfo

Stage 2: join

| join kind=inner (VisaThreatIntelligenceIOC_CL  | where IOCType == "domain" and SourceSeverity == "High")
on $left.UrlDomain == $right.Value

Indicators

These rows show field, operator, and value matches.

Back to all Kusto rules