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

GSA Enriched Office 365 - Office Policy Tampering

Back
Id0f1f2b17-f9d6-4d2a-a0fb-a7ae1659e3eb
RulenameGSA Enriched Office 365 - Office Policy Tampering
DescriptionIdentifies if any tampering is done to either audit log, ATP Safelink, SafeAttachment, AntiPhish, or Dlp policy.

An adversary may use this technique to evade detection or avoid other policy-based defenses.

References: https://docs.microsoft.com/powershell/module/exchange/advanced-threat-protection/remove-antiphishrule?view=exchange-ps.
SeverityMedium
TacticsPersistence
DefenseEvasion
TechniquesT1098
T1562
Required data connectorsAzureActiveDirectory
Office365
KindScheduled
Query frequency1d
Query period1d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - office_policytampering.yaml
Version2.0.6
Arm template0f1f2b17-f9d6-4d2a-a0fb-a7ae1659e3eb.json
Deploy To Azure
// Query for EnrichedMicrosoft365AuditLogs
let enrichedOpList = EnrichedMicrosoft365AuditLogs 
    | summarize by Operation
    | where Operation has_any ("Remove", "Disable")
    | where Operation contains "AntiPhish" 
        or Operation contains "SafeAttachment" 
        or Operation contains "SafeLinks" 
        or Operation contains "Dlp" 
        or Operation contains "Audit"
    | summarize make_set(Operation, 500);

let enrichedLogs = EnrichedMicrosoft365AuditLogs
    | where RecordType == "ExchangeAdmin"
    | where UserType in~ ("Admin", "DcAdmin")
    | where Operation in~ (enrichedOpList)
    | extend ClientIPOnly = case( 
        ClientIp has ".", tostring(split(ClientIp, ":")[0]), 
        ClientIp has "[", tostring(trim_start(@'[[]', tostring(split(ClientIp, "]")[0]))),
        ClientIp
      )  
    | extend Port = case(
        ClientIp has ".", tostring(split(ClientIp, ":")[1]),
        ClientIp has "[", tostring(split(ClientIp, "]:")[1]),
        ""
      )
    | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), OperationCount = count() 
        by Operation, UserType, UserId, ClientIP = ClientIPOnly, Port, ResultStatus, Parameters = tostring(AdditionalProperties.Parameters)
    | extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1]);

// Query for OfficeActivity
let officeOpList = OfficeActivity 
    | summarize by Operation
    | where Operation has_any ("Remove", "Disable")
    | where Operation contains "AntiPhish" 
        or Operation contains "SafeAttachment" 
        or Operation contains "SafeLinks" 
        or Operation contains "Dlp" 
        or Operation contains "Audit"
    | summarize make_set(Operation, 500);

let officeLogs = OfficeActivity
    | where RecordType =~ "ExchangeAdmin"
    | where UserType in~ ("Admin","DcAdmin")
    | where Operation in~ (officeOpList)
    | extend ClientIPOnly = case( 
        ClientIP has ".", tostring(split(ClientIP,":")[0]), 
        ClientIP has "[", tostring(trim_start(@'[[]', tostring(split(ClientIP,"]")[0]))),
        ClientIP
      )  
    | extend Port = case(
        ClientIP has ".", tostring(split(ClientIP,":")[1]),
        ClientIP has "[", tostring(split(ClientIP, "]:")[1]),
        ""
      )
    | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), OperationCount = count() 
        by Operation, UserType, UserId, ClientIP = ClientIPOnly, Port, ResultStatus, Parameters
    | extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1]);

// Combine Enriched Logs and Office Activity Logs
union isfuzzy=true enrichedLogs, officeLogs
| summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), TotalOperationCount = sum(OperationCount) 
    by Operation, UserType, UserId, ClientIP, Port, ResultStatus, Parameters, AccountName, AccountUPNSuffix
| order by StartTimeUtc desc;
query: |
  // Query for EnrichedMicrosoft365AuditLogs
  let enrichedOpList = EnrichedMicrosoft365AuditLogs 
      | summarize by Operation
      | where Operation has_any ("Remove", "Disable")
      | where Operation contains "AntiPhish" 
          or Operation contains "SafeAttachment" 
          or Operation contains "SafeLinks" 
          or Operation contains "Dlp" 
          or Operation contains "Audit"
      | summarize make_set(Operation, 500);

  let enrichedLogs = EnrichedMicrosoft365AuditLogs
      | where RecordType == "ExchangeAdmin"
      | where UserType in~ ("Admin", "DcAdmin")
      | where Operation in~ (enrichedOpList)
      | extend ClientIPOnly = case( 
          ClientIp has ".", tostring(split(ClientIp, ":")[0]), 
          ClientIp has "[", tostring(trim_start(@'[[]', tostring(split(ClientIp, "]")[0]))),
          ClientIp
        )  
      | extend Port = case(
          ClientIp has ".", tostring(split(ClientIp, ":")[1]),
          ClientIp has "[", tostring(split(ClientIp, "]:")[1]),
          ""
        )
      | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), OperationCount = count() 
          by Operation, UserType, UserId, ClientIP = ClientIPOnly, Port, ResultStatus, Parameters = tostring(AdditionalProperties.Parameters)
      | extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1]);

  // Query for OfficeActivity
  let officeOpList = OfficeActivity 
      | summarize by Operation
      | where Operation has_any ("Remove", "Disable")
      | where Operation contains "AntiPhish" 
          or Operation contains "SafeAttachment" 
          or Operation contains "SafeLinks" 
          or Operation contains "Dlp" 
          or Operation contains "Audit"
      | summarize make_set(Operation, 500);

  let officeLogs = OfficeActivity
      | where RecordType =~ "ExchangeAdmin"
      | where UserType in~ ("Admin","DcAdmin")
      | where Operation in~ (officeOpList)
      | extend ClientIPOnly = case( 
          ClientIP has ".", tostring(split(ClientIP,":")[0]), 
          ClientIP has "[", tostring(trim_start(@'[[]', tostring(split(ClientIP,"]")[0]))),
          ClientIP
        )  
      | extend Port = case(
          ClientIP has ".", tostring(split(ClientIP,":")[1]),
          ClientIP has "[", tostring(split(ClientIP, "]:")[1]),
          ""
        )
      | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), OperationCount = count() 
          by Operation, UserType, UserId, ClientIP = ClientIPOnly, Port, ResultStatus, Parameters
      | extend AccountName = tostring(split(UserId, "@")[0]), AccountUPNSuffix = tostring(split(UserId, "@")[1]);

  // Combine Enriched Logs and Office Activity Logs
  union isfuzzy=true enrichedLogs, officeLogs
  | summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), TotalOperationCount = sum(OperationCount) 
      by Operation, UserType, UserId, ClientIP, Port, ResultStatus, Parameters, AccountName, AccountUPNSuffix
  | order by StartTimeUtc desc;  
relevantTechniques:
- T1098
- T1562
name: GSA Enriched Office 365 - Office Policy Tampering
severity: Medium
triggerThreshold: 0
description: |
  Identifies if any tampering is done to either audit log, ATP Safelink, SafeAttachment, AntiPhish, or Dlp policy. 
  An adversary may use this technique to evade detection or avoid other policy-based defenses.
  References: https://docs.microsoft.com/powershell/module/exchange/advanced-threat-protection/remove-antiphishrule?view=exchange-ps.  
status: Available
triggerOperator: gt
tactics:
- Persistence
- DefenseEvasion
entityMappings:
- fieldMappings:
  - columnName: UserId
    identifier: FullName
  - columnName: AccountName
    identifier: Name
  - columnName: AccountUPNSuffix
    identifier: UPNSuffix
  entityType: Account
- fieldMappings:
  - columnName: ClientIP
    identifier: Address
  entityType: IP
requiredDataConnectors:
- connectorId: AzureActiveDirectory
  dataTypes:
  - EnrichedMicrosoft365AuditLogs
- connectorId: Office365
  dataTypes:
  - OfficeActivity (Exchange)
id: 0f1f2b17-f9d6-4d2a-a0fb-a7ae1659e3eb
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Office 365 - office_policytampering.yaml
queryPeriod: 1d
queryFrequency: 1d
version: 2.0.6
kind: Scheduled
{
  "$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/0f1f2b17-f9d6-4d2a-a0fb-a7ae1659e3eb')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/0f1f2b17-f9d6-4d2a-a0fb-a7ae1659e3eb')]",
      "properties": {
        "alertRuleTemplateName": "0f1f2b17-f9d6-4d2a-a0fb-a7ae1659e3eb",
        "customDetails": null,
        "description": "Identifies if any tampering is done to either audit log, ATP Safelink, SafeAttachment, AntiPhish, or Dlp policy. \nAn adversary may use this technique to evade detection or avoid other policy-based defenses.\nReferences: https://docs.microsoft.com/powershell/module/exchange/advanced-threat-protection/remove-antiphishrule?view=exchange-ps.\n",
        "displayName": "GSA Enriched Office 365 - Office Policy Tampering",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "UserId",
                "identifier": "FullName"
              },
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "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 - office_policytampering.yaml",
        "query": "// Query for EnrichedMicrosoft365AuditLogs\nlet enrichedOpList = EnrichedMicrosoft365AuditLogs \n    | summarize by Operation\n    | where Operation has_any (\"Remove\", \"Disable\")\n    | where Operation contains \"AntiPhish\" \n        or Operation contains \"SafeAttachment\" \n        or Operation contains \"SafeLinks\" \n        or Operation contains \"Dlp\" \n        or Operation contains \"Audit\"\n    | summarize make_set(Operation, 500);\n\nlet enrichedLogs = EnrichedMicrosoft365AuditLogs\n    | where RecordType == \"ExchangeAdmin\"\n    | where UserType in~ (\"Admin\", \"DcAdmin\")\n    | where Operation in~ (enrichedOpList)\n    | extend ClientIPOnly = case( \n        ClientIp has \".\", tostring(split(ClientIp, \":\")[0]), \n        ClientIp has \"[\", tostring(trim_start(@'[[]', tostring(split(ClientIp, \"]\")[0]))),\n        ClientIp\n      )  \n    | extend Port = case(\n        ClientIp has \".\", tostring(split(ClientIp, \":\")[1]),\n        ClientIp has \"[\", tostring(split(ClientIp, \"]:\")[1]),\n        \"\"\n      )\n    | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), OperationCount = count() \n        by Operation, UserType, UserId, ClientIP = ClientIPOnly, Port, ResultStatus, Parameters = tostring(AdditionalProperties.Parameters)\n    | extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1]);\n\n// Query for OfficeActivity\nlet officeOpList = OfficeActivity \n    | summarize by Operation\n    | where Operation has_any (\"Remove\", \"Disable\")\n    | where Operation contains \"AntiPhish\" \n        or Operation contains \"SafeAttachment\" \n        or Operation contains \"SafeLinks\" \n        or Operation contains \"Dlp\" \n        or Operation contains \"Audit\"\n    | summarize make_set(Operation, 500);\n\nlet officeLogs = OfficeActivity\n    | where RecordType =~ \"ExchangeAdmin\"\n    | where UserType in~ (\"Admin\",\"DcAdmin\")\n    | where Operation in~ (officeOpList)\n    | extend ClientIPOnly = case( \n        ClientIP has \".\", tostring(split(ClientIP,\":\")[0]), \n        ClientIP has \"[\", tostring(trim_start(@'[[]', tostring(split(ClientIP,\"]\")[0]))),\n        ClientIP\n      )  \n    | extend Port = case(\n        ClientIP has \".\", tostring(split(ClientIP,\":\")[1]),\n        ClientIP has \"[\", tostring(split(ClientIP, \"]:\")[1]),\n        \"\"\n      )\n    | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), OperationCount = count() \n        by Operation, UserType, UserId, ClientIP = ClientIPOnly, Port, ResultStatus, Parameters\n    | extend AccountName = tostring(split(UserId, \"@\")[0]), AccountUPNSuffix = tostring(split(UserId, \"@\")[1]);\n\n// Combine Enriched Logs and Office Activity Logs\nunion isfuzzy=true enrichedLogs, officeLogs\n| summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), TotalOperationCount = sum(OperationCount) \n    by Operation, UserType, UserId, ClientIP, Port, ResultStatus, Parameters, AccountName, AccountUPNSuffix\n| order by StartTimeUtc desc;\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P1D",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "DefenseEvasion",
          "Persistence"
        ],
        "techniques": [
          "T1098",
          "T1562"
        ],
        "templateVersion": "2.0.6",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}