Detection rules › Kusto

High severity malicious activity detected

Status
available
Severity
high
Time window
1d
Group by
SourceIp, ThreatCategory
Source
github.com/Azure/Azure-Sentinel

Identifies high severity malicious activity in Azure Firewall IDPS logs.

MITRE ATT&CK coverage

Rule body kusto

id: 504257c1-81e2-4609-8d40-b395e62f11c7
name: High severity malicious activity detected
description: |
  Identifies high severity malicious activity in Azure Firewall IDPS logs.
severity: High
status: Available
requiredDataConnectors:
  - connectorId: AzureFirewall
    dataTypes:
      - AZFWIdpsSignature
queryFrequency: 1h
queryPeriod: 24h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
  - Exfiltration
  - CredentialAccess
  - CommandAndControl
  - Execution
relevantTechniques:
  - T1190
  - T1041
  - T1003
  - T1204
query: |
  let TimeWindow   = 90d;    // How far back to look 
  let HitThreshold = 10;     // Minimum hits to alert per SourceIp + Category
  let MinSeverity  = 1;      // Set Minimum Severity
  let EnableCategoryFilter    = true;   // Filter 1: use CategoriesOfInterest
  let EnableDescriptionFilter = false;  // Filter 2: use DescriptionsOfInterest
  let EnableActionFilter      = false;  // Filter 3: use MatchActions
  let CategoriesOfInterest    = dynamic([
      "Targeted Malicious Activity was Detected",
      "Exploit Kit Activity Detected",
      "Domain Observed Used for C2 Detected",
      "Successful Credential Theft Detected",
      "Malware Command and Control Activity Detected",
      "Executable code was detected",
      "A Network Trojan was detected"
  ]);
  let DescriptionsOfInterest  = dynamic([
      "targeted-activity",
      "exploit-kit",
      "domain-c2",
      "credential-theft",
      "command-and-control",
      "shellcode-detect",
      "trojan-activity"
  ]);
  let MatchActions = dynamic(["Deny", "alert"]);
  AZFWIdpsSignature
  | where TimeGenerated >= ago(TimeWindow)
  | where Severity >= MinSeverity
  // Filter 1: Category filter (optional)
  | where (EnableCategoryFilter == false) or (Category has_any (CategoriesOfInterest))
  // Filter 2: Description filter (optional)
  | where (EnableDescriptionFilter == false) or (Description has_any (DescriptionsOfInterest))
  // Filter 3: Action filter (optional)
  | where (EnableActionFilter == false) or (Action in~ (MatchActions))
  | summarize
      StartTime   = min(TimeGenerated),
      EndTime     = max(TimeGenerated),
      TotalHits   = count(),
      MaxSeverity = max(Severity),
      Actions     = make_set(Action, 5),
      Signatures  = make_set(SignatureId, 20),
      Description = make_set(substring(tostring(Description), 0, 120), 3)
      by SourceIp, ThreatCategory = Category
  | where TotalHits >= HitThreshold
  | project
      StartTime,
      EndTime,
      SourceIp,
      ThreatCategory,
      TotalHits,
      MaxSeverity,
      Actions,
      Signatures,
      Description
  | order by MaxSeverity desc, TotalHits desc
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SourceIp
version: 1.0.1
kind: Scheduled

Stages and Predicates

Parameters

let TimeWindow = 90d;
let HitThreshold = 10;
let MinSeverity = 1;
let EnableCategoryFilter = true;
let EnableDescriptionFilter = false;
let EnableActionFilter = false;
let MatchActions = dynamic(["Deny", "alert"]);

Let binding: CategoriesOfInterest

let CategoriesOfInterest = dynamic([
    "Targeted Malicious Activity was Detected",
    "Exploit Kit Activity Detected",
    "Domain Observed Used for C2 Detected",
    "Successful Credential Theft Detected",
    "Malware Command and Control Activity Detected",
    "Executable code was detected",
    "A Network Trojan was detected"
]);

Let binding: DescriptionsOfInterest

let DescriptionsOfInterest = dynamic([
    "targeted-activity",
    "exploit-kit",
    "domain-c2",
    "credential-theft",
    "command-and-control",
    "shellcode-detect",
    "trojan-activity"
]);

Stage 1: source

AZFWIdpsSignature

Stage 2: where

| where TimeGenerated >= ago(TimeWindow)

Stage 3: where

| where Severity >= MinSeverity

Stage 4: where

| where (EnableCategoryFilter == false) or (Category has_any (CategoriesOfInterest))

References CategoriesOfInterest (defined above).

Stage 5: where

| where (EnableDescriptionFilter == false) or (Description has_any (DescriptionsOfInterest))

References DescriptionsOfInterest (defined above).

Stage 6: where

| where (EnableActionFilter == false) or (Action in~ (MatchActions))

Stage 7: summarize

| summarize
    StartTime   = min(TimeGenerated),
    EndTime     = max(TimeGenerated),
    TotalHits   = count(),
    MaxSeverity = max(Severity),
    Actions     = make_set(Action, 5),
    Signatures  = make_set(SignatureId, 20),
    Description = make_set(substring(tostring(Description), 0, 120), 3)
    by SourceIp, ThreatCategory = Category
Threshold
ge 10

Stage 8: where

| where TotalHits >= HitThreshold

Stage 9: project

| project
    StartTime,
    EndTime,
    SourceIp,
    ThreatCategory,
    TotalHits,
    MaxSeverity,
    Actions,
    Signatures,
    Description

Stage 10: sort

| order by MaxSeverity desc, TotalHits desc

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
Actionin
  • Deny
  • alert
Categorymatch
  • A Network Trojan was detected
  • Domain Observed Used for C2 Detected
  • Executable code was detected
  • Exploit Kit Activity Detected
  • Malware Command and Control Activity Detected
  • Successful Credential Theft Detected
  • Targeted Malicious Activity was Detected
Descriptionmatch
  • command-and-control
  • credential-theft
  • domain-c2
  • exploit-kit
  • shellcode-detect
  • targeted-activity
  • trojan-activity
Severityge
  • 1 transforms: cased
TotalHitsge
  • 10 transforms: cased

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
Actionsproject
Descriptionproject
EndTimeproject
MaxSeverityproject
Signaturesproject
SourceIpproject
StartTimeproject
ThreatCategoryproject
TotalHitsproject