Detection rules › Kusto

Tomcat - Server errors after multiple requests from same IP

Status
available
Severity
medium
Time window
1h
Group by
SrcIpAddr
Source
github.com/Azure/Azure-Sentinel

'Detects server errors after multiple requests from same IP address.'

MITRE ATT&CK coverage

Rule body

id: 875da588-4875-11ec-81d3-0242ac130003
name: Tomcat - Server errors after multiple requests from same IP
description: |
  'Detects server errors after multiple requests from same IP address.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: CustomLogsAma
    datatypes:
      - Tomcat_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Impact
  - InitialAccess
relevantTechniques:
  - T1498
  - T1190
  - T1133
query: |
  let multi_errors = TomcatEvent
  | where toint(HttpStatusCode) >= 500 and toint(HttpStatusCode) <= 599
  | sort by EventStartTime asc
  | summarize MultipleServerErrors = count() by SrcIpAddr, bin(EventStartTime, 5m)
  | where MultipleServerErrors > 10;
  let error_time_table = TomcatEvent
  | where toint(HttpStatusCode) >= 500 and toint(HttpStatusCode) <= 599
  | summarize error_time=min(EventStartTime) by SrcIpAddr
  | join kind=innerunique (multi_errors) on SrcIpAddr;
  TomcatEvent
  | where toint(HttpStatusCode) >= 100 and toint(HttpStatusCode) <= 399
  | summarize success_time=max(EventStartTime) by SrcIpAddr
  | join kind=innerunique (error_time_table) on SrcIpAddr
  | extend time_between_error_and_success = datetime_diff('second', error_time, success_time)
  | where time_between_error_and_success between (1 .. 300)
  | project time_between_error_and_success, error_time, success_time, SrcIpAddr
  | extend IPCustomEntity = SrcIpAddr
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPCustomEntity
version: 1.0.2
kind: Scheduled

Stages and Predicates

Let binding: multi_errors

let multi_errors = TomcatEvent
| where toint(HttpStatusCode) >= 500 and toint(HttpStatusCode) <= 599
| sort by EventStartTime asc
| summarize MultipleServerErrors = count() by SrcIpAddr, bin(EventStartTime, 5m)
| where MultipleServerErrors > 10;

Let binding: error_time_table used in Stage 4

let error_time_table = TomcatEvent
| where toint(HttpStatusCode) >= 500 and toint(HttpStatusCode) <= 599
| summarize error_time=min(EventStartTime) by SrcIpAddr
| join kind=innerunique (multi_errors) on SrcIpAddr;

Stage 1: source

TomcatEvent

Stage 2: where

| where toint(HttpStatusCode) >= 100 and toint(HttpStatusCode) <= 399

Stage 3: summarize

| summarize success_time=max(EventStartTime) by SrcIpAddr

Stage 4: join

| join kind=innerunique (error_time_table) on SrcIpAddr

Stage 5: extend

| extend time_between_error_and_success = datetime_diff('second', error_time, success_time)

Stage 6: where

| where time_between_error_and_success between (1 .. 300)

Stage 7: project

| project time_between_error_and_success, error_time, success_time, SrcIpAddr

Stage 8: extend

| extend IPCustomEntity = SrcIpAddr

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
SrcIpAddrproject
error_timeproject
success_timeproject
time_between_error_and_successproject
IPCustomEntityextend