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

Office 365 - Accessed files shared by temporary external user

Back
Id4d38f80f-6b7d-4a1f-aeaf-e38df637e6ac
RulenameOffice 365 - Accessed files shared by temporary external user
DescriptionThis detection identifies when an external user is added to a Team or Teams chat and shares a file which is accessed by many users (>10) and the users is removed within short period of time. This might be an indicator of suspicious activity.
SeverityLow
TacticsInitialAccess
TechniquesT1566
Required data connectorsAzureActiveDirectory
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - External User added to Team and immediately uploads file.yaml
Version2.1.2
Arm template4d38f80f-6b7d-4a1f-aeaf-e38df637e6ac.json
Deploy To Azure
let fileAccessThreshold = 10;
EnrichedMicrosoft365AuditLogs
| where Workload =~ "MicrosoftTeams"
| where Operation =~ "MemberAdded"
| extend MemberAdded = tostring(parse_json(tostring(AdditionalProperties)).Members[0].UPN)
| where MemberAdded contains "#EXT#"
| project TimeAdded = TimeGenerated, Operation, MemberAdded, UserWhoAdded = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
| join kind=inner (
    EnrichedMicrosoft365AuditLogs
    | where Workload =~ "MicrosoftTeams"
    | where Operation =~ "MemberRemoved"
    | extend MemberAdded = tostring(parse_json(tostring(AdditionalProperties)).Members[0].UPN)
    | where MemberAdded contains "#EXT#"
    | project TimeDeleted = TimeGenerated, Operation, MemberAdded, UserWhoDeleted = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
) on MemberAdded, TeamName
| where TimeDeleted > TimeAdded
| join kind=inner (
    EnrichedMicrosoft365AuditLogs
    | where RecordType == "SharePointFileOperation"
    | where Operation == "FileUploaded"
    | extend MemberAdded = UserId, SourceRelativeUrl = tostring(parse_json(tostring(AdditionalProperties)).SourceRelativeUrl), TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
    | where SourceRelativeUrl has "Microsoft Teams Chat Files"
    | join kind=inner (
        EnrichedMicrosoft365AuditLogs
        | where RecordType == "SharePointFileOperation"
        | where Operation == "FileAccessed"
        | extend SourceRelativeUrl = tostring(parse_json(tostring(AdditionalProperties)).SourceRelativeUrl), TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
        | where SourceRelativeUrl has "Microsoft Teams Chat Files"
        | summarize FileAccessCount = count() by ObjectId, TeamName
        | where FileAccessCount > fileAccessThreshold
    ) on ObjectId, TeamName
) on MemberAdded, TeamName
| project-away MemberAdded1, MemberAdded2, ObjectId1, Operation1, Operation2
| extend MemberAddedAccountName = tostring(split(MemberAdded, "@")[0]), MemberAddedAccountUPNSuffix = tostring(split(MemberAdded, "@")[1])
| extend UserWhoAddedAccountName = tostring(split(UserWhoAdded, "@")[0]), UserWhoAddedAccountUPNSuffix = tostring(split(UserWhoAdded, "@")[1])
| extend UserWhoDeletedAccountName = tostring(split(UserWhoDeleted, "@")[0]), UserWhoDeletedAccountUPNSuffix = tostring(split(UserWhoDeleted, "@")[1])
queryPeriod: 1h
version: 2.1.2
tactics:
- InitialAccess
queryFrequency: 1h
id: 4d38f80f-6b7d-4a1f-aeaf-e38df637e6ac
triggerOperator: gt
requiredDataConnectors:
- dataTypes:
  - EnrichedMicrosoft365AuditLogs
  connectorId: AzureActiveDirectory
severity: Low
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: MemberAdded
    identifier: FullName
  - columnName: MemberAddedAccountName
    identifier: Name
  - columnName: MemberAddedAccountUPNSuffix
    identifier: UPNSuffix
