Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

GSA Enriched Office 365 - User made Owner of multiple teams

Back
Id558f15dd-3171-4b11-bf24-31c0610a20e0
RulenameGSA Enriched Office 365 - User made Owner of multiple teams
DescriptionThis hunting query identifies users who have been made Owner of multiple Teams.
TacticsPrivilegeEscalation
TechniquesT1078
Required data connectorsAzureActiveDirectory
KindScheduled
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Hunting Queries/MultiTeamOwner.yaml
Version2.0.2
Arm template558f15dd-3171-4b11-bf24-31c0610a20e0.json
Deploy To Azure
let max_owner_count = 3;  
// Adjust this value to change how many teams a user is made owner of before detecting
// OfficeActivity Query: Identify users who have been made owners of more than 'max_owner_count' teams
let high_owner_count_office = (
    OfficeActivity
    | where OfficeWorkload =~ "MicrosoftTeams"
    | where Operation =~ "MemberRoleChanged"
    | extend Member = tostring(parse_json(Members)[0].UPN) 
    | extend NewRole = toint(parse_json(Members)[0].Role)
    | where NewRole == 2  // Role 2 corresponds to "Owner"
    | summarize TeamCount = dcount(TeamName) by Member
    | where TeamCount > max_owner_count
    | project Member
);
// OfficeActivity Query: Fetch details for users with high ownership count
let OfficeEvents = OfficeActivity
    | where OfficeWorkload =~ "MicrosoftTeams"
    | where Operation =~ "MemberRoleChanged"
    | extend Member = tostring(parse_json(Members)[0].UPN)
    | extend NewRole = toint(parse_json(Members)[0].Role)
    | where NewRole == 2  // Role 2 corresponds to "Owner"
    | where Member in (high_owner_count_office)
    | extend AccountName = tostring(split(Member, "@")[0]), AccountUPNSuffix = tostring(split(Member, "@")[1]);
// EnrichedMicrosoft365AuditLogs Query: Identify users who have been made owners of more than 'max_owner_count' teams
let high_owner_count_enriched = (
    EnrichedMicrosoft365AuditLogs
    | where Workload == "MicrosoftTeams"
    | where Operation == "MemberRoleChanged"
    | extend Member = tostring(UserId)
    | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)
    | where NewRole == 2  // Role 2 corresponds to "Owner"
    | summarize TeamCount = dcount(ObjectId) by Member
    | where TeamCount > max_owner_count
    | project Member
);
// EnrichedMicrosoft365AuditLogs Query: Fetch details for users with high ownership count
let EnrichedEvents = EnrichedMicrosoft365AuditLogs
    | where Workload == "MicrosoftTeams"
    | where Operation == "MemberRoleChanged"
    | extend Member = tostring(UserId)
    | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)
    | where NewRole == 2  // Role 2 corresponds to "Owner"
    | where Member in (high_owner_count_enriched)
    | extend AccountName = tostring(split(Member, "@")[0]), AccountUPNSuffix = tostring(split(Member, "@")[1]);
// Combine Office and Enriched Logs
let CombinedEvents = OfficeEvents
    | union EnrichedEvents
    | summarize by Member, AccountName, AccountUPNSuffix;
// Final Output
CombinedEvents
| order by Member asc
| project Member, AccountName, AccountUPNSuffix
version: 2.0.2
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
  entityType: Account
kind: Scheduled
relevantTechniques:
- T1078
tactics:
- PrivilegeEscalation
query: |
  let max_owner_count = 3;  
  // Adjust this value to change how many teams a user is made owner of before detecting
  // OfficeActivity Query: Identify users who have been made owners of more than 'max_owner_count' teams
  let high_owner_count_office = (
      OfficeActivity
      | where OfficeWorkload =~ "MicrosoftTeams"
      | where Operation =~ "MemberRoleChanged"
      | extend Member = tostring(parse_json(Members)[0].UPN) 
      | extend NewRole = toint(parse_json(Members)[0].Role)
      | where NewRole == 2  // Role 2 corresponds to "Owner"
      | summarize TeamCount = dcount(TeamName) by Member
      | where TeamCount > max_owner_count
      | project Member
  );
  // OfficeActivity Query: Fetch details for users with high ownership count
  let OfficeEvents = OfficeActivity
      | where OfficeWorkload =~ "MicrosoftTeams"
      | where Operation =~ "MemberRoleChanged"
      | extend Member = tostring(parse_json(Members)[0].UPN)
      | extend NewRole = toint(parse_json(Members)[0].Role)
      | where NewRole == 2  // Role 2 corresponds to "Owner"
      | where Member in (high_owner_count_office)
      | extend AccountName = tostring(split(Member, "@")[0]), AccountUPNSuffix = tostring(split(Member, "@")[1]);
  // EnrichedMicrosoft365AuditLogs Query: Identify users who have been made owners of more than 'max_owner_count' teams
  let high_owner_count_enriched = (
      EnrichedMicrosoft365AuditLogs
      | where Workload == "MicrosoftTeams"
      | where Operation == "MemberRoleChanged"
      | extend Member = tostring(UserId)
      | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)
      | where NewRole == 2  // Role 2 corresponds to "Owner"
      | summarize TeamCount = dcount(ObjectId) by Member
      | where TeamCount > max_owner_count
      | project Member
  );
  // EnrichedMicrosoft365AuditLogs Query: Fetch details for users with high ownership count
  let EnrichedEvents = EnrichedMicrosoft365AuditLogs
      | where Workload == "MicrosoftTeams"
      | where Operation == "MemberRoleChanged"
      | extend Member = tostring(UserId)
      | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)
      | where NewRole == 2  // Role 2 corresponds to "Owner"
      | where Member in (high_owner_count_enriched)
      | extend AccountName = tostring(split(Member, "@")[0]), AccountUPNSuffix = tostring(split(Member, "@")[1]);
  // Combine Office and Enriched Logs
  let CombinedEvents = OfficeEvents
      | union EnrichedEvents
      | summarize by Member, AccountName, AccountUPNSuffix;
  // Final Output
  CombinedEvents
  | order by Member asc
  | project Member, AccountName, AccountUPNSuffix  
id: 558f15dd-3171-4b11-bf24-31c0610a20e0
requiredDataConnectors:
- dataTypes:
  - EnrichedMicrosoft365AuditLogs
  connectorId: AzureActiveDirectory
name: GSA Enriched Office 365 - User made Owner of multiple teams
description: |
    This hunting query identifies users who have been made Owner of multiple Teams.
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Hunting Queries/MultiTeamOwner.yaml
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/558f15dd-3171-4b11-bf24-31c0610a20e0')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/558f15dd-3171-4b11-bf24-31c0610a20e0')]",
      "properties": {
        "alertRuleTemplateName": "558f15dd-3171-4b11-bf24-31c0610a20e0",
        "customDetails": null,
        "description": "This hunting query identifies users who have been made Owner of multiple Teams.\n",
        "displayName": "GSA Enriched Office 365 - User made Owner of multiple teams",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Hunting Queries/MultiTeamOwner.yaml",
        "query": "let max_owner_count = 3;  \n// Adjust this value to change how many teams a user is made owner of before detecting\n// OfficeActivity Query: Identify users who have been made owners of more than 'max_owner_count' teams\nlet high_owner_count_office = (\n    OfficeActivity\n    | where OfficeWorkload =~ \"MicrosoftTeams\"\n    | where Operation =~ \"MemberRoleChanged\"\n    | extend Member = tostring(parse_json(Members)[0].UPN) \n    | extend NewRole = toint(parse_json(Members)[0].Role)\n    | where NewRole == 2  // Role 2 corresponds to \"Owner\"\n    | summarize TeamCount = dcount(TeamName) by Member\n    | where TeamCount > max_owner_count\n    | project Member\n);\n// OfficeActivity Query: Fetch details for users with high ownership count\nlet OfficeEvents = OfficeActivity\n    | where OfficeWorkload =~ \"MicrosoftTeams\"\n    | where Operation =~ \"MemberRoleChanged\"\n    | extend Member = tostring(parse_json(Members)[0].UPN)\n    | extend NewRole = toint(parse_json(Members)[0].Role)\n    | where NewRole == 2  // Role 2 corresponds to \"Owner\"\n    | where Member in (high_owner_count_office)\n    | extend AccountName = tostring(split(Member, \"@\")[0]), AccountUPNSuffix = tostring(split(Member, \"@\")[1]);\n// EnrichedMicrosoft365AuditLogs Query: Identify users who have been made owners of more than 'max_owner_count' teams\nlet high_owner_count_enriched = (\n    EnrichedMicrosoft365AuditLogs\n    | where Workload == \"MicrosoftTeams\"\n    | where Operation == \"MemberRoleChanged\"\n    | extend Member = tostring(UserId)\n    | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)\n    | where NewRole == 2  // Role 2 corresponds to \"Owner\"\n    | summarize TeamCount = dcount(ObjectId) by Member\n    | where TeamCount > max_owner_count\n    | project Member\n);\n// EnrichedMicrosoft365AuditLogs Query: Fetch details for users with high ownership count\nlet EnrichedEvents = EnrichedMicrosoft365AuditLogs\n    | where Workload == \"MicrosoftTeams\"\n    | where Operation == \"MemberRoleChanged\"\n    | extend Member = tostring(UserId)\n    | extend NewRole = toint(parse_json(tostring(AdditionalProperties)).Role)\n    | where NewRole == 2  // Role 2 corresponds to \"Owner\"\n    | where Member in (high_owner_count_enriched)\n    | extend AccountName = tostring(split(Member, \"@\")[0]), AccountUPNSuffix = tostring(split(Member, \"@\")[1]);\n// Combine Office and Enriched Logs\nlet CombinedEvents = OfficeEvents\n    | union EnrichedEvents\n    | summarize by Member, AccountName, AccountUPNSuffix;\n// Final Output\nCombinedEvents\n| order by Member asc\n| project Member, AccountName, AccountUPNSuffix\n",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "PrivilegeEscalation"
        ],
        "techniques": [
          "T1078"
        ],
        "templateVersion": "2.0.2"
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}