Detection rules › Kusto

Detect threat information in web requests (ASIM Web Session)

Status
available
Severity
high
Time window
5m
Group by
DstIpAddr, SrcHostname, SrcIpAddr, SrcUsername, ThreatCategory, ThreatField, ThreatName, ThreatOriginalConfidence, ThreatRiskLevel, Url
Source
github.com/Azure/Azure-Sentinel

'This rule would generate an alert if EvenSeverity is 'High' or 'ThreatRiskLevel' or 'ThreatOriginalConfidence' value is greater than 90.

MITRE ATT&CK coverage

Rule body kusto

id: 7d2ed1c7-da26-45fd-b4ea-b6f2bbeccea7
name: Detect threat information in web requests (ASIM Web Session)
description: |
  'This rule would generate an alert if EvenSeverity is 'High' or 'ThreatRiskLevel' or 'ThreatOriginalConfidence' value is greater than 90.
severity: High
status: Available 
tags:
  - Schema: WebSession
    SchemaVersion: 0.2.6
requiredDataConnectors: []
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
relevantTechniques:
  - T1190
  - T1133
query: |
  let lookback= 5m;
  _Im_WebSession(starttime=ago(lookback))
  | project
      EventSeverity,
      ThreatName,
      ThreatCategory,
      ThreatRiskLevel,
      ThreatOriginalConfidence,
      ThreatField,
      TimeGenerated,
      SrcIpAddr,
      SrcUsername,
      SrcHostname,
      Url,
      DstIpAddr
  | where ThreatRiskLevel >= 90
      or toint(ThreatOriginalConfidence) >= 90
      or EventSeverity =~ "High"
  | summarize
      EventCount = count(),
      EventStartTime=min(TimeGenerated),
      EvenEndTime=max(TimeGenerated)
      by
      SrcIpAddr,
      SrcUsername,
      SrcHostname,
      Url,
      DstIpAddr,
      ThreatName,
      ThreatCategory,
      ThreatRiskLevel,
      ThreatOriginalConfidence,
      ThreatField
  | extend
      Name = iif(SrcUsername contains "@", tostring(split(SrcUsername, '@', 0)[0]), SrcUsername),
      UPNSuffix = iif(SrcUsername contains "@", tostring(split(SrcUsername, '@', 1)[0]), "")
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: SrcHostname
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SrcIpAddr
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: DstIpAddr
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: Name
      - identifier: UPNSuffix
        columnName: UPNSuffix
  - entityType: URL
    fieldMappings:
      - identifier: Url
        columnName: Url
eventGroupingSettings:
  aggregationKind: AlertPerResult
customDetails:
  ThreatCategory: ThreatCategory
  ThreatConfidence: ThreatOriginalConfidence
  ThreatName: ThreatName
  EventStartTime: EventStartTime
  EvenEndTime: EvenEndTime
  EventCount: EventCount
alertDetailsOverride:
  alertDisplayNameFormat: "User '{{SrcUsername}}' with IP address '{{SrcIpAddr}}' has been identified as being associated with a threat named '{{ThreatName}}'"
version: 1.0.0
kind: Scheduled

Stages and Predicates

Parameters

let lookback = 5m;

Stage 1: source

_Im_WebSession(starttime=ago(lookback))

Stage 2: project

| project
    EventSeverity,
    ThreatName,
    ThreatCategory,
    ThreatRiskLevel,
    ThreatOriginalConfidence,
    ThreatField,
    TimeGenerated,
    SrcIpAddr,
    SrcUsername,
    SrcHostname,
    Url,
    DstIpAddr

Stage 3: where

| where ThreatRiskLevel >= 90
    or toint(ThreatOriginalConfidence) >= 90
    or EventSeverity =~ "High"

Stage 4: summarize

| summarize
    EventCount = count(),
    EventStartTime=min(TimeGenerated),
    EvenEndTime=max(TimeGenerated)
    by
    SrcIpAddr,
    SrcUsername,
    SrcHostname,
    Url,
    DstIpAddr,
    ThreatName,
    ThreatCategory,
    ThreatRiskLevel,
    ThreatOriginalConfidence,
    ThreatField

Stage 5: extend

| extend
    Name = iif(SrcUsername contains "@", tostring(split(SrcUsername, '@', 0)[0]), SrcUsername),
    UPNSuffix = iif(SrcUsername contains "@", tostring(split(SrcUsername, '@', 1)[0]), "")

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
EventSeverityeq
  • High
ThreatOriginalConfidencege
  • 90 transforms: toint, cased
ThreatRiskLevelge
  • 90 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
DstIpAddrsummarize
EvenEndTimesummarize
EventCountsummarize
EventStartTimesummarize
SrcHostnamesummarize
SrcIpAddrsummarize
SrcUsernamesummarize
ThreatCategorysummarize
ThreatFieldsummarize
ThreatNamesummarize
ThreatOriginalConfidencesummarize
ThreatRiskLevelsummarize
Urlsummarize
Nameextend
UPNSuffixextend