- entityType: Account
  fieldMappings:
  - columnName: UserWhoAdded
    identifier: FullName
  - columnName: UserWhoAddedAccountName
    identifier: Name
  - columnName: UserWhoAddedAccountUPNSuffix
    identifier: UPNSuffix
- entityType: Account
  fieldMappings:
  - columnName: UserWhoDeleted
    identifier: FullName
  - columnName: UserWhoDeletedAccountName
    identifier: Name
  - columnName: UserWhoDeletedAccountUPNSuffix
    identifier: UPNSuffix
- entityType: IP
  fieldMappings:
  - columnName: ClientIP
    identifier: Address
triggerThreshold: 0
relevantTechniques:
- T1566
query: |
  let fileAccessThreshold = 10;
  EnrichedMicrosoft365AuditLogs
  | where Workload =~ "MicrosoftTeams"
  | where Operation =~ "MemberAdded"
  | extend MemberAdded = tostring(parse_json(tostring(AdditionalProperties)).Members[0].UPN)
  | where MemberAdded contains "#EXT#"
  | project TimeAdded = TimeGenerated, Operation, MemberAdded, UserWhoAdded = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
  | join kind=inner (
      EnrichedMicrosoft365AuditLogs
      | where Workload =~ "MicrosoftTeams"
      | where Operation =~ "MemberRemoved"
      | extend MemberAdded = tostring(parse_json(tostring(AdditionalProperties)).Members[0].UPN)
      | where MemberAdded contains "#EXT#"
      | project TimeDeleted = TimeGenerated, Operation, MemberAdded, UserWhoDeleted = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
  ) on MemberAdded, TeamName
  | where TimeDeleted > TimeAdded
  | join kind=inner (
      EnrichedMicrosoft365AuditLogs
      | where RecordType == "SharePointFileOperation"
      | where Operation == "FileUploaded"
      | extend MemberAdded = UserId, SourceRelativeUrl = tostring(parse_json(tostring(AdditionalProperties)).SourceRelativeUrl), TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
      | where SourceRelativeUrl has "Microsoft Teams Chat Files"
      | join kind=inner (
          EnrichedMicrosoft365AuditLogs
          | where RecordType == "SharePointFileOperation"
          | where Operation == "FileAccessed"
          | extend SourceRelativeUrl = tostring(parse_json(tostring(AdditionalProperties)).SourceRelativeUrl), TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)
          | where SourceRelativeUrl has "Microsoft Teams Chat Files"
          | summarize FileAccessCount = count() by ObjectId, TeamName
          | where FileAccessCount > fileAccessThreshold
      ) on ObjectId, TeamName
  ) on MemberAdded, TeamName
  | project-away MemberAdded1, MemberAdded2, ObjectId1, Operation1, Operation2
  | extend MemberAddedAccountName = tostring(split(MemberAdded, "@")[0]), MemberAddedAccountUPNSuffix = tostring(split(MemberAdded, "@")[1])
  | extend UserWhoAddedAccountName = tostring(split(UserWhoAdded, "@")[0]), UserWhoAddedAccountUPNSuffix = tostring(split(UserWhoAdded, "@")[1])
  | extend UserWhoDeletedAccountName = tostring(split(UserWhoDeleted, "@")[0]), UserWhoDeletedAccountUPNSuffix = tostring(split(UserWhoDeleted, "@")[1])  
kind: Scheduled
name: Office 365 - Accessed files shared by temporary external user
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - External User added to Team and immediately uploads file.yaml
description: |
    'This detection identifies when an external user is added to a Team or Teams chat and shares a file which is accessed by many users (>10) and the users is removed within short period of time. This might be an indicator of suspicious activity.'
