Detection rules › Kusto
Kusto rules: 2i
ADWS Connection from Unexpected Binary
#This query first collects the IP addresses of all machines that have the Active Directory Web Services (ADWS) service running. It then searches for network connections to these IP addresses from processes that are not expected to connect to ADWS.
Known False Positives
- ADWS is used by a number of legitimate applications that need to interact with Active Directory. These applications should be added to the allow-listing to avoid false positives.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Discovery | |
| Collection |
References
Telemetry Coverage
Rule Body
let timeframe = 2*1h;
let ADWSIPs=(
DeviceNetworkEvents
| where ingestion_time() >= ago(timeframe)
| where InitiatingProcessFolderPath == @"c:\windows\adws\microsoft.activedirectory.webservices.exe"
| where LocalPort == 9389
| distinct LocalIP
);
DeviceNetworkEvents
| where ingestion_time() >= ago(timeframe)
| where ActionType == "ConnectionSuccess"
| where RemotePort == 9389
| where RemoteIP in (ADWSIPs)
| where not(isempty(InitiatingProcessFileName))
| where not(InitiatingProcessFolderPath in~ (@"c:\windows\system32\dsac.exe", @"c:\program files\powershell\7\pwsh.exe"))
| where not(InitiatingProcessFolderPath startswith @"c:\windows\system32\windowspowershell\")
| where not(InitiatingProcessFolderPath startswith @"c:\windows\syswow64\windowspowershell\")
| where not(InitiatingProcessFolderPath startswith @"c:\program files\microsoft monitoring agent\")
// Begin environment-specific filter.
// End environment-specific filter.
Stages and Predicates
Parameters
let timeframe = 2*1h;
Let Binding: ADWSIPs
let ADWSIPs = (
DeviceNetworkEvents
| where ingestion_time() >= ago(timeframe)
| where InitiatingProcessFolderPath == @"c:\windows\adws\microsoft.activedirectory.webservices.exe"
| where LocalPort == 9389
| distinct LocalIP
);
Stage 1: source
let ADWSIPs
Stage 2: source
DeviceNetworkEvents
Stage 3: where
where ...
Stage 4: where
where ActionType == "ConnectionSuccess"
Stage 5: where
where RemotePort == 9389
Stage 6: where
where RemoteIP == "ADWSIPs"
Stage 7: where
where not (isempty(InitiatingProcessFileName))
Stage 8: where
where not (InitiatingProcessFolderPath in~ (@"c:\program files\powershell\7\pwsh.exe", @"c:\windows\system32\dsac.exe"))
Stage 9: where
where not (InitiatingProcessFolderPath startswith @"c:\windows\system32\windowspowershell\")
Stage 10: where
where not (InitiatingProcessFolderPath startswith @"c:\windows\syswow64\windowspowershell\")
Stage 11: where
where not (InitiatingProcessFolderPath startswith @"c:\program files\microsoft monitoring agent\")
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
ActionType | eq |
| field:"ActionType" kind:eq value:"ConnectionSuccess" |
RemoteIP | in |
| field:"RemoteIP" kind:in value:"ADWSIPs" |
RemotePort | eq |
| field:"RemotePort" kind:eq value:"9389" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
InitiatingProcessFileName | is_null | excludes:InitiatingProcessFileName | |
InitiatingProcessFolderPath | in | c:\program files\powershell\7\pwsh.exe, c:\windows\system32\dsac.exe | excludes:InitiatingProcessFolderPath field:"InitiatingProcessFolderPath" value:"c:\program files\powershell\7\pwsh.exe" field:"InitiatingProcessFolderPath" value:"c:\windows\system32\dsac.exe" |
InitiatingProcessFolderPath | starts_with | c:\windows\system32\windowspowershell\ | excludes:InitiatingProcessFolderPath field:"InitiatingProcessFolderPath" value:"c:\windows\system32\windowspowershell\" |
InitiatingProcessFolderPath | starts_with | c:\windows\syswow64\windowspowershell\ | excludes:InitiatingProcessFolderPath field:"InitiatingProcessFolderPath" value:"c:\windows\syswow64\windowspowershell\" |
InitiatingProcessFolderPath | starts_with | c:\program files\microsoft monitoring agent\ | excludes:InitiatingProcessFolderPath field:"InitiatingProcessFolderPath" value:"c:\program files\microsoft monitoring agent\" |
Alsid Active Directory attacks pathways
#'Searches for triggered Indicators of Exposures related to Active Directory attacks pathways'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
id: 9649e203-3cb7-47ff-89a9-42f2a5eefe31
name: Alsid Active Directory attacks pathways
description: |
'Searches for triggered Indicators of Exposures related to Active Directory attacks pathways'
severity: Low
requiredDataConnectors:
- connectorId: AlsidForAD
dataTypes:
- AlsidForADLog_CL
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
- CredentialAccess
relevantTechniques:
- T1110
query: |
let SeverityTable=datatable(Severity:string,Level:int) [
"low", 1,
"medium", 2,
"high", 3,
"critical", 4
];
let codeNameList = datatable(Codename:string)["C-PRIV-ACCOUNTS-SPN", "C-SDPROP-CONSISTENCY", "C-DANG-PRIMGROUPID", "C-GPO-HARDENING", "C-DC-ACCESS-CONSISTENCY", "C-DANGEROUS-TRUST-RELATIONSHIP", "C-UNCONST-DELEG", "C-ABNORMAL-ENTRIES-IN-SCHEMA"];
afad_parser
| where MessageType == 0 and Codename in~ (codeNameList)
| lookup kind=leftouter SeverityTable on Severity
| order by Level
| extend HostName = tostring(split(Host, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Host, '.'), 1, -1), '.'))
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
version: 1.0.1
kind: Scheduled
Stages and Predicates
Let Binding: SeverityTable
let SeverityTable = datatable(Severity:string,Level:int) [
"low", 1,
"medium", 2,
"high", 3,
"critical", 4
];
Let Binding: codeNameList
let codeNameList = datatable(Codename:string)["C-PRIV-ACCOUNTS-SPN", "C-SDPROP-CONSISTENCY", "C-DANG-PRIMGROUPID", "C-GPO-HARDENING", "C-DC-ACCESS-CONSISTENCY", "C-DANGEROUS-TRUST-RELATIONSHIP", "C-UNCONST-DELEG", "C-ABNORMAL-ENTRIES-IN-SCHEMA"];
Stage 1: source
afad_parser
Stage 2: where
| where MessageType == 0 and Codename in~ (codeNameList)
Stage 3: kusto:lookup
lookup kind=leftouter (SeverityTable) on Severity
Stage 4: sort
sort by Level
Stage 5: extend
extend DnsDomain, HostName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Codename | in |
| field:"Codename" kind:in value:"codeNameList" |
MessageType | eq |
| field:"MessageType" kind:eq value:"0" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DnsDomain | extend |
HostName | extend |
BloodHound Attack Path Finding - GenericWrite Privileges on Tier Zero Objects
#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.
BloodHound Attack Path Finding - GenericWrite Privileges on Tier Zero Objects
Rule Body
id: 20d7a85c-6af9-4471-a403-961445c0e49e
name: BloodHound Attack Path Finding - GenericWrite Privileges on Tier Zero Objects
description: BloodHound Attack Path Finding - GenericWrite Privileges on Tier Zero
Objects
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: BloodHoundEnterprise
dataTypes:
- BHEAttackPathsData_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics: []
relevantTechniques: []
query: "BHEAttackPathsData_CL \n| where Finding == \"T0GenericWrite\""
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 == "T0GenericWrite"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Finding | eq |
| field:"Finding" kind:eq value:"T0GenericWrite" |
BloodHound Attack Path Finding - Large Default Groups With Resource-Based Constrained Delegation Privileges
#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.
BloodHound Attack Path Finding - Large Default Groups With Resource-Based Constrained Delegation Privileges
Rule Body
id: a50a328d-a14d-4599-a4e4-32de5b7fe0c7
name: BloodHound Attack Path Finding - Large Default Groups With Resource-Based Constrained
Delegation Privileges
description: BloodHound Attack Path Finding - Large Default Groups With Resource-Based
Constrained Delegation Privileges
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 == "LargeDefaultGroupsAddAllowedToAct"
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 == "LargeDefaultGroupsAddAllowedToAct"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Finding | eq |
| field:"Finding" kind:eq value:"LargeDefaultGroupsAddAllowedToAct" |
Cisco Umbrella - Crypto Miner User-Agent Detected
#'Detects suspicious user agent strings used by crypto miners in proxy logs.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control | No specific technique |
Rule Body
id: b619d1f1-7f39-4c7e-bf9e-afbb46457997
name: Cisco Umbrella - Crypto Miner User-Agent Detected
description: |
'Detects suspicious user agent strings used by crypto miners in proxy logs.'
severity: Medium
requiredDataConnectors:
- connectorId: CiscoUmbrellaDataConnector
dataTypes:
- Cisco_Umbrella_proxy_CL
queryFrequency: 15m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
query: |
let timeframe = 15m;
Cisco_Umbrella
| where EventType == "proxylogs"
| where TimeGenerated > ago(timeframe)
| where HttpUserAgentOriginal contains "XMRig" or HttpUserAgentOriginal contains "ccminer"
| extend Message = "Crypto Miner User Agent"
| project Message, SrcIpAddr, DstIpAddr, UrlOriginal, TimeGenerated,HttpUserAgentOriginal
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: UrlOriginal
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
version: 1.1.2
kind: Scheduled
Stages and Predicates
Parameters
let timeframe = 15m;
Stage 1: source
Cisco_Umbrella
Stage 2: where
| where EventType == "proxylogs"
Stage 3: where
| where TimeGenerated > ago(timeframe)
Stage 4: where
| where HttpUserAgentOriginal contains "XMRig" or HttpUserAgentOriginal contains "ccminer"
Stage 5: extend
| extend Message = "Crypto Miner User Agent"
Stage 6: project
| project Message, SrcIpAddr, DstIpAddr, UrlOriginal, TimeGenerated,HttpUserAgentOriginal
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventType | eq |
| field:"EventType" kind:eq value:"proxylogs" |
HttpUserAgentOriginal | contains |
| field:"HttpUserAgentOriginal" kind:contains |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstIpAddr | project |
HttpUserAgentOriginal | project |
Message | project |
SrcIpAddr | project |
TimeGenerated | project |
UrlOriginal | project |
Cisco Umbrella - Rare User Agent Detected
#'Rule helps to detect a rare user-agents indicating web browsing activity by an unusual process other than a web browser.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control | No specific technique |
Rule Body
id: 8c8de3fa-6425-4623-9cd9-45de1dd0569a
name: Cisco Umbrella - Rare User Agent Detected
description: |
'Rule helps to detect a rare user-agents indicating web browsing activity by an unusual process other than a web browser.'
severity: Medium
requiredDataConnectors:
- connectorId: CiscoUmbrellaDataConnector
dataTypes:
- Cisco_Umbrella_proxy_CL
queryFrequency: 1d
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CommandAndControl
query: |
let lookBack = 14d;
let timeframe = 1d;
let user_agents_list = Cisco_Umbrella
| where EventType == "proxylogs"
| where TimeGenerated > ago(lookBack) and TimeGenerated < ago(timeframe)
| summarize count() by HttpUserAgentOriginal
| summarize make_list(HttpUserAgentOriginal);
Cisco_Umbrella
| where EventType == "proxylogs"
| where TimeGenerated > ago(timeframe)
| where HttpUserAgentOriginal !in (user_agents_list)
| extend Message = "Rare User Agent"
| project Message, SrcIpAddr, DstIpAddr, UrlOriginal, TimeGenerated, HttpUserAgentOriginal
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: UrlOriginal
- entityType: IP
fieldMappings:
- identifier: Address
columnName: SrcIpAddr
version: 1.1.2
kind: Scheduled
Stages and Predicates
Parameters
let lookBack = 14d;
let timeframe = 1d;
Let Binding: user_agents_list
let user_agents_list = Cisco_Umbrella
| where EventType == "proxylogs"
| where TimeGenerated > ago(lookBack) and TimeGenerated < ago(timeframe)
| summarize count() by HttpUserAgentOriginal
| summarize make_list(HttpUserAgentOriginal);
Stage 1: source
Cisco_Umbrella
Stage 2: where
| where EventType == "proxylogs"
Stage 3: where
| where TimeGenerated > ago(timeframe)
Stage 4: where
| where HttpUserAgentOriginal !in (user_agents_list)
Stage 5: extend
| extend Message = "Rare User Agent"
Stage 6: project
| project Message, SrcIpAddr, DstIpAddr, UrlOriginal, TimeGenerated, HttpUserAgentOriginal
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventType | eq |
| field:"EventType" kind:eq value:"proxylogs" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
HttpUserAgentOriginal | eq | user_agents_list | excludes:HttpUserAgentOriginal field:"HttpUserAgentOriginal" value:"user_agents_list" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DstIpAddr | project |
HttpUserAgentOriginal | project |
Message | project |
SrcIpAddr | project |
TimeGenerated | project |
UrlOriginal | project |
Conditional Access - A Conditional Access Device platforms condition has changed (the Device platforms condition can be spoofed)
#A Conditional Access Device platforms condition has changed (the Device platforms condition can be spoofed) in Entra ID.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Update conditional access policy |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure MFA Disabled (Panther)
- Azure Policy Violation Detected (Panther)
- CA Policy Removed by Non Approved Actor (Sigma)
- CA Policy Updated by Non Approved Actor (Sigma)
- Certificate-Based Authentication Enabled (Sigma)
- Changes to Device Registration Policy (Sigma)
- Conditional Access - A Conditional Access app exclusion has changed (Kusto)
- Conditional Access - A Conditional Access policy was deleted (Kusto)
Rule Body
id: e3368079-a2c0-4f1c-9fb7-287e907393ef
name: Conditional Access - A Conditional Access Device platforms condition has changed (the Device platforms condition can be spoofed)
version: 1.0.1
kind: Scheduled
description: A Conditional Access Device platforms condition has changed (the Device platforms condition can be spoofed) in Entra ID.
severity: Low
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1562.007
query: |+
// A Conditional Access Device platforms condition has changed (the Device platforms condition can be spoofed).
AuditLogs
| where OperationName in ("Update conditional access policy")
| extend excludePlatformsOld = extractjson("$.conditions.platforms.excludePlatforms", tostring(TargetResources[0].modifiedProperties[0].oldValue))
| extend excludePlatformsNew = extractjson("$.conditions.platforms.excludePlatforms", tostring(TargetResources[0].modifiedProperties[0].newValue))
| where excludePlatformsOld != excludePlatformsNew
| extend modifiedBy = tostring(InitiatedBy.user.userPrincipalName)
| extend accountName = tostring(split(modifiedBy, "@")[0])
| extend upnSuffix = tostring(split(modifiedBy, "@")[1])
| project
TimeGenerated,
OperationName,
policy = TargetResources[0].displayName,
modifiedBy,
accountName,
upnSuffix,
result = Result,
excludePlatformsOld,
excludePlatformsNew
| order by TimeGenerated desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: accountName
- identifier: UPNSuffix
columnName: upnSuffix
suppressionEnabled: false
suppressionDuration: 5h
eventGroupingSettings:
aggregationKind: AlertPerResult
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT1H
matchingMethod: AllEntities
groupByEntities: []
groupByAlertDetails: []
groupByCustomDetails: []
Stages and Predicates
Stage 1: source
AuditLogs
Stage 2: where
| where OperationName in ("Update conditional access policy")
Stage 3: extend
| extend excludePlatformsOld = extractjson("$.conditions.platforms.excludePlatforms", tostring(TargetResources[0].modifiedProperties[0].oldValue))
Stage 4: extend
| extend excludePlatformsNew = extractjson("$.conditions.platforms.excludePlatforms", tostring(TargetResources[0].modifiedProperties[0].newValue))
Stage 5: where
| where excludePlatformsOld != excludePlatformsNew
Stage 6: extend (3 consecutive steps)
| extend modifiedBy = tostring(InitiatedBy.user.userPrincipalName)
| extend accountName = tostring(split(modifiedBy, "@")[0])
| extend upnSuffix = tostring(split(modifiedBy, "@")[1])
Stage 7: project
| project
TimeGenerated,
OperationName,
policy = TargetResources[0].displayName,
modifiedBy,
accountName,
upnSuffix,
result = Result,
excludePlatformsOld,
excludePlatformsNew
Stage 8: sort
| order by TimeGenerated desc
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
OperationName | in |
| field:"OperationName" kind:in value:"Update conditional access policy" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
OperationName | project |
TimeGenerated | project |
accountName | project |
excludePlatformsNew | project |
excludePlatformsOld | project |
modifiedBy | project |
policy | project |
result | project |
upnSuffix | project |
Conditional Access - A Conditional Access policy was disabled
#A Conditional Access policy was disabled in Entra ID.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Defense Impairment |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Update conditional access policy |
Rules Detecting the Same Action
These rules filter on the same operation.
- Azure MFA Disabled (Panther)
- Azure Policy Violation Detected (Panther)
- CA Policy Removed by Non Approved Actor (Sigma)
- CA Policy Updated by Non Approved Actor (Sigma)
- Certificate-Based Authentication Enabled (Sigma)
- Changes to Device Registration Policy (Sigma)
- Conditional Access - A Conditional Access app exclusion has changed (Kusto)
- Conditional Access - A Conditional Access Device platforms condition has changed (the Device platforms condition can be spoofed) (Kusto)
Rule Body
id: 40702da1-ae8a-4e46-ac1f-9327ca6ef588
name: Conditional Access - A Conditional Access policy was disabled
version: 1.0.1
kind: Scheduled
description: A Conditional Access policy was disabled in Entra ID.
severity: Low
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1562.007
query: |+
// A Conditional Access policy was disabled.
AuditLogs
| where OperationName in ("Update conditional access policy")
| extend stateOld = extractjson("$.state", tostring(TargetResources[0].modifiedProperties[0].oldValue))
| extend stateNew = extractjson("$.state", tostring(TargetResources[0].modifiedProperties[0].newValue))
| where stateOld == "enabled" and stateNew == "disabled"
| extend modifiedBy = tostring(InitiatedBy.user.userPrincipalName)
| extend accountName = tostring(split(modifiedBy, "@")[0])
| extend upnSuffix = tostring(split(modifiedBy, "@")[1])
| project
TimeGenerated,
OperationName,
policy = TargetResources[0].displayName,
modifiedBy,
accountName,
upnSuffix,
result = Result,
stateOld,
stateNew
| order by TimeGenerated desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: accountName
- identifier: UPNSuffix
columnName: upnSuffix
suppressionEnabled: false
suppressionDuration: 5h
eventGroupingSettings:
aggregationKind: AlertPerResult
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT1H
matchingMethod: AllEntities
groupByEntities: []
groupByAlertDetails: []
groupByCustomDetails: []
Stages and Predicates
Stage 1: source
AuditLogs
Stage 2: where
| where OperationName in ("Update conditional access policy")
Stage 3: extend
| extend stateOld = extractjson("$.state", tostring(TargetResources[0].modifiedProperties[0].oldValue))
Stage 4: extend
| extend stateNew = extractjson("$.state", tostring(TargetResources[0].modifiedProperties[0].newValue))
Stage 5: where
| where stateOld == "enabled" and stateNew == "disabled"
Stage 6: extend (3 consecutive steps)
| extend modifiedBy = tostring(InitiatedBy.user.userPrincipalName)
| extend accountName = tostring(split(modifiedBy, "@")[0])
| extend upnSuffix = tostring(split(modifiedBy, "@")[1])
Stage 7: project
| project
TimeGenerated,
OperationName,
policy = TargetResources[0].displayName,
modifiedBy,
accountName,
upnSuffix,
result = Result,
stateOld,
stateNew
Stage 8: sort
| order by TimeGenerated desc
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
OperationName | in |
| field:"OperationName" kind:in value:"Update conditional access policy" |
stateNew | eq |
| field:"stateNew" kind:eq value:"disabled" |
stateOld | eq |
| field:"stateOld" kind:eq value:"enabled" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
OperationName | project |
TimeGenerated | project |
accountName | project |
modifiedBy | project |
policy | project |
result | project |
stateNew | project |
stateOld | project |
upnSuffix | project |
Critical Finding Overdue on Internet-Facing App
#Detects Critical and High severity findings older than 7 days that remain open on internet-facing applications. Uses the InternetFacingApps watchlist to scope results to externally exposed assets requiring urgent remediation.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Impact |
Rule Body
id: 88c4b680-db1c-46b9-8ca4-4165c3abf63f
name: Critical Finding Overdue on Internet-Facing App
description: |
Detects Critical and High severity findings older than 7 days that remain
open on internet-facing applications. Uses the InternetFacingApps watchlist
to scope results to externally exposed assets requiring urgent remediation.
severity: High
status: Available
requiredDataConnectors:
- connectorId: StratoSecurePush
dataTypes:
- StratoSecure_Findings_CL
queryFrequency: 1d
queryPeriod: 1455m
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
relevantTechniques:
- T1499
query: |
let maxAgeDays = 7;
let InternetFacingList = _GetWatchlist("InternetFacingApps")
| project WL_ApplicationId = column_ifexists("ApplicationId", ""),
WL_AppName = column_ifexists("AppName", ""),
WL_Owner = column_ifexists("Owner", "");
StratoSecure_Findings_CL
| where FixStatus =~ "open"
| where Severity in ("Critical", "High")
| extend AgeInDays = datetime_diff("day", now(), TimeGenerated)
| where AgeInDays > maxAgeDays
| join kind=inner InternetFacingList on $left.ApplicationId == $right.WL_ApplicationId
| summarize TotalOverdueFindings = count(), OldestAge = max(AgeInDays),
RuleIds = make_set(RuleId, 20), EndTime = max(TimeGenerated)
by ApplicationId, WL_AppName, WL_Owner, StraTenantId
| project TimeGenerated = EndTime, ApplicationId, AppName = WL_AppName, Owner = WL_Owner,
StraTenantId, TotalOverdueFindings, OldestAge, RuleIds
entityMappings:
- entityType: CloudApplication
fieldMappings:
- identifier: AppId
columnName: ApplicationId
version: 1.0.0
kind: Scheduled
Stages and Predicates
Parameters
let maxAgeDays = 7;
Let Binding: InternetFacingList
let InternetFacingList = _GetWatchlist("InternetFacingApps")
| project WL_ApplicationId = column_ifexists("ApplicationId", ""),
WL_AppName = column_ifexists("AppName", ""),
WL_Owner = column_ifexists("Owner", "");
Stage 1: source
StratoSecure_Findings_CL
Stage 2: where
| where FixStatus =~ "open"
Stage 3: where
| where Severity in ("Critical", "High")
Stage 4: extend
| extend AgeInDays = datetime_diff("day", now(), TimeGenerated)
Stage 5: where
| where AgeInDays > maxAgeDays
Stage 6: join
| join kind=inner InternetFacingList on $left.ApplicationId == $right.WL_ApplicationId
Stage 7: summarize
summarize EndTime, OldestAge, RuleIds, TotalOverdueFindings by ApplicationId, WL_AppName, WL_Owner, StraTenantId
Stage 8: project
project AppName, ApplicationId, OldestAge, Owner, RuleIds, StraTenantId, TimeGenerated, TotalOverdueFindings
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
AgeInDays | gt |
| field:"AgeInDays" kind:gt value:"7" |
FixStatus | eq |
| field:"FixStatus" kind:eq value:"open" |
Severity | in |
| field:"Severity" kind:in |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AppName | project |
ApplicationId | project |
OldestAge | project |
Owner | project |
RuleIds | project |
StraTenantId | project |
TimeGenerated | project |
TotalOverdueFindings | project |
Cyble Vision Alerts Phishing Domain Detected
#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.
'Cyble detected a phishing website impersonating a monitored brand. This alert provides landing page, host, screenshot, status and configured keyword for SOC triage.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Reconnaissance |
Rule Body
id: eb1d45fe-1b19-4b54-b146-971f282a6fd9
name: Cyble Vision Alerts Phishing Domain Detected
description: |
'Cyble detected a phishing website impersonating a monitored brand. This alert provides landing page, host, screenshot, status and configured keyword for SOC triage.'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: CybleVisionAlerts
dataTypes:
- CybleVisionAlerts_CL
enabled: true
queryfrequency: 30m
queryPeriod: 30m
triggerOperator: GreaterThan
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics:
- Reconnaissance
relevantTechniques:
- T1598.003
query: |
Alerts_phishing
| where Service == "phishing"
| extend MappedSeverity = Severity
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
alertDetailsOverride:
alertDisplayNameFormat: Phishing Detected {{PH_PhishingKeyword}} on {{PH_DomainName}}
alertDescriptionFormat: |
A phishing landing page impersonating {{PH_Brand}}.
Host {{PH_HostName}}
Live {{PH_IsLive}}
customDetails:
MappedSeverity: Severity
Status: Status
AlertID: AlertID
Service: Service
PH_DomainName: PH_DomainName
PH_Top_Domain: PH_Top_Domain
PH_PhishingKeyword: PH_PhishingKeyword
PH_PhishingStatus: PH_PhishingStatus
PH_HostName: PH_HostName
PH_Title: PH_Title
PH_ScreenshotURL: PH_ScreenshotURL
PH_IsLive: PH_IsLive
PH_DetectedAt: PH_DetectedAt
PH_LastLiveOn: PH_LastLiveOn
PH_AWSObjectName: PH_AWSObjectName
PH_Score: PH_Score
entityMappings:
- entityType: Url
fieldMappings:
- identifier: Url
columnName: PH_DomainName
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: PH_HostName
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
Alerts_phishing
Stage 2: where
| where Service == "phishing"
Stage 3: extend
| extend MappedSeverity = Severity
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Service | eq |
| field:"Service" kind:eq value:"phishing" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
MappedSeverity | extend |
DNS events related to ToR proxies
#'Identifies IP addresses performing DNS lookups associated with common ToR proxies.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Exfiltration |
Rule Body
id: a83ef0f4-dace-4767-bce3-ebd32599d2a0
name: DNS events related to ToR proxies
description: |
'Identifies IP addresses performing DNS lookups associated with common ToR proxies.'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: DNS
dataTypes:
- DnsEvents
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Exfiltration
relevantTechniques:
- T1048
query: |
DnsEvents
| where Name contains "."
| where Name has_any ("tor2web.org", "tor2web.com", "torlink.co", "onion.to", "onion.ink", "onion.cab", "onion.nu", "onion.link",
"onion.it", "onion.city", "onion.direct", "onion.top", "onion.casa", "onion.plus", "onion.rip", "onion.dog", "tor2web.fi",
"tor2web.blutmagie.de", "onion.sh", "onion.lu", "onion.pet", "t2w.pw", "tor2web.ae.org", "tor2web.io", "tor2web.xyz", "onion.lt",
"s1.tor-gateways.de", "s2.tor-gateways.de", "s3.tor-gateways.de", "s4.tor-gateways.de", "s5.tor-gateways.de", "hiddenservice.net")
| extend HostName = iff(Computer has '.', substring(Computer,0,indexof(Computer,'.')),Computer)
| extend DnsDomain = iff(Computer has '.', substring(Computer,indexof(Computer,'.')+1),"")
entityMappings:
- entityType: Host
fieldMappings:
- identifier: FullName
columnName: Computer
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIP
version: 1.0.3
kind: Scheduled
Stages and Predicates
Stage 1: source
DnsEvents
Stage 2: where
| where Name contains "."
Stage 3: where
| where Name has_any ("tor2web.org", "tor2web.com", "torlink.co", "onion.to", "onion.ink", "onion.cab", "onion.nu", "onion.link",
"onion.it", "onion.city", "onion.direct", "onion.top", "onion.casa", "onion.plus", "onion.rip", "onion.dog", "tor2web.fi",
"tor2web.blutmagie.de", "onion.sh", "onion.lu", "onion.pet", "t2w.pw", "tor2web.ae.org", "tor2web.io", "tor2web.xyz", "onion.lt",
"s1.tor-gateways.de", "s2.tor-gateways.de", "s3.tor-gateways.de", "s4.tor-gateways.de", "s5.tor-gateways.de", "hiddenservice.net")
Stage 4: extend
| extend HostName = iff(Computer has '.', substring(Computer,0,indexof(Computer,'.')),Computer)
HostName =Computer has "."substring(Computer, 0, indexof(Computer, '.'))ComputerStage 5: extend
| extend DnsDomain = iff(Computer has '.', substring(Computer,indexof(Computer,'.')+1),"")
DnsDomain =Computer has "."substring(Computer, (indexof(Computer, '.') + 1))""Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Name | contains |
| field:"Name" kind:contains value:"." |
Name | match |
| field:"Name" kind:match |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
HostName | extend |
DnsDomain | extend |
F&O - Non-interactive account mapped to self or sensitive privileged user
#Identifies changes to Microsoft Entra client apps registered for Finance & Operations, specifically when a new client is mapped to a predefined list of sensitive privileged user accounts, or when a user associates a client app with their own account.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | |
| Privilege Escalation | |
| Credential Access | |
| Persistence | |
| Lateral Movement |
Rule Body
id: 5b7cc7f9-fe54-4138-9fb0-d650807345d3
kind: Scheduled
name: F&O - Non-interactive account mapped to self or sensitive privileged user
description: Identifies changes to Microsoft Entra client apps registered for Finance
& Operations, specifically when a new client is mapped to a predefined list of sensitive
privileged user accounts, or when a user associates a client app with their own
account.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: Dynamics365Finance
dataTypes:
- FinanceOperationsActivity_CL
queryFrequency: 15m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
- Persistence
- PrivilegeEscalation
relevantTechniques:
- T1556
- T1098
- T1136
- T1078
- T0859
query: |
// Add sensitive privilege accounts to the privileged_user_accounts variable.
// Example: let privileged_user_accounts = dynamic(["Admin1", "Admin"]);
let privileged_user_accounts = dynamic([]);
FinanceOperationsActivity_CL
| where TableName == "SysAADClientTable" and LogType in ("Insert", "Update")
| extend ClientId = tostring(parse_json(tostring(FormattedData.["03::AADClientId"])).NewData)
| extend User = parse_json(tostring(FormattedData.UserId))
| extend
MappedUser = tostring(User.NewData),
PreviousUserId = tostring(User.OldData),
TargetAppName = tostring(parse_json(tostring(FormattedData.Name)).NewData),
FinOpsAppId = 32780
| where MappedUser in (privileged_user_accounts) or LogCreatedBy == MappedUser
| project
LogCreatedDateTime,
LogCreatedBy,
LogType,
TargetAppName,
MappedUser,
PreviousUserId,
ClientId,
FinOpsAppId
eventGroupingSettings:
aggregationKind: AlertPerResult
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: LogCreatedBy
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: ClientId
- entityType: CloudApplication
fieldMappings:
- identifier: AppId
columnName: FinOpsAppId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: MappedUser
alertDetailsOverride:
alertDisplayNameFormat: F&O - Sensitive non-interactive user mapping detected
alertDescriptionFormat: User account {{LogCreatedBy}} mapped an Azure AD App to
senstitive privileged user account {{MappedUser}}. The associated Azure AD client
ID is {{ClientId}}
version: 3.2.0
Stages and Predicates
Parameters
let privileged_user_accounts = dynamic([]);
Stage 1: source
FinanceOperationsActivity_CL
Stage 2: where
| where TableName == "SysAADClientTable" and LogType in ("Insert", "Update")
Stage 3: extend (3 consecutive steps)
| extend ClientId = tostring(parse_json(tostring(FormattedData.["03::AADClientId"])).NewData)
| extend User = parse_json(tostring(FormattedData.UserId))
| extend
MappedUser = tostring(User.NewData),
PreviousUserId = tostring(User.OldData),
TargetAppName = tostring(parse_json(tostring(FormattedData.Name)).NewData),
FinOpsAppId = 32780
Stage 4: where
| where MappedUser in (privileged_user_accounts) or LogCreatedBy == MappedUser
Stage 5: project
| project
LogCreatedDateTime,
LogCreatedBy,
LogType,
TargetAppName,
MappedUser,
PreviousUserId,
ClientId,
FinOpsAppId
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
LogType | in |
| field:"LogType" kind:in |
MappedUser | in |
| field:"MappedUser" kind:in value:"[]" |
TableName | eq |
| field:"TableName" kind:eq value:"SysAADClientTable" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ClientId | project |
FinOpsAppId | project |
LogCreatedBy | project |
LogCreatedDateTime | project |
LogType | project |
MappedUser | project |
PreviousUserId | project |
TargetAppName | project |
IaaS admin detected
#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.
The policy detects admin users in AWS or Azure.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: dc728ba1-5204-4fde-ab48-eda19c8fad3a
name: IaaS admin detected
kind: Scheduled
description: The policy detects admin users in AWS or Azure.
severity: Medium
status: Available
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1078
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 "IaaS admin detected"
| 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 - IaaS admin detected
alertDescriptionFormat: |
IaaS admin detected. The policy detects admin users in AWS or Azure
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.2
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 "IaaS admin detected"
Stage 5: project
| project EventID, Policy, Severity, Description, Recommendation, URL, Category, Tactics
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Policy | match |
| field:"policy_name_s" kind:match value:"IaaS admin detected" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Category | project |
Description | project |
EventID | project |
Policy | project |
Recommendation | project |
Severity | project |
Tactics | project |
URL | project |
Mimecast Secure Email Gateway - URL Protect
#'Detect threat when potentially malicious url found.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: 80f244cd-b0d6-404e-9aed-37f7a66eda9f
name: Mimecast Secure Email Gateway - URL Protect
description: |
'Detect threat when potentially malicious url found.'
severity: High
status: Available
requiredDataConnectors:
- connectorId: MimecastSEGAPI
dataTypes:
- MimecastCG
enabled: true
queryFrequency: 15m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- Discovery
- Execution
relevantTechniques:
- T1566
query: |
MimecastCG
| where Type == "email_ttp_url"
| extend SenderEnvelope = ['Sender Envelope']
suppressionDuration: 5h
suppressionEnabled: false
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: P7D
matchingMethod: AllEntities
eventGroupingSettings:
aggregationKind: AlertPerResult
entityMappings:
- entityType: MailMessage
fieldMappings:
- identifier: Sender
columnName: SenderEnvelope
- identifier: Recipient
columnName: Recipients
- identifier: Subject
columnName: Subject
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
MimecastCG
Stage 2: where
| where Type == "email_ttp_url"
Stage 3: extend
| extend SenderEnvelope = ['Sender Envelope']
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Type | eq |
| field:"Type" kind:eq value:"email_ttp_url" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
SenderEnvelope | extend |
Mimecast Secure Email Gateway - URL Protect
#Detect threat when potentially malicious url found
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Rule Body
id: ea19dae6-bbb3-4444-a1b8-8e9ae6064aab
name: Mimecast Secure Email Gateway - URL Protect
description: Detect threat when potentially malicious url found
severity: High
requiredDataConnectors:
- connectorId: MimecastSIEMAPI
dataTypes:
- MimecastSIEM_CL
enabled: true
query: MimecastSIEM_CL| where mimecastEventId_s=="mail_ttp_url" and reason_s != "clean"
queryFrequency: 5m
queryPeriod: 15m
triggerOperator: gt
triggerThreshold: 0
suppressionDuration: 5h
suppressionEnabled: false
tactics:
- InitialAccess
- Discovery
- Execution
relevantTechniques:
- T1566
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: 1d
matchingMethod: AllEntities
eventGroupingSettings:
aggregationKind: SingleAlert
customDetails:
senderDomain: senderDomain_s
credentialTheft: credentialTheft_s
urlCategory: urlCategory_s
action: action_s
url: url_s
MsgId_s: msgid_s
route: route_s
SourceIP: SourceIP
reason: reason_s
entityMappings:
- entityType: MailMessage
fieldMappings:
- identifier: Sender
columnName: sender_s
- identifier: Recipient
columnName: recipient_s
- identifier: Subject
columnName: subject_s
version: 1.0.1
kind: Scheduled
Stages and Predicates
Stage 1: source
MimecastSIEM_CL
Stage 2: where
| where mimecastEventId_s=="mail_ttp_url" and reason_s != "clean"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
mimecastEventId_s | eq |
| field:"mimecastEventId_s" kind:eq value:"mail_ttp_url" |
reason_s | ne |
| field:"reason_s" kind:ne value:"clean" |
Rubrik Critical Anomaly
#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.
'Rubrik Critical Anomaly rule matches Severity and if Critical severity found then generate the incident for each object.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Rule Body
id: 54c70d21-696f-4f03-9238-9d7118d079fe
name: Rubrik Critical Anomaly
version: 1.0.0
kind: Scheduled
description: |
'Rubrik Critical Anomaly rule matches Severity and if Critical severity found then generate the incident for each object.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: RubrikSecurityCloudAzureFunctions
dataTypes:
- RubrikAnomalyData
queryFrequency: 10m
queryPeriod: 10m
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
relevantTechniques:
- T1546
query: |
Rubrik_Anomaly_Data_CL
| where severity_s == "critical"
eventGroupingSettings:
aggregationKind: AlertPerResult
customDetails:
ClusterIdentifier: custom_details_clusterId_g
ObjectId: custom_details_objectId_g
ObjectName: custom_details_objectName_s
ObjectType: custom_details_objectType_s
ClusterName: custom_details_clusterName_s
incidentConfiguration:
createIncident: true
Stages and Predicates
Stage 1: source
Rubrik_Anomaly_Data_CL
Stage 2: where
| where severity_s == "critical"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
severity_s | eq |
| field:"okta::severity" kind:eq value:"critical" |
Service Provider Deleted
#Detects when a service provider is deleted from Veeam Backup & Replication. This might indicate unauthorized removal of critical components.
Rule Body
id: cbe9fcb2-8767-4965-887e-350710145386
name: Service Provider Deleted
description: Detects when a service provider is deleted from Veeam Backup & Replication.
This might indicate unauthorized removal of critical components.
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 == 27600\n| project\n Date\
\ = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),\n DataSource = original_host,\n\
\ EventId = instanceId,\n [\"User Name\"] = user,\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 == 27600
Stage 3: project
| project
Date = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),
DataSource = original_host,
EventId = instanceId,
["User Name"] = user,
MessageDetails = Description,
Severity = SeverityDescription
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
instanceId | eq |
| field:"instanceId" kind:eq value:"27600" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DataSource | project |
Date | project |
EventId | project |
MessageDetails | project |
Severity | project |
User Name | project |
StealthTalk - Multi new devices registration
#Identifies a single StealthTalk user registering two or more previously-unseen devices within a 24-hour window. Sudden registration of multiple new devices is a strong indicator of account takeover (an attacker enrolling their own device after credential theft) or device-farm abuse. The rule fires when a user produces two or more distinct NewDeviceId values within the lookback window, regardless of operating system. Look at the OSList custom detail to spot cross-platform patterns (e.g. an iOS-only user suddenly enrolling an Android device).
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence | |
| Stealth |
Rule Body
id: f9d4c2a8-1b6e-4a3f-9c7d-8e2b1a3c5d7e
name: StealthTalk - Multi new devices registration
description: |
Identifies a single StealthTalk user registering two or more previously-unseen devices within
a 24-hour window. Sudden registration of multiple new devices is a strong indicator of
account takeover (an attacker enrolling their own device after credential theft) or
device-farm abuse.
The rule fires when a user produces two or more distinct NewDeviceId values within the
lookback window, regardless of operating system. Look at the OSList custom detail to spot
cross-platform patterns (e.g. an iOS-only user suddenly enrolling an Android device).
severity: Medium
requiredDataConnectors:
- connectorId: StealthTalkAnomalousAuth
dataTypes:
- StealthTalkAnomalousAuth_CL
queryFrequency: 30m
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
- Persistence
- InitialAccess
- DefenseEvasion
relevantTechniques:
- T1078
- T1098
query: |
let LookbackPeriod = 24h;
let MinNewDevices = 2;
StealthTalkAnomalousAuth_CL
| where TimeGenerated >= ago(LookbackPeriod)
| where EventType == "NewDeviceLogin"
| summarize
NewDeviceCount = dcount(NewDeviceId),
NewDevices = make_set(NewDeviceId),
NewDeviceOSList = make_set(NewDeviceOS),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated),
AppVersions = make_set(AppVersion)
by UserId
| where NewDeviceCount >= MinNewDevices
| extend
AlertName = "MultiNewDevicesRegistration",
AlertDetails = strcat(
"User ", UserId,
" registered ", NewDeviceCount, " new devices within 24 hours.",
" Device IDs: ", tostring(NewDevices), ".",
" Operating systems: ", tostring(NewDeviceOSList), "."
)
| project
TimeGenerated = LastSeen,
UserId, NewDeviceCount, NewDevices, NewDeviceOSList,
FirstSeen, LastSeen, AppVersions, AlertName, AlertDetails
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: UserId
customDetails:
NewDeviceCount: NewDeviceCount
NewDevices: NewDevices
NewDeviceOSList: NewDeviceOSList
FirstSeen: FirstSeen
LastSeen: LastSeen
alertDetailsOverride:
alertDisplayNameFormat: 'StealthTalk: Multi New Devices - {{UserId}} ({{NewDeviceCount}} new devices)'
alertDescriptionFormat: '{{AlertDetails}}'
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: 5h
matchingMethod: Selected
groupByEntities:
- Account
suppressionEnabled: false
suppressionDuration: 5h
version: 1.0.0
kind: Scheduled
Stages and Predicates
Parameters
let LookbackPeriod = 24h;
let MinNewDevices = 2;
Stage 1: source
StealthTalkAnomalousAuth_CL
Stage 2: where
| where TimeGenerated >= ago(LookbackPeriod)
Stage 3: where
| where EventType == "NewDeviceLogin"
Stage 4: summarize
| summarize
NewDeviceCount = dcount(NewDeviceId),
NewDevices = make_set(NewDeviceId),
NewDeviceOSList = make_set(NewDeviceOS),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated),
AppVersions = make_set(AppVersion)
by UserId
Stage 5: where
| where NewDeviceCount >= MinNewDevices
Stage 6: extend
| extend
AlertName = "MultiNewDevicesRegistration",
AlertDetails = strcat(
"User ", UserId,
" registered ", NewDeviceCount, " new devices within 24 hours.",
" Device IDs: ", tostring(NewDevices), ".",
" Operating systems: ", tostring(NewDeviceOSList), "."
)
Stage 7: project
| project
TimeGenerated = LastSeen,
UserId, NewDeviceCount, NewDevices, NewDeviceOSList,
FirstSeen, LastSeen, AppVersions, AlertName, AlertDetails
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
EventType | eq |
| field:"EventType" kind:eq value:"NewDeviceLogin" |
NewDeviceCount | ge |
| field:"NewDeviceCount" kind:ge value:"2" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AlertDetails | project |
AlertName | project |
AppVersions | project |
FirstSeen | project |
LastSeen | project |
NewDeviceCount | project |
NewDeviceOSList | project |
NewDevices | project |
TimeGenerated | project |
UserId | project |
SureBackup Job Failed
#Detects failed SureBackup job operations. This might indicate malware issues, storage problems, or potential sabotage of backup infrastructure.
Rule Body
id: b7409bbb-6f0c-43c4-bb63-b20add5eb717
name: SureBackup Job Failed
description: Detects failed SureBackup job operations. This might indicate malware
issues, storage problems, or potential sabotage of backup infrastructure.
severity: High
status: Available
requiredDataConnectors:
- connectorId: Syslog
dataTypes:
- Syslog
- connectorId: SyslogAma
dataTypes:
- Syslog
queryFrequency: 3h
queryPeriod: 3h
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics: []
relevantTechniques: []
query: "Veeam_GetJobFinished\n| where instanceId == 390\n| project\n Date = format_datetime(TimeGenerated,\
\ 'dd.MM.yyyy HH:mm'),\n DataSource = original_host,\n EventId = instanceId,\n\
\ [\"StateMessage\"] = JobTypeDescription,\n [\"State\"] = JobResultMessage,\n\
\ Severity = Severity,\n MessageDetails = Description"
version: 1.0.1
kind: Scheduled
customDetails:
Date: Date
VbrHostName: DataSource
EventId: EventId
MessageDetails: MessageDetails
Severity: Severity
Stages and Predicates
Stage 1: source
Veeam_GetJobFinished
Stage 2: where
| where instanceId == 390
Stage 3: project
| project
Date = format_datetime(TimeGenerated, 'dd.MM.yyyy HH:mm'),
DataSource = original_host,
EventId = instanceId,
["StateMessage"] = JobTypeDescription,
["State"] = JobResultMessage,
Severity = Severity,
MessageDetails = Description
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
instanceId | eq |
| field:"instanceId" kind:eq value:"390" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DataSource | project |
Date | project |
EventId | project |
MessageDetails | project |
Severity | project |
State | project |
StateMessage | project |
Tenable.ad Indicators of Attack
#'Searches for triggered Indicators of Attack.'
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule Body
id: 6405329a-8d20-48f3-aabc-e1b8a745568e
name: Tenable.ad Indicators of Attack
description: |
'Searches for triggered Indicators of Attack.'
severity: Low
requiredDataConnectors:
- connectorId: Tenable.ad
dataTypes:
- Tenable_ad_CL
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1110
query: |
// For the query to work properly, make sure you have imported the afad_parser.kql parser into the workspace
// Retrieve the parser here: https://raw.githubusercontent.com/tenable/Azure-Sentinel/Tenable.ad-connector/Solutions/TenableAD/Parsers/afad_parser.kql
// Then, create the Kusto Function with alias afad_parser
let SeverityTable=datatable(Severity:string,Level:int) [
"low", 1,
"medium", 2,
"high", 3,
"critical", 4
];
afad_parser
| where MessageType == 2
| lookup kind=leftouter SeverityTable on Severity
| order by Level
| extend HostName = tostring(split(Host, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Host, '.'), 1, -1), '.'))
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: HostName
- identifier: DnsDomain
columnName: DnsDomain
version: 1.0.1
kind: Scheduled
Stages and Predicates
Let Binding: SeverityTable
let SeverityTable = datatable(Severity:string,Level:int) [
"low", 1,
"medium", 2,
"high", 3,
"critical", 4
];
Stage 1: source
afad_parser
Stage 2: where
| where MessageType == 2
Stage 3: kusto:lookup
lookup kind=leftouter (SeverityTable) on Severity
Stage 4: sort
sort by Level
Stage 5: extend
extend DnsDomain, HostName
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
MessageType | eq |
| field:"MessageType" kind:eq value:"2" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
DnsDomain | extend |
HostName | extend |
Threat Essentials - User Assigned Privileged Role
#Identifies when a new privileged role is assigned to a user. Any account eligible for a role is now being given privileged access. If the assignment is unexpected or into a role that isn't the responsibility of the account holder, investigate. Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-privileged-accounts#things-to-monitor-1
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | any: Entra ID audit event (any operation) |
Rules Detecting the Same Action
These rules filter on the same operation.
- [Entra ID] Application Assigned Administrator Permissions Immediately After Obtaining Role Management Permissions (Kusto)
- [Entra ID] Mass Privileged Role Change Activity Detected (Kusto)
- [Entra ID] Privilege Elevation Request Denied (Kusto)
- [Entra ID] Privileged Role Assigned to a New User (Kusto)
- [Entra ID] Privileged Role Assigned to User (Kusto)
- Account Elevated to New Role (Kusto)
- Admin promotion after Role Management Application Permission Grant (Kusto)
- App Assigned To Azure RBAC/Microsoft Entra Role (Sigma)
Rule Body
id: b09795c9-8dce-47ab-8f75-5a4afb78ef0c
name: Threat Essentials - User Assigned Privileged Role
description: |
'Identifies when a new privileged role is assigned to a user. Any account eligible for a role is now being given privileged access. If the assignment is unexpected or into a role that isn't the responsibility of the account holder, investigate.
Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-privileged-accounts#things-to-monitor-1'
severity: High
status: Available
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Persistence
relevantTechniques:
- T1078.004
tags:
- AADSecOpsGuide
query: |
AuditLogs
| where Category =~ "RoleManagement"
| where AADOperationType in~ ("Assign", "AssignEligibleRole")
| where ActivityDisplayName has_any ("Add eligible member to role", "Add member to role")
| mv-expand TargetResources
| mv-expand TargetResources.modifiedProperties
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
| where displayName_ =~ "Role.DisplayName"
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue)))
| where RoleName contains "Admin"
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
| extend Target = tostring(TargetResources.userPrincipalName)
| summarize by bin(TimeGenerated, 1h), OperationName, RoleName, Target, Initiator, Result
| extend InitiatorName=split(Initiator, "@")[0], InitiatorUPNSuffix=split(Initiator, "@")[1]
| extend TargetName=split(Target, "@")[0], TargetUPNSuffix=split(Target, "@")[1]
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: InitiatorName
- identifier: UPNSuffix
columnName: InitiatorUPNSuffix
- entityType: Account
fieldMappings:
- identifier: Name
columnName: TargetName
- identifier: UPNSuffix
columnName: TargetUPNSuffix
version: 1.0.3
kind: Scheduled
Stages and Predicates
Stage 1: source
AuditLogs
Stage 2: where
| where Category =~ "RoleManagement"
Stage 3: where
| where AADOperationType in~ ("Assign", "AssignEligibleRole")
Stage 4: where
| where ActivityDisplayName has_any ("Add eligible member to role", "Add member to role")
Stage 5: mv-expand
| mv-expand TargetResources
Stage 6: mv-expand
| mv-expand TargetResources.modifiedProperties
Stage 7: extend
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
Stage 8: where
| where displayName_ =~ "Role.DisplayName"
Stage 9: extend
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue)))
Stage 10: where
| where RoleName contains "Admin"
Stage 11: extend (3 consecutive steps)
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
| extend Target = tostring(TargetResources.userPrincipalName)
Stage 12: summarize
| summarize by bin(TimeGenerated, 1h), OperationName, RoleName, Target, Initiator, Result
Stage 13: extend
| extend InitiatorName=split(Initiator, "@")[0], InitiatorUPNSuffix=split(Initiator, "@")[1]
Stage 14: extend
| extend TargetName=split(Target, "@")[0], TargetUPNSuffix=split(Target, "@")[1]
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
AADOperationType | in |
| field:"AADOperationType" kind:in |
ActivityDisplayName | match |
| field:"azure_ad::activity_display_name" kind:match |
Category | eq |
| field:"Category" kind:eq value:"RoleManagement" |
RoleName | contains |
| field:"RoleName" kind:contains value:"Admin" |
displayName_ | eq |
| field:"displayName_" kind:eq value:"Role.DisplayName" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Initiator | summarize |
OperationName | summarize |
Result | summarize |
RoleName | summarize |
Target | summarize |
InitiatorName | extend |
InitiatorUPNSuffix | extend |
TargetName | extend |
TargetUPNSuffix | extend |
TI map Email entity to EmailEvents
#Identifies a match in EmailEvents table from any Email IOC from TI
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Microsoft Defender for Endpoint | EmailEvents action any: Email processed |
Rule Body
id: 11f7c6e3-f066-4b3c-9a81-b487ec0a6873
name: TI map Email entity to EmailEvents
description: |
'Identifies a match in EmailEvents table from any Email IOC from TI'
severity: Medium
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- EmailEvents
- connectorId: ThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
dataTypes:
- ThreatIntelligenceIndicator
- connectorId: MicrosoftDefenderThreatIntelligence
dataTypes:
- ThreatIntelligenceIndicator
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let EmailEvents_ = materialize(EmailEvents | where isnotempty(RecipientEmailAddress) and isnotempty(SenderFromAddress) and TimeGenerated >= ago(dt_lookBack) and DeliveryAction !has "Blocked" | project-rename EmailEvents_TimeGenerated = TimeGenerated | extend SenderFromAddress = tolower(SenderFromAddress) | extend RecipientEmailAddress = tolower(RecipientEmailAddress));
let SenderAddresses = EmailEvents_ | distinct SenderFromAddress | summarize make_list(SenderFromAddress);
let RecipientAddresses = EmailEvents_ | distinct RecipientEmailAddress | summarize make_list(RecipientEmailAddress);
let TI = materialize(ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack)
| where isnotempty(EmailSenderAddress)
| extend TI_EmailAddress = tolower(EmailSenderAddress)
| where TI_EmailAddress in (SenderAddresses) or TI_EmailAddress in (RecipientAddresses)
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true and ExpirationDateTime > now());
(union
(TI | join kind=innerunique (EmailEvents_) on $left.TI_EmailAddress == $right.SenderFromAddress),
(TI | join kind=innerunique (EmailEvents_) on $left.TI_EmailAddress == $right.RecipientEmailAddress))
| where EmailEvents_TimeGenerated < ExpirationDateTime
| summarize EmailEvents_TimeGenerated = arg_max(EmailEvents_TimeGenerated, *) by IndicatorId, TI_EmailAddress
| project EmailEvents_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DomainName, RecipientEmailAddress, SenderFromAddress, Subject, ConfidenceLevel, Url, Type, TI_EmailAddress, TrafficLightProtocolLevel, DeliveryAction, DeliveryLocation, EmailDirection
| extend Name = tostring(split(RecipientEmailAddress, '@', 0)[0]), UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0])
| extend timestamp = EmailEvents_TimeGenerated
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: RecipientEmailAddress
- identifier: Name
columnName: Name
- identifier: UPNSuffix
columnName: UPNSuffix
version: 1.0.2
kind: Scheduled
Stages and Predicates
Parameters
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
Let Binding: EmailEvents_
let EmailEvents_ = materialize(EmailEvents | where isnotempty(RecipientEmailAddress) and isnotempty(SenderFromAddress) and TimeGenerated >= ago(dt_lookBack) and DeliveryAction !has "Blocked" | project-rename EmailEvents_TimeGenerated = TimeGenerated | extend SenderFromAddress = tolower(SenderFromAddress) | extend RecipientEmailAddress = tolower(RecipientEmailAddress));
Let Binding: SenderAddresses
let SenderAddresses = EmailEvents_ | distinct SenderFromAddress | summarize make_list(SenderFromAddress);
Let Binding: RecipientAddresses
let RecipientAddresses = EmailEvents_ | distinct RecipientEmailAddress | summarize make_list(RecipientEmailAddress);
Union (2 Sources)
Each leg below queries one source; the rule matches if any leg does. Sources: TI, TI
Leg 1: TI
TI | join kind=innerunique (EmailEvents_) on $left.TI_EmailAddress == $right.SenderFromAddress
Leg 2: TI
TI | join kind=innerunique (EmailEvents_) on $left.TI_EmailAddress == $right.RecipientEmailAddress
Applied to the Combined Result
| where EmailEvents_TimeGenerated < ExpirationDateTime
| summarize EmailEvents_TimeGenerated = arg_max(EmailEvents_TimeGenerated, *) by IndicatorId, TI_EmailAddress
| project EmailEvents_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DomainName, RecipientEmailAddress, SenderFromAddress, Subject, ConfidenceLevel, Url, Type, TI_EmailAddress, TrafficLightProtocolLevel, DeliveryAction, DeliveryLocation, EmailDirection
| extend Name = tostring(split(RecipientEmailAddress, '@', 0)[0]), UPNSuffix = tostring(split(RecipientEmailAddress, '@', 1)[0])
| extend timestamp = EmailEvents_TimeGenerated
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Active | eq |
| field:"Active" kind:eq value:"true" |
EmailSenderAddress | is_not_null | field:"EmailSenderAddress" kind:is_not_null | |
RecipientEmailAddress | is_not_null | field:"RecipientEmailAddress" kind:is_not_null | |
SenderFromAddress | is_not_null | field:"SenderFromAddress" kind:is_not_null | |
TI_EmailAddress | in |
| field:"TI_EmailAddress" kind:in |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
DeliveryAction | match | Blocked | excludes:DeliveryAction field:"DeliveryAction" value:"Blocked" |
Output Fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ActivityGroupNames | project |
ConfidenceLevel | project |
ConfidenceScore | project |
DeliveryAction | project |
DeliveryLocation | project |
Description | project |
DomainName | project |
EmailDirection | project |
EmailEvents_TimeGenerated | project |
ExpirationDateTime | project |
IndicatorId | project |
RecipientEmailAddress | project |
SenderFromAddress | project |
Subject | project |
TI_EmailAddress | project |
ThreatType | project |
TrafficLightProtocolLevel | project |
Type | project |
Url | project |
Name | extend |
UPNSuffix | extend |
timestamp | extend |
Veeam ONE Computer with No Backup
#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.
Detects computers with no backup.
Rule Body
id: c0ead324-d8e8-484d-b590-9639f5ac5d93
name: Veeam ONE Computer with No Backup
description: Detects computers with no backup.
severity: High
status: Available
requiredDataConnectors:
- connectorId: VeeamCustomTablesDataConnector
dataTypes:
- VeeamOneTriggeredAlarms_CL
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics: []
relevantTechniques: []
query: VeeamOneTriggeredAlarms_CL | where PredefinedAlarmId == 370
version: 1.0.1
kind: Scheduled
customDetails:
PredefinedAlarmId: PredefinedAlarmId
TriggeredAlarmId: TriggeredAlarmId
Description: Description
Name: Name
VoneHostName: VoneHostName
TriggeredTime: TriggeredTime
Status: Status
Comment: Comment
ObjectId: ObjectId
ObjectName: ObjectName
ObjectType: ObjectType
Stages and Predicates
Stage 1: source
VeeamOneTriggeredAlarms_CL
Stage 2: where
| where PredefinedAlarmId == 370
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
PredefinedAlarmId | eq |
| field:"PredefinedAlarmId" kind:eq value:"370" |
Veeam ONE Immutability Change Tracking
#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.
Detects changes in Veeam ONE immutability tracking configuration.
Rule Body
id: 21ef1e12-75ac-43be-a77e-d2cee4c69225
name: Veeam ONE Immutability Change Tracking
description: Detects changes in Veeam ONE immutability tracking configuration.
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: VeeamCustomTablesDataConnector
dataTypes:
- VeeamOneTriggeredAlarms_CL
queryFrequency: 3h
queryPeriod: 3h
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics: []
relevantTechniques: []
query: VeeamOneTriggeredAlarms_CL | where PredefinedAlarmId == 377
version: 1.0.1
kind: Scheduled
customDetails:
PredefinedAlarmId: PredefinedAlarmId
TriggeredAlarmId: TriggeredAlarmId
Description: Description
Name: Name
VoneHostName: VoneHostName
TriggeredTime: TriggeredTime
Status: Status
Comment: Comment
ObjectId: ObjectId
ObjectName: ObjectName
ObjectType: ObjectType
Stages and Predicates
Stage 1: source
VeeamOneTriggeredAlarms_CL
Stage 2: where
| where PredefinedAlarmId == 377
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
PredefinedAlarmId | eq |
| field:"PredefinedAlarmId" kind:eq value:"377" |
Veeam ONE VM with No Backup (Hyper-V)
#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.
Detects Veeam ONE VMs with no backup (Hyper-V).
Rule Body
id: ae880194-5766-46d3-a17b-c8c53e9ca96c
name: Veeam ONE VM with No Backup (Hyper-V)
description: Detects Veeam ONE VMs with no backup (Hyper-V).
severity: High
status: Available
requiredDataConnectors:
- connectorId: VeeamCustomTablesDataConnector
dataTypes:
- VeeamOneTriggeredAlarms_CL
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics: []
relevantTechniques: []
query: VeeamOneTriggeredAlarms_CL | where PredefinedAlarmId == 315
version: 1.0.1
kind: Scheduled
customDetails:
PredefinedAlarmId: PredefinedAlarmId
TriggeredAlarmId: TriggeredAlarmId
Description: Description
Name: Name
VoneHostName: VoneHostName
TriggeredTime: TriggeredTime
Status: Status
Comment: Comment
ObjectId: ObjectId
ObjectName: ObjectName
ObjectType: ObjectType
Stages and Predicates
Stage 1: source
VeeamOneTriggeredAlarms_CL
Stage 2: where
| where PredefinedAlarmId == 315
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
PredefinedAlarmId | eq |
| field:"PredefinedAlarmId" kind:eq value:"315" |
VMware Cloud Web Security - Web Access Policy Violation
#VMware Cloud Web Security reported access events which were violating web access policy rules. Additional investigation might be required.
Rule Body
id: b84a1f62-ad30-4ae1-8b21-3d304d8aa818
name: VMware Cloud Web Security - Web Access Policy Violation
version: 1.0.0
kind: Scheduled
description: VMware Cloud Web Security reported access events which were violating web access policy rules. Additional investigation might be required.
severity: Medium
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
requiredDataConnectors:
- connectorId: VMwareSDWAN
dataTypes:
- CWS
query: |
VMware_CWS_Weblogs_CL
| where action == "block"
suppressionEnabled: false
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: 5h
matchingMethod: AllEntities
groupByEntities: []
groupByAlertDetails: []
groupByCustomDetails: []
eventGroupingSettings:
aggregationKind: AlertPerResult
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: sourceIp
- entityType: Malware
fieldMappings:
- identifier: Name
columnName: virusList
- entityType: URL
fieldMappings:
- identifier: Url
columnName: url
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: userId
suppressionDuration: 5h
Stages and Predicates
Stage 1: source
VMware_CWS_Weblogs_CL
Stage 2: where
| where action == "block"
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
action | eq |
| field:"action" kind:eq value:"block" |