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

Detecting Impossible travel with mailbox permission tampering Privilege Escalation attempt

Back
Id1399664f-9434-497c-9cde-42e4d74ae20e
RulenameDetecting Impossible travel with mailbox permission tampering & Privilege Escalation attempt
DescriptionThis hunting query will alert on any Impossible travel activity in correlation with mailbox permission tampering followed by account being added to a PIM managed privileged group.

Ensure this impossible travel incident with increase of privileges is legitimate in your environment.
SeverityMedium
TacticsInitialAccess
PrivilegeEscalation
TechniquesT1078
T1548
Required data connectorsAzureActiveDirectory
AzureActivity
AzureSecurityCenter
Office365
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/MailBoxTampering.yaml
Version1.0.2
Arm template1399664f-9434-497c-9cde-42e4d74ae20e.json
Deploy To Azure
SecurityAlert 
| where AlertName == "Impossible travel activity"
| extend Extprop = parsejson(Entities)
| mv-expand Extprop
| extend Extprop = parsejson(Extprop)
| extend CmdLine = iff(Extprop['Type']=="process", Extprop['CommandLine'], '')
| extend File = iff(Extprop['Type']=="file", Extprop['Name'], '')
| extend Account = Extprop['Name']
| extend Domain = Extprop['UPNSuffix']
| extend Account = iif(isnotempty(Domain) and Extprop['Type']=="account", tolower(strcat(Account, "@", Domain)), iif(Extprop['Type']=="account", tolower(Account), ""))
| extend IpAddress = iff(Extprop["Type"] == "ip",Extprop['Address'], '')
| extend Process = iff(isnotempty(CmdLine), CmdLine, File)
| project TimeGenerated,Account,IpAddress,CompromisedEntity,Description,ProviderName,ResourceId
| join kind=inner
(
OfficeActivity
| where Operation =~ "Add-MailboxPermission"
| extend value = tostring(parse_json(Parameters)[3].Value)
| where value contains "FullAccess"
| where ResultStatus == "True"
| project Parameters,TimeGenerated,value,RecordType,Operation,OrganizationId,UserType,UserKey,OfficeWorkload,ResultStatus,OfficeObjectId,UserId,ClientIP,ExternalAccess,OriginatingServer,OrganizationName,TenantId,ElevationTime,SourceSystem,OfficeId,OfficeTenantId,Type,SourceRecordId
) on $left.Account == $right.UserId
| join kind=inner
(
AuditLogs
| where ActivityDisplayName =~ "Add eligible member to role in PIM requested (timebound)"
| where AADOperationType =~ "CreateRequestEligibleRole"
| where TargetResources has_any ("-PRIV", "Administrator", "Security")
| extend BuiltinRole = tostring(parse_json(TargetResources[0].displayName))
| extend CustomGroup = tostring(parse_json(TargetResources[3].displayName))
| extend TargetAccount = tostring(parse_json(TargetResources[2].displayName))
| extend Initiatedby = Identity
| project TimeGenerated, ActivityDisplayName, AADOperationType, Initiatedby, TargetAccount, BuiltinRole, CustomGroup, LoggedByService, Result, ResourceId, Id
| sort by TimeGenerated desc
) on $left.UserId == $right.Initiatedby
| extend AccountName = tostring(split(Initiatedby, "@")[0]), AccountUPNSuffix = tostring(split(Initiatedby, "@")[1])
| project AADOperationType, ActivityDisplayName,AccountName, AccountUPNSuffix, Id,ResourceId,IpAddress
relevantTechniques:
- T1078
- T1548
name: Detecting Impossible travel with mailbox permission tampering & Privilege Escalation attempt
requiredDataConnectors:
- dataTypes:
  - SecurityAlert (ASC)
  connectorId: AzureSecurityCenter
- dataTypes:
  - OfficeActivity
  connectorId: Office365
- dataTypes:
  - AzureActivity
  connectorId: AzureActivity
- dataTypes:
  - AuditLogs
  connectorId: AzureActiveDirectory
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: Initiatedby
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: IpAddress
  entityType: IP
triggerThreshold: 0
id: 1399664f-9434-497c-9cde-42e4d74ae20e
tactics:
- InitialAccess
- PrivilegeEscalation
version: 1.0.2
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/MailBoxTampering.yaml
queryPeriod: 1d
kind: Scheduled
metadata:
  categories:
    domains:
    - Security - Others
    - Identity
  author:
    name: Microsoft Security Research
  support:
    tier: Community
  source:
    kind: Community
queryFrequency: 1d
severity: Medium
description: |
  'This hunting query will alert on any Impossible travel activity in correlation with mailbox permission tampering followed by account being added to a PIM managed privileged group.
  Ensure this impossible travel incident with increase of privileges is legitimate in your environment.'  
query: |
  SecurityAlert 
  | where AlertName == "Impossible travel activity"
  | extend Extprop = parsejson(Entities)
  | mv-expand Extprop
  | extend Extprop = parsejson(Extprop)
  | extend CmdLine = iff(Extprop['Type']=="process", Extprop['CommandLine'], '')
  | extend File = iff(Extprop['Type']=="file", Extprop['Name'], '')
  | extend Account = Extprop['Name']
  | extend Domain = Extprop['UPNSuffix']
  | extend Account = iif(isnotempty(Domain) and Extprop['Type']=="account", tolower(strcat(Account, "@", Domain)), iif(Extprop['Type']=="account", tolower(Account), ""))
  | extend IpAddress = iff(Extprop["Type"] == "ip",Extprop['Address'], '')
  | extend Process = iff(isnotempty(CmdLine), CmdLine, File)
  | project TimeGenerated,Account,IpAddress,CompromisedEntity,Description,ProviderName,ResourceId
  | join kind=inner
  (
  OfficeActivity
  | where Operation =~ "Add-MailboxPermission"
  | extend value = tostring(parse_json(Parameters)[3].Value)
  | where value contains "FullAccess"
  | where ResultStatus == "True"
  | project Parameters,TimeGenerated,value,RecordType,Operation,OrganizationId,UserType,UserKey,OfficeWorkload,ResultStatus,OfficeObjectId,UserId,ClientIP,ExternalAccess,OriginatingServer,OrganizationName,TenantId,ElevationTime,SourceSystem,OfficeId,OfficeTenantId,Type,SourceRecordId
  ) on $left.Account == $right.UserId
  | join kind=inner
  (
  AuditLogs
  | where ActivityDisplayName =~ "Add eligible member to role in PIM requested (timebound)"
  | where AADOperationType =~ "CreateRequestEligibleRole"
  | where TargetResources has_any ("-PRIV", "Administrator", "Security")
  | extend BuiltinRole = tostring(parse_json(TargetResources[0].displayName))
  | extend CustomGroup = tostring(parse_json(TargetResources[3].displayName))
  | extend TargetAccount = tostring(parse_json(TargetResources[2].displayName))
  | extend Initiatedby = Identity
  | project TimeGenerated, ActivityDisplayName, AADOperationType, Initiatedby, TargetAccount, BuiltinRole, CustomGroup, LoggedByService, Result, ResourceId, Id
  | sort by TimeGenerated desc
  ) on $left.UserId == $right.Initiatedby
  | extend AccountName = tostring(split(Initiatedby, "@")[0]), AccountUPNSuffix = tostring(split(Initiatedby, "@")[1])
  | project AADOperationType, ActivityDisplayName,AccountName, AccountUPNSuffix, Id,ResourceId,IpAddress  
triggerOperator: gt
{
  "$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/1399664f-9434-497c-9cde-42e4d74ae20e')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/1399664f-9434-497c-9cde-42e4d74ae20e')]",
      "properties": {
        "alertRuleTemplateName": "1399664f-9434-497c-9cde-42e4d74ae20e",
        "customDetails": null,
        "description": "'This hunting query will alert on any Impossible travel activity in correlation with mailbox permission tampering followed by account being added to a PIM managed privileged group.\nEnsure this impossible travel incident with increase of privileges is legitimate in your environment.'\n",
        "displayName": "Detecting Impossible travel with mailbox permission tampering & Privilege Escalation attempt",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "Initiatedby",
                "identifier": "FullName"
              },
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IpAddress",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/MailBoxTampering.yaml",
        "query": "SecurityAlert \n| where AlertName == \"Impossible travel activity\"\n| extend Extprop = parsejson(Entities)\n| mv-expand Extprop\n| extend Extprop = parsejson(Extprop)\n| extend CmdLine = iff(Extprop['Type']==\"process\", Extprop['CommandLine'], '')\n| extend File = iff(Extprop['Type']==\"file\", Extprop['Name'], '')\n| extend Account = Extprop['Name']\n| extend Domain = Extprop['UPNSuffix']\n| extend Account = iif(isnotempty(Domain) and Extprop['Type']==\"account\", tolower(strcat(Account, \"@\", Domain)), iif(Extprop['Type']==\"account\", tolower(Account), \"\"))\n| extend IpAddress = iff(Extprop[\"Type\"] == \"ip\",Extprop['Address'], '')\n| extend Process = iff(isnotempty(CmdLine), CmdLine, File)\n| project TimeGenerated,Account,IpAddress,CompromisedEntity,Description,ProviderName,ResourceId\n| join kind=inner\n(\nOfficeActivity\n| where Operation =~ \"Add-MailboxPermission\"\n| extend value = tostring(parse_json(Parameters)[3].Value)\n| where value contains \"FullAccess\"\n| where ResultStatus == \"True\"\n| project Parameters,TimeGenerated,value,RecordType,Operation,OrganizationId,UserType,UserKey,OfficeWorkload,ResultStatus,OfficeObjectId,UserId,ClientIP,ExternalAccess,OriginatingServer,OrganizationName,TenantId,ElevationTime,SourceSystem,OfficeId,OfficeTenantId,Type,SourceRecordId\n) on $left.Account == $right.UserId\n| join kind=inner\n(\nAuditLogs\n| where ActivityDisplayName =~ \"Add eligible member to role in PIM requested (timebound)\"\n| where AADOperationType =~ \"CreateRequestEligibleRole\"\n| where TargetResources has_any (\"-PRIV\", \"Administrator\", \"Security\")\n| extend BuiltinRole = tostring(parse_json(TargetResources[0].displayName))\n| extend CustomGroup = tostring(parse_json(TargetResources[3].displayName))\n| extend TargetAccount = tostring(parse_json(TargetResources[2].displayName))\n| extend Initiatedby = Identity\n| project TimeGenerated, ActivityDisplayName, AADOperationType, Initiatedby, TargetAccount, BuiltinRole, CustomGroup, LoggedByService, Result, ResourceId, Id\n| sort by TimeGenerated desc\n) on $left.UserId == $right.Initiatedby\n| extend AccountName = tostring(split(Initiatedby, \"@\")[0]), AccountUPNSuffix = tostring(split(Initiatedby, \"@\")[1])\n| project AADOperationType, ActivityDisplayName,AccountName, AccountUPNSuffix, Id,ResourceId,IpAddress\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess",
          "PrivilegeEscalation"
        ],
        "techniques": [
          "T1078",
          "T1548"
        ],
        "templateVersion": "1.0.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}