Detection rules › Kusto

Box - User role changed to owner

Status
available
Severity
medium
Time window
14d
Group by
AccessibleByName, AdditionalDetailsRole, FileDirectory
Source
github.com/Azure/Azure-Sentinel

'Detects when user collaboration role is changed to owner.'

MITRE ATT&CK coverage

TacticTechniques
Privilege EscalationT1078 Valid Accounts

Rule body kusto

id: 174c31c9-22ec-42e5-8226-814391c08200
name: Box - User role changed to owner
description: |
  'Detects when user collaboration role is changed to owner.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: BoxDataConnector
    dataTypes:
      - BoxEvents_CL
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - PrivilegeEscalation
relevantTechniques:
  - T1078
query: |
  let lbperiod = 14d;
  let lbtime = 1h;
  BoxEvents
  | where EventEndTime between (ago(lbperiod) .. ago(lbtime))
  | where EventType =~ 'COLLABORATION_INVITE'
  | where AdditionalDetailsRole !~ 'Owner'
  | summarize min(EventEndTime) by AccessibleByName, FileDirectory, AdditionalDetailsRole
  | project AccessibleByName, FileDirectory, InitialRole = AdditionalDetailsRole
  |join (BoxEvents
            | where EventType =~ 'COLLABORATION_ROLE_CHANGE'
            | summarize max(EventEndTime) by AccessibleByName, FileDirectory, AdditionalDetailsRole
            | project AccessibleByName, FileDirectory, NewRole = AdditionalDetailsRole
            ) on FileDirectory, AccessibleByName
  | where NewRole =~ 'Owner'
  | project AccessibleByName, FileDirectory
  | extend AccountCustomEntity = AccessibleByName
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: AccountCustomEntity
version: 1.0.1
kind: Scheduled

Stages and Predicates

Parameters

let lbperiod = 14d;
let lbtime = 1h;

Stage 1: source

BoxEvents

Stage 2: where

| where EventEndTime between (ago(lbperiod) .. ago(lbtime))

Stage 3: where

| where EventType =~ 'COLLABORATION_INVITE'

Stage 4: where

| where AdditionalDetailsRole !~ 'Owner'

Stage 5: summarize

| summarize min(EventEndTime) by AccessibleByName, FileDirectory, AdditionalDetailsRole

Stage 6: project

| project AccessibleByName, FileDirectory, InitialRole = AdditionalDetailsRole

Stage 7: join

| join (BoxEvents
          | where EventType =~ 'COLLABORATION_ROLE_CHANGE'
          | summarize max(EventEndTime) by AccessibleByName, FileDirectory, AdditionalDetailsRole
          | project AccessibleByName, FileDirectory, NewRole = AdditionalDetailsRole
          ) on FileDirectory, AccessibleByName

Stage 8: where

| where NewRole =~ 'Owner'

Stage 9: project

| project AccessibleByName, FileDirectory

Stage 10: extend

| extend AccountCustomEntity = AccessibleByName

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
AdditionalDetailsRolene
  • Owner
EventTypeeq
  • COLLABORATION_INVITE
  • COLLABORATION_ROLE_CHANGE
NewRoleeq
  • Owner

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
AccessibleByNameproject
FileDirectoryproject
AccountCustomEntityextend