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

Accessed files shared by temporary external user

Back
Idbff058b2-500e-4ae5-bb49-a5b1423cbd5b
RulenameAccessed 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 connectorsOffice365
KindScheduled
Query frequency1h
Query period1h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft 365/Analytic Rules/External User added to Team and immediately uploads file.yaml
Version2.1.0
Arm templatebff058b2-500e-4ae5-bb49-a5b1423cbd5b.json
Deploy To Azure
let fileAccessThrehold = 10;
OfficeActivity
| where OfficeWorkload =~ "MicrosoftTeams"
| where Operation =~ "MemberAdded"
| extend MemberAdded = tostring(parse_json(Members)[0].UPN)
| where MemberAdded contains ("#EXT#")
| project TimeAdded=TimeGenerated, Operation, MemberAdded, UserWhoAdded = UserId, TeamName
| join kind = inner (
  OfficeActivity
  | where OfficeWorkload =~ "MicrosoftTeams"
  | where Operation =~ "MemberRemoved"
  | extend MemberAdded = tostring(parse_json(Members)[0].UPN)
  | where MemberAdded contains ("#EXT#")
  | project TimeDeleted=TimeGenerated, Operation, MemberAdded, UserWhoDeleted = UserId, TeamName
  ) on MemberAdded
| where TimeDeleted > TimeAdded
| join kind=inner (
  OfficeActivity
  | where RecordType == "SharePointFileOperation"
  | where SourceRelativeUrl has "Microsoft Teams Chat Files"
  | where Operation == "FileUploaded"
  | extend MemberAdded = UserId
  | join kind = inner (
      OfficeActivity
      | where RecordType == "SharePointFileOperation"
      | where Operation  == "FileAccessed"
      | where SourceRelativeUrl has "Microsoft Teams Chat Files"
      | summarize FileAccessCount = count() by OfficeObjectId
      | where FileAccessCount > fileAccessThrehold
      ) on $left.OfficeObjectId == $right.OfficeObjectId
  )on MemberAdded
| project-away MemberAdded1, MemberAdded2, OfficeObjectId1, Operation1, Operation2, TeamName1, TeamName2
| 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])
triggerOperator: gt
queryFrequency: 1h
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
kind: Scheduled
triggerThreshold: 0
requiredDataConnectors:
- connectorId: Office365
  dataTypes:
  - OfficeActivity (Teams)
- connectorId: Office365
  dataTypes:
  - OfficeActivity (SharePoint)
version: 2.1.0
queryPeriod: 1h
name: Accessed files shared by temporary external user
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft 365/Analytic Rules/External User added to Team and immediately uploads file.yaml
id: bff058b2-500e-4ae5-bb49-a5b1423cbd5b
tactics:
- InitialAccess
relevantTechniques:
- T1566
severity: Low
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: MemberAdded
  - identifier: Name
    columnName: MemberAddedAccountName
  - identifier: UPNSuffix
    columnName: MemberAddedAccountUPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: FullName
    columnName: UserWhoAdded
  - identifier: Name
    columnName: UserWhoAddedAccountName
  - identifier: UPNSuffix
    columnName: UserWhoAddedAccountUPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: FullName
    columnName: UserWhoDeleted
  - identifier: Name
    columnName: UserWhoDeletedAccountName
  - identifier: UPNSuffix
    columnName: UserWhoDeletedAccountUPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: ClientIP
  entityType: IP
query: |
  let fileAccessThrehold = 10;
  OfficeActivity
  | where OfficeWorkload =~ "MicrosoftTeams"
  | where Operation =~ "MemberAdded"
  | extend MemberAdded = tostring(parse_json(Members)[0].UPN)
  | where MemberAdded contains ("#EXT#")
  | project TimeAdded=TimeGenerated, Operation, MemberAdded, UserWhoAdded = UserId, TeamName
  | join kind = inner (
    OfficeActivity
    | where OfficeWorkload =~ "MicrosoftTeams"
    | where Operation =~ "MemberRemoved"
    | extend MemberAdded = tostring(parse_json(Members)[0].UPN)
    | where MemberAdded contains ("#EXT#")
    | project TimeDeleted=TimeGenerated, Operation, MemberAdded, UserWhoDeleted = UserId, TeamName
    ) on MemberAdded
  | where TimeDeleted > TimeAdded
  | join kind=inner (
    OfficeActivity
    | where RecordType == "SharePointFileOperation"
    | where SourceRelativeUrl has "Microsoft Teams Chat Files"
    | where Operation == "FileUploaded"
    | extend MemberAdded = UserId
    | join kind = inner (
        OfficeActivity
        | where RecordType == "SharePointFileOperation"
        | where Operation  == "FileAccessed"
        | where SourceRelativeUrl has "Microsoft Teams Chat Files"
        | summarize FileAccessCount = count() by OfficeObjectId
        | where FileAccessCount > fileAccessThrehold
        ) on $left.OfficeObjectId == $right.OfficeObjectId
    )on MemberAdded
  | project-away MemberAdded1, MemberAdded2, OfficeObjectId1, Operation1, Operation2, TeamName1, TeamName2
  | 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])  
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2023-02-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/bff058b2-500e-4ae5-bb49-a5b1423cbd5b')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/bff058b2-500e-4ae5-bb49-a5b1423cbd5b')]",
      "properties": {
        "alertRuleTemplateName": "bff058b2-500e-4ae5-bb49-a5b1423cbd5b",
        "customDetails": null,
        "description": "'This detection identifies when an external user is added to a Team or Teams chat\nand shares a file which is accessed by many users (>10) and the users is removed within short period of time. This might be\nan indicator of suspicious activity.'\n",
        "displayName": "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/Microsoft 365/Analytic Rules/External User added to Team and immediately uploads file.yaml",
        "query": "let fileAccessThrehold = 10;\nOfficeActivity\n| where OfficeWorkload =~ \"MicrosoftTeams\"\n| where Operation =~ \"MemberAdded\"\n| extend MemberAdded = tostring(parse_json(Members)[0].UPN)\n| where MemberAdded contains (\"#EXT#\")\n| project TimeAdded=TimeGenerated, Operation, MemberAdded, UserWhoAdded = UserId, TeamName\n| join kind = inner (\n  OfficeActivity\n  | where OfficeWorkload =~ \"MicrosoftTeams\"\n  | where Operation =~ \"MemberRemoved\"\n  | extend MemberAdded = tostring(parse_json(Members)[0].UPN)\n  | where MemberAdded contains (\"#EXT#\")\n  | project TimeDeleted=TimeGenerated, Operation, MemberAdded, UserWhoDeleted = UserId, TeamName\n  ) on MemberAdded\n| where TimeDeleted > TimeAdded\n| join kind=inner (\n  OfficeActivity\n  | where RecordType == \"SharePointFileOperation\"\n  | where SourceRelativeUrl has \"Microsoft Teams Chat Files\"\n  | where Operation == \"FileUploaded\"\n  | extend MemberAdded = UserId\n  | join kind = inner (\n      OfficeActivity\n      | where RecordType == \"SharePointFileOperation\"\n      | where Operation  == \"FileAccessed\"\n      | where SourceRelativeUrl has \"Microsoft Teams Chat Files\"\n      | summarize FileAccessCount = count() by OfficeObjectId\n      | where FileAccessCount > fileAccessThrehold\n      ) on $left.OfficeObjectId == $right.OfficeObjectId\n  )on MemberAdded\n| project-away MemberAdded1, MemberAdded2, OfficeObjectId1, Operation1, Operation2, TeamName1, TeamName2\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",
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1566"
        ],
        "templateVersion": "2.1.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}