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.1
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
| project AADOperationType, ActivityDisplayName,AccountCustomEntity=Initiatedby, Id,ResourceId,IPCustomEntity=IpAddress
queryPeriod: 1d
version: 1.0.1
relevantTechniques:
- T1078
- T1548
queryFrequency: 1d
kind: Scheduled
severity: Medium
name: Detecting Impossible travel with mailbox permission tampering & Privilege Escalation attempt
id: 1399664f-9434-497c-9cde-42e4d74ae20e
entityMappings:
- fieldMappings:
  - columnName: AccountCustomEntity
    identifier: FullName
  entityType: Account
- fieldMappings:
  - columnName: IPCustomEntity
    identifier: Address
  entityType: IP
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/MailBoxTampering.yaml
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
  | project AADOperationType, ActivityDisplayName,AccountCustomEntity=Initiatedby, Id,ResourceId,IPCustomEntity=IpAddress  
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.'  
requiredDataConnectors:
- connectorId: AzureSecurityCenter
  dataTypes:
  - SecurityAlert (ASC)
- connectorId: Office365
  dataTypes:
  - OfficeActivity
- connectorId: AzureActivity
  dataTypes:
  - AzureActivity
- connectorId: AzureActiveDirectory
  dataTypes:
  - AuditLogs
metadata:
  author:
    name: Pete Bryan
  source:
    kind: Community
  categories:
    domains:
    - Security - Others
    - Identity
  support:
    tier: Community
triggerThreshold: 0
triggerOperator: gt
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/1399664f-9434-497c-9cde-42e4d74ae20e')]",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/1399664f-9434-497c-9cde-42e4d74ae20e')]",
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "kind": "Scheduled",
      "apiVersion": "2022-11-01",
      "properties": {
        "displayName": "Detecting Impossible travel with mailbox permission tampering & Privilege Escalation attempt",
        "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",
        "severity": "Medium",
        "enabled": true,
        "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| project AADOperationType, ActivityDisplayName,AccountCustomEntity=Initiatedby, Id,ResourceId,IPCustomEntity=IpAddress\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess",
          "PrivilegeEscalation"
        ],
        "techniques": [
          "T1078",
          "T1548"
        ],
        "alertRuleTemplateName": "1399664f-9434-497c-9cde-42e4d74ae20e",
        "customDetails": null,
        "entityMappings": [
          {
            "fieldMappings": [
              {
                "identifier": "FullName",
                "columnName": "AccountCustomEntity"
              }
            ],
            "entityType": "Account"
          },
          {
            "fieldMappings": [
              {
                "identifier": "Address",
                "columnName": "IPCustomEntity"
              }
            ],
            "entityType": "IP"
          }
        ],
        "templateVersion": "1.0.1",
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/MailBoxTampering.yaml"
      }
    }
  ]
}