Detection rules › Kusto

F&O - Mass update or deletion of user records

Status
available
Severity
medium
Time window
1h
Group by
LogType, TableName, Username
Source
github.com/Azure/Azure-Sentinel

Identifies large delete or update operations on Finance & Operations user records based on predefined thresholds.

MITRE ATT&CK coverage

Rule body kusto

id: 5ab00fbb-ba2c-44dc-b02e-f119639b9a11
kind: Scheduled
name: F&O - Mass update or deletion of user records
description: Identifies large delete or update operations on Finance & Operations
  user records based on predefined thresholds.
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: Dynamics365Finance
    dataTypes:
      - FinanceOperationsActivity_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Impact
relevantTechniques:
  - T1485
  - T1565
  - T1491
query: |
  // Set threshold for number of updated or deleted records
  let update_detection_threshold = 50;
  let deleted_detection_threshold = 10;
  FinanceOperationsActivity_CL
  | where TableName == "UserInfo" and LogType in ("Update", "Delete")
  | summarize
      TotalEvents = count(),
      StartTime = min(LogCreatedDateTime),
      EndTime = max(LogCreatedDateTime)
      by TableName, Username, LogType
  | where (LogType == "Update" and TotalEvents > update_detection_threshold) or (LogType == "Delete" and TotalEvents > deleted_detection_threshold)
  | extend FinOpsAppId = 32780
  | project StartTime, EndTime, Username, LogType, TableName, TotalEvents, FinOpsAppId
eventGroupingSettings:
  aggregationKind: SingleAlert
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Username
  - entityType: CloudApplication
    fieldMappings:
      - identifier: AppId
        columnName: FinOpsAppId
alertDetailsOverride:
  alertDisplayNameFormat: F&O - many user account records deleted
  alertDescriptionFormat: '{{TotalEvents}} user records deleted in F&O by user {{Username}}'
version: 3.2.0

Stages and Predicates

Parameters

let update_detection_threshold = 50;
let deleted_detection_threshold = 10;

Stage 1: source

FinanceOperationsActivity_CL

Stage 2: where

| where TableName == "UserInfo" and LogType in ("Update", "Delete")

Stage 3: summarize

| summarize
    TotalEvents = count(),
    StartTime = min(LogCreatedDateTime),
    EndTime = max(LogCreatedDateTime)
    by TableName, Username, LogType

Stage 4: where

| where (LogType == "Update" and TotalEvents > update_detection_threshold) or (LogType == "Delete" and TotalEvents > deleted_detection_threshold)

Stage 5: extend

| extend FinOpsAppId = 32780

Stage 6: project

| project StartTime, EndTime, Username, LogType, TableName, TotalEvents, FinOpsAppId

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
LogTypeeq
  • Delete transforms: cased
  • Update transforms: cased
LogTypein
  • Delete transforms: cased
  • Update transforms: cased
TableNameeq
  • UserInfo transforms: cased
TotalEventsgt
  • 10 transforms: cased
  • 50 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
EndTimeproject
FinOpsAppIdproject
LogTypeproject
StartTimeproject
TableNameproject
TotalEventsproject
Usernameproject