Detection rules › Kusto

Box - Abmormal user activity

Status
available
Severity
medium
Time window
14d
Group by
SourceName, SrcUserName, User, k
Source
github.com/Azure/Azure-Sentinel

'Detects spikes (deviations from avarage) in user activity.'

MITRE ATT&CK coverage

TacticTechniques
Collection

Rule body

id: 1139230c-cf10-45db-b616-fed0d1415c05
name: Box - Abmormal user activity
description: |
  'Detects spikes (deviations from avarage) in user activity.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: BoxDataConnector
    dataTypes:
      - BoxEvents_CL
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Collection
relevantTechniques:
  - T1530
query: |
  let lbperiod_start = 14d;
  let lbperiod_end = 24h;
  let user_actions_1 = BoxEvents
  | where EventEndTime between (ago(lbperiod_start) .. ago(lbperiod_end))
  | summarize TotalEvents = count() by SourceName
  | project TotalEvents, User = SourceName;
  let user_actions_2 = BoxEvents
  | where EventEndTime between (ago(lbperiod_start) .. ago(lbperiod_end))
  | summarize TotalEvents = count() by SrcUserName
  | project TotalEvents, User = SrcUserName;
  let TotalActions = (union user_actions_1, user_actions_2)
  | summarize TotalEvents = count() by User
  | extend EventsPerDay = TotalEvents / 29
  | extend k = 1;
  let actions1_last_h = BoxEvents
  | summarize TotalEventsH = count() by SourceName
  | project TotalEventsH, User = SourceName;
  let actions2_last_h = BoxEvents
  | summarize TotalEventsH = count() by SourceName
  | project TotalEventsH, User = SourceName;
  let TotalActionsLastHour = (union actions1_last_h, actions2_last_h)
  | summarize TotalEventsH = sum(TotalEventsH) by User
  | extend k = 1;
  TotalActions
  | join (TotalActionsLastHour) on k
  | where EventsPerDay > TotalEventsH
  | project User
  | extend AccountCustomEntity = User
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountCustomEntity
version: 1.0.1
kind: Scheduled

Stages and Predicates

Stage 0: let

let lbperiod_start = 14d;
let lbperiod_end = 24h;
let user_actions_1 = BoxEvents <inlined as stages below>;
let user_actions_2 = BoxEvents <inlined as stages below>;
let TotalActions = (union <inlined as stages below>;
let actions1_last_h = BoxEvents
| summarize TotalEventsH = count() by SourceName
| project TotalEventsH, User = SourceName;
let actions2_last_h = BoxEvents
| summarize TotalEventsH = count() by SourceName
| project TotalEventsH, User = SourceName;
let TotalActionsLastHour = (union actions1_last_h, actions2_last_h)
| summarize TotalEventsH = sum(TotalEventsH) by User
| extend k = 1;

Stage 1: union

union of 2 branches

Stage 2: source

BoxEvents

Stage 3: where

| where EventEndTime between (ago(lbperiod_start) .. ago(lbperiod_end))

Stage 4: summarize

| summarize TotalEvents = count() by SourceName

Stage 5: project

| project TotalEvents, User = SourceName

Stage 6: source

BoxEvents

Stage 7: where

| where EventEndTime between (ago(lbperiod_start) .. ago(lbperiod_end))

Stage 8: summarize

| summarize TotalEvents = count() by SrcUserName

Stage 9: project

| project TotalEvents, User = SrcUserName

Stage 10: summarize

summarize TotalEvents by User

Stage 11: extend

extend EventsPerDay

Stage 12: extend

extend k

Stage 13: join

join (TotalActionsLastHour) on k

Stage 14: where

where EventsPerDay > TotalEventsH

Stage 15: project

project User

Stage 16: extend

extend AccountCustomEntity

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventsPerDaycross_field_compare
  • TotalEventsH transforms: op:gt
field:"EventsPerDay" kind:cross_field_compare value:"TotalEventsH"

Output fields

These fields are emitted when the rule matches.

FieldSource
Userproject
AccountCustomEntityextend