Detection rules › Kusto
Multiple Teams deleted by a single user
This detection flags the occurrences of deleting multiple teams within an hour. This data is a part of Office 365 Connector in Microsoft Sentinel.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Impact | T1485 Data Destruction, T1489 Service Stop |
Event coverage
| Provider | Event |
|---|---|
| M365-MicrosoftTeams | TeamDeleted |
Rule body kusto
id: 173f8699-6af5-484a-8b06-8c47ba89b380
name: Multiple Teams deleted by a single user
description: |
'This detection flags the occurrences of deleting multiple teams within an hour.
This data is a part of Office 365 Connector in Microsoft Sentinel.'
severity: Low
status: Available
requiredDataConnectors:
- connectorId: Office365
dataTypes:
- OfficeActivity (Teams)
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Impact
relevantTechniques:
- T1485
- T1489
query: |
// Adjust this value to change how many Teams should be deleted before including
let max_delete_count = 3;
// Adjust this value to change the timewindow the query runs over
OfficeActivity
| where OfficeWorkload =~ "MicrosoftTeams"
| where Operation =~ "TeamDeleted"
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DeletedTeams = make_set(TeamName, 1000) by UserId
| where array_length(DeletedTeams) > max_delete_count
| extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserId
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
version: 2.0.4
kind: Scheduled
Stages and Predicates
Parameters
let max_delete_count = 3;
Stage 1: source
OfficeActivity
Stage 2: where
| where OfficeWorkload =~ "MicrosoftTeams"
Stage 3: where
| where Operation =~ "TeamDeleted"
Stage 4: summarize
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), DeletedTeams = make_set(TeamName, 1000) by UserId
Stage 5: where
| where array_length(DeletedTeams) > max_delete_count
Stage 6: extend
| extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1])
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.
| Field | Kind | Values |
|---|---|---|
DeletedTeams | gt |
|
OfficeWorkload | eq |
|
Operation | eq |
|
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.
| Field | Source |
|---|---|
DeletedTeams | summarize |
EndTime | summarize |
StartTime | summarize |
UserId | summarize |
AccountName | extend |
AccountUPNSuffix | extend |