status: Available
{
  "$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/4d38f80f-6b7d-4a1f-aeaf-e38df637e6ac')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/4d38f80f-6b7d-4a1f-aeaf-e38df637e6ac')]",
      "properties": {
        "alertRuleTemplateName": "4d38f80f-6b7d-4a1f-aeaf-e38df637e6ac",
        "customDetails": null,
        "description": "'This detection identifies when an external user is added to a Team or Teams chat and shares a file which is accessed by many users (>10) and the users is removed within short period of time. This might be an indicator of suspicious activity.'\n",
        "displayName": "Office 365 - Accessed files shared by temporary external user",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "MemberAdded",
                "identifier": "FullName"
              },
              {
                "columnName": "MemberAddedAccountName",
                "identifier": "Name"
              },
              {
                "columnName": "MemberAddedAccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserWhoAdded",
                "identifier": "FullName"
              },
              {
                "columnName": "UserWhoAddedAccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UserWhoAddedAccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserWhoDeleted",
                "identifier": "FullName"
              },
              {
                "columnName": "UserWhoDeletedAccountName",
                "identifier": "Name"
              },
              {
                "columnName": "UserWhoDeletedAccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "ClientIP",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - External User added to Team and immediately uploads file.yaml",
        "query": "let fileAccessThreshold = 10;\nEnrichedMicrosoft365AuditLogs\n| where Workload =~ \"MicrosoftTeams\"\n| where Operation =~ \"MemberAdded\"\n| extend MemberAdded = tostring(parse_json(tostring(AdditionalProperties)).Members[0].UPN)\n| where MemberAdded contains \"#EXT#\"\n| project TimeAdded = TimeGenerated, Operation, MemberAdded, UserWhoAdded = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)\n| join kind=inner (\n    EnrichedMicrosoft365AuditLogs\n    | where Workload =~ \"MicrosoftTeams\"\n    | where Operation =~ \"MemberRemoved\"\n    | extend MemberAdded = tostring(parse_json(tostring(AdditionalProperties)).Members[0].UPN)\n    | where MemberAdded contains \"#EXT#\"\n    | project TimeDeleted = TimeGenerated, Operation, MemberAdded, UserWhoDeleted = UserId, TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)\n) on MemberAdded, TeamName\n| where TimeDeleted > TimeAdded\n| join kind=inner (\n    EnrichedMicrosoft365AuditLogs\n    | where RecordType == \"SharePointFileOperation\"\n    | where Operation == \"FileUploaded\"\n    | extend MemberAdded = UserId, SourceRelativeUrl = tostring(parse_json(tostring(AdditionalProperties)).SourceRelativeUrl), TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)\n    | where SourceRelativeUrl has \"Microsoft Teams Chat Files\"\n    | join kind=inner (\n        EnrichedMicrosoft365AuditLogs\n        | where RecordType == \"SharePointFileOperation\"\n        | where Operation == \"FileAccessed\"\n        | extend SourceRelativeUrl = tostring(parse_json(tostring(AdditionalProperties)).SourceRelativeUrl), TeamName = tostring(parse_json(tostring(AdditionalProperties)).TeamName)\n        | where SourceRelativeUrl has \"Microsoft Teams Chat Files\"\n        | summarize FileAccessCount = count() by ObjectId, TeamName\n        | where FileAccessCount > fileAccessThreshold\n    ) on ObjectId, TeamName\n) on MemberAdded, TeamName\n| project-away MemberAdded1, MemberAdded2, ObjectId1, Operation1, Operation2\n| extend MemberAddedAccountName = tostring(split(MemberAdded, \"@\")[0]), MemberAddedAccountUPNSuffix = tostring(split(MemberAdded, \"@\")[1])\n| extend UserWhoAddedAccountName = tostring(split(UserWhoAdded, \"@\")[0]), UserWhoAddedAccountUPNSuffix = tostring(split(UserWhoAdded, \"@\")[1])\n| extend UserWhoDeletedAccountName = tostring(split(UserWhoDeleted, \"@\")[0]), UserWhoDeletedAccountUPNSuffix = tostring(split(UserWhoDeleted, \"@\")[1])\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT1H",
        "severity": "Low",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1566"
        ],
        "templateVersion": "2.1.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}