Detection rules › Kusto
Vectra AI Detect - Detections with High Severity
'Create an incident for high severity malicious behavior detected by Vectra AI (Threat score superior to 7.0). The Severity is a mapping with the Threat score assigned to a detection. It ranges between 0 and 10. The severity_threshold variable can be adjusted as desired.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access | |
| Discovery | |
| Lateral Movement | |
| Collection | |
| Command & Control | |
| Exfiltration | |
| Impact |
Rule body
id: 39e48890-2c02-487e-aa9e-3ba494061798
name: Vectra AI Detect - Detections with High Severity
description: |
'Create an incident for high severity malicious behavior detected by Vectra AI (Threat score superior to 7.0).
The Severity is a mapping with the Threat score assigned to a detection. It ranges between 0 and 10.
The severity_threshold variable can be adjusted as desired.'
severity: High
status: Available
requiredDataConnectors:
- connectorId: CefAma
dataTypes:
- CommonSecurityLog
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
eventGroupingSettings:
aggregationKind: AlertPerResult
tactics:
- CredentialAccess
- Discovery
- LateralMovement
- Collection
- CommandAndControl
- Exfiltration
- Impact
relevantTechniques:
- T1003
- T1087
- T1021
- T1119
- T1071
- T1041
- T1499
query: |
// Edit this variable to only keep the tactics where an incident needs to be created (Defaults are: "COMMAND & CONTROL", "BOTNET ACTIVITY", "EXFILTRATION", "LATERAL MOVEMENT", "RECONNAISSANCE")
let configured_tactics = dynamic(["COMMAND & CONTROL", "BOTNET ACTIVITY", "EXFILTRATION", "LATERAL MOVEMENT", "RECONNAISSANCE"]);
//default threshold is 7 (meaning a threat score of 70)
let severity_threshold = 7.0;
//Map by default to High Severity in Sentinel
let Severity = "High";
CommonSecurityLog
| where DeviceVendor == "Vectra Networks"
| where DeviceProduct == "X Series"
| where DeviceEventClassID != "campaigns" and DeviceEventClassID != "hsc" and DeviceEventClassID != "audit" and DeviceEventClassID != "health" and DeviceEventClassID != "asc"
| extend Category = coalesce(
column_ifexists("DeviceEventCategory", ""),
extract("cat=(.+?)(;|$)", 1, AdditionalExtensions),
""
)
| project-rename threat_score = FlexNumber1
| project-rename certainty_score = FlexNumber2
| project-rename vectra_URL = DeviceCustomString4
| project-rename detection_name = DeviceEventClassID
| where todecimal(LogSeverity) >= severity_threshold
| extend Tactic = case( Category == "COMMAND & CONTROL", "CommandAndControl",
Category == "BOTNET ACTIVITY" , "Impact",
Category == "EXFILTRATION", "Exfiltration",
Category == "LATERAL MOVEMENT", "LateralMovement",
Category == "RECONNAISSANCE", "Discovery",
"UNKNOWN")
| extend level = case(threat_score == 0 and certainty_score == 0, "Info",
threat_score < 50 and certainty_score < 50, "Low",
threat_score < 50 and certainty_score >= 50, "Medium",
threat_score >= 50 and certainty_score <= 50, "High",
threat_score >= 50 and certainty_score >= 50, "Critical",
"UNKNOWN")
| extend Severity = case(level == "Info", "Informational",level == "Critical", "High", level)
| extend account = extract("account=(.+?);", 1, AdditionalExtensions)
| extend upn = iff(account matches regex ":", tostring(split(account,":")[1]) ,tostring(split(account,":")[0]))
| extend name = tostring(split(upn, "@")[0])
| extend upn_suffix = tostring(split(upn, "@")[1])
| extend source_entity = case( isnotempty(upn), upn,
isnotempty(SourceHostName), SourceHostName,
"UNKNWON")
| where Category in (configured_tactics)
| summarize arg_max(threat_score, *) by source_entity, Activity
| sort by TimeGenerated
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: SourceHostName
- entityType: Account
fieldMappings:
- identifier: Name
columnName: name
- identifier: UPNSuffix
columnName: upn_suffix
alertDetailsOverride:
alertDisplayNameFormat: Vectra AI Detect - {{Activity}} detected
alertDescriptionFormat: Source entity is {{source_entity}} and category is {{Category}}. Threat score is {{threat_score}}.
alertSeverityColumnName: Severity
alertDynamicProperties:
- alertProperty: AlertLink
value: vectra_URL
- alertProperty: ProductName
value: DeviceProduct
- alertProperty: ProviderName
value: DeviceVendor
- alertProperty: ConfidenceScore
value: certainty_score
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: true
lookbackDuration: 7d
matchingMethod: AllEntities
customDetails:
AttackType: Activity
AttackCategory: Category
version: 1.1.0
kind: Scheduled
Stages and Predicates
Parameters
let configured_tactics = dynamic(["COMMAND & CONTROL", "BOTNET ACTIVITY", "EXFILTRATION", "LATERAL MOVEMENT", "RECONNAISSANCE"]);
let severity_threshold = 7.0;
let Severity = "High";
Stage 1: source
CommonSecurityLog
Stage 2: where
| where DeviceVendor == "Vectra Networks"
Stage 3: where
| where DeviceProduct == "X Series"
Stage 4: where
| where DeviceEventClassID != "campaigns" and DeviceEventClassID != "hsc" and DeviceEventClassID != "audit" and DeviceEventClassID != "health" and DeviceEventClassID != "asc"
Stage 5: extend
| extend Category = coalesce(
column_ifexists("DeviceEventCategory", ""),
extract("cat=(.+?)(;|$)", 1, AdditionalExtensions),
""
)
Stage 6: project-rename
| project-rename threat_score = FlexNumber1
Stage 7: project-rename
| project-rename certainty_score = FlexNumber2
Stage 8: project-rename
| project-rename vectra_URL = DeviceCustomString4
Stage 9: project-rename
| project-rename detection_name = DeviceEventClassID
Stage 10: where
| where todecimal(LogSeverity) >= severity_threshold
Stage 11: extend (8 consecutive steps)
| extend Tactic = case( Category == "COMMAND & CONTROL", "CommandAndControl",
Category == "BOTNET ACTIVITY" , "Impact",
Category == "EXFILTRATION", "Exfiltration",
Category == "LATERAL MOVEMENT", "LateralMovement",
Category == "RECONNAISSANCE", "Discovery",
"UNKNOWN")
| extend level = case(threat_score == 0 and certainty_score == 0, "Info",
threat_score < 50 and certainty_score < 50, "Low",
threat_score < 50 and certainty_score >= 50, "Medium",
threat_score >= 50 and certainty_score <= 50, "High",
threat_score >= 50 and certainty_score >= 50, "Critical",
"UNKNOWN")
| extend Severity = case(level == "Info", "Informational",level == "Critical", "High", level)
| extend account = extract("account=(.+?);", 1, AdditionalExtensions)
| extend upn = iff(account matches regex ":", tostring(split(account,":")[1]) ,tostring(split(account,":")[0]))
| extend name = tostring(split(upn, "@")[0])
| extend upn_suffix = tostring(split(upn, "@")[1])
| extend source_entity = case( isnotempty(upn), upn,
isnotempty(SourceHostName), SourceHostName,
"UNKNWON")
Tactic =if
Category == "COMMAND & CONTROL""CommandAndControl"elif
Category == "BOTNET ACTIVITY""Impact"elif
Category == "EXFILTRATION""Exfiltration"elif
Category == "LATERAL MOVEMENT""LateralMovement"elif
Category == "RECONNAISSANCE""Discovery"else
"UNKNOWN"Stage 12: where
| where Category in (configured_tactics)
Stage 13: summarize
| summarize arg_max(threat_score, *) by source_entity, Activity
Stage 14: sort
| sort by TimeGenerated
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Category | in |
| field:"Category" kind:in |
DeviceEventClassID | ne |
| field:"DeviceEventClassID" kind:ne |
DeviceProduct | eq |
| field:"DeviceProduct" kind:eq value:"X Series" |
DeviceVendor | eq |
| field:"DeviceVendor" kind:eq value:"Vectra Networks" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Activity | summarize |
source_entity | summarize |