Detection rules › Kusto

Detect instances of multiple server errors occurring within a brief period of time (ASIM Web Session)

Status
available
Severity
medium
Time window
5m
Group by
SrcHostname, SrcIpAddr, SrcUsername
Source
github.com/Azure/Azure-Sentinel

'This detection mechanism identifies situations where multiple server errors originate from a single source within a limited time frame.'

MITRE ATT&CK coverage

Rule body kusto

id: a59ba76c-0205-4966-948e-3d5640140688
name: Detect instances of multiple server errors occurring within a brief period of time (ASIM Web Session)
description: |
  'This detection mechanism identifies situations where multiple server errors originate from a single source within a limited time frame.'
severity: Medium
status: Available 
tags:
  - Schema: WebSession
    SchemaVersion: 0.2.6
requiredDataConnectors: []
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
  - Impact
relevantTechniques:
  - T1190
  - T1133
  - T1498
query: |
  // HTTP response status codes indicate whether a specific HTTP request has been successfully completed.
  // Please refer this for more details: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
  let threshold = 100; // You can update threshold value as per your environment
  _Im_WebSession(starttime=ago(1h))
  | where toint(EventResultDetails) between (500 .. 599)
  | summarize
      TotalErrorCount = count(),
      URLs=make_set(Url, 100),
      EventStartTime = min(TimeGenerated),
      EventEndTime = max(TimeGenerated),
      EventResultDetailsSet=make_set(EventResultDetails,10)
      by SrcIpAddr, bin(TimeGenerated, 5m), SrcUsername, SrcHostname
  | where TotalErrorCount > threshold
  | extend
      Name = iif(SrcUsername contains "@", tostring(split(SrcUsername, '@', 0)[0]), SrcUsername),
      UPNSuffix = iif(SrcUsername contains "@", tostring(split(SrcUsername, '@', 1)[0]), ""), Threshold=threshold
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SrcIpAddr
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: Name
      - identifier: UPNSuffix
        columnName: UPNSuffix
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: SrcHostname
eventGroupingSettings:
  aggregationKind: AlertPerResult
customDetails:
  TotalErrorCount: TotalErrorCount
  RequestURLs: URLs
  ErrorThreshold: Threshold
  EventResultSet: EventResultDetailsSet
  EventStartTime: EventStartTime
  EventEndTime: EventEndTime
alertDetailsOverride:
  alertDisplayNameFormat: "High number of server errors originated by user '{{SrcUsername}}' from IP address '{{SrcIpAddr}}'"
  alertDescriptionFormat: "The client has made a total of '{{TotalErrorCount}}' requests to URLs '{{URLs}}', 
                            which have resulted in server errors. It is recommended to thoroughly investigate this alert to determine the underlying cause behind this 
                            significant number of errors. For detailed information regarding the specific errors encountered, please refer to the following link:
                            https://developer.mozilla.org/en-US/docs/Web/HTTP/Status."
version: 1.0.0
kind: Scheduled

Stages and Predicates

Parameters

let threshold = 100;

Stage 1: source

_Im_WebSession(starttime=ago(1h))

Stage 2: where

| where toint(EventResultDetails) between (500 .. 599)

Stage 3: summarize

| summarize
    TotalErrorCount = count(),
    URLs=make_set(Url, 100),
    EventStartTime = min(TimeGenerated),
    EventEndTime = max(TimeGenerated),
    EventResultDetailsSet=make_set(EventResultDetails,10)
    by SrcIpAddr, bin(TimeGenerated, 5m), SrcUsername, SrcHostname
Threshold
gt 100

Stage 4: where

| where TotalErrorCount > threshold

Stage 5: extend

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

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
TotalErrorCountgt
  • 100 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
EventEndTimesummarize
EventResultDetailsSetsummarize
EventStartTimesummarize
SrcHostnamesummarize
SrcIpAddrsummarize
SrcUsernamesummarize
TotalErrorCountsummarize
URLssummarize
Nameextend
Thresholdextend
UPNSuffixextend