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.3
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
entityMappings:
- entityType: Account
  fieldMappings:
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: IpAddress
name: Detecting Impossible travel with mailbox permission tampering & Privilege Escalation attempt
kind: Scheduled
queryFrequency: 1d
triggerOperator: gt
queryPeriod: 1d
requiredDataConnectors:
- connectorId: AzureSecurityCenter
  dataTypes:
  - SecurityAlert (ASC)
- connectorId: Office365
  dataTypes:
  - OfficeActivity
- connectorId: AzureActivity
  dataTypes:
  - AzureActivity
- connectorId: AzureActiveDirectory
  dataTypes:
  - AuditLogs
tactics:
- InitialAccess
- PrivilegeEscalation
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.'
severity: Medium
id: 1399664f-9434-497c-9cde-42e4d74ae20e
metadata:
  author:
    name: Microsoft Security Research
  categories:
    domains:
    - Security - Others
    - Identity
  source:
    kind: Community
  support:
    tier: Community
triggerThreshold: 0
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
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/MailBoxTampering.yaml
version: 1.0.3
relevantTechniques:
- T1078
- T1548
{
  "$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": "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.3",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}