Your SIEM Isn’t Broken; Your Logs Are Lying: How OAuth Consent Abuse Exploited M365 Audit Gaps + Video

Listen to this Post

Featured Image

Introduction:

In the modern enterprise, the battle lines are drawn not just at the endpoint, but deep within the identity fabric of the cloud. A recent sophisticated incident involving Microsoft 365 revealed a critical vulnerability that bypassed standard detections: OAuth consent grant abuse. The attack utilized no malware and triggered no anomalous logins, yet it successfully compromised a mailbox. This highlights a fundamental truth in detection engineering—a SIEM is only as effective as the integrity and completeness of the data it ingests. When log pipelines truncate critical nested fields, security teams are effectively flying blind, mistaking data noise for silence.

Learning Objectives:

  • Understand the mechanics of OAuth consent grant abuse and why it evades traditional authentication monitoring.
  • Identify common pitfalls in log ingestion pipelines, specifically truncation and schema drift.
  • Implement schema validation, dead-letter queues, and canary events to ensure telemetry integrity.
  • Analyze forensic artifacts in M365 (AuditLogs, UnifiedAuditLog) to detect malicious OAuth applications.

You Should Know:

  1. The Anatomy of the Attack: OAuth Consent Abuse in M365
    The attacker didn’t brute-force a password or exploit a zero-day. They leveraged a feature: OAuth 2.0 consent grants. By tricking a user into granting permissions to a malicious application registered in Azure AD, the attacker obtained a refresh token. This token allowed access to the mailbox via Graph API without requiring further authentication.

The SIEM Blindspot: The detection rule looking for “suspicious OAuth apps” was configured to parse the `modifiedProperties` field in the AuditLogs. However, the log shipper truncated any value exceeding 16KB. The critical evidence—AppId, ConsentType, and the delegated `Scopes` (like `Mail.Read` or Mail.Send)—resided in this truncated section. The alert never fired because the data required for correlation was literally missing.

  1. Diagnosing Log Truncation: The First Step in Recovery
    If you suspect log integrity issues, you cannot rely on the SIEM to tell you. You must verify at the source and during transit.

Check M365 Audit Logs Directly (PowerShell):

First, ensure you have the Exchange Online Management module installed.

 Connect to Exchange Online
Connect-ExchangeOnline

Search for Consent to Application events (Operation: "Consent to application")
$startDate = (Get-Date).AddDays(-7)
$logs = Search-UnifiedAuditLog -StartDate $startDate -EndDate (Get-Date) -Operations "Consent to application" -ResultSize 5000

Inspect the raw AuditData (which is JSON)
foreach ($log in $logs) {
$auditData = $log.AuditData | ConvertFrom-Json
 Check if the ModifiedProperties array exists and is fully populated
$auditData.ModifiedProperties | Format-List
}

If you see truncated data here, the issue is at the source API or the initial pull. If it looks complete here but is missing in your SIEM, the truncation occurs in the pipeline (e.g., Logstash, Fluentd, Splunk Universal Forwarder).

  1. Securing the Pipeline: Schema Validation and Dead-Letter Queues
    The fix implemented wasn’t a new rule; it was data integrity engineering. Treat your logs like production data streams.

Concept: Dead-Letter Queue (DLQ)

Instead of dropping logs that fail parsing, route them to a storage location (like AWS S3, Azure Blob, or a local directory) for manual inspection and replay.

Concept: Schema Validation

Use a schema registry or validation tool at the ingest point.

Example: Logstash Configuration Snippet (with JSON validation and DLQ)

input {
azure_event_hubs { ... }  Pulling from M365 Audit Logs
}

filter {
json {
source => "message"
target => "parsed_json"
 This will fail if JSON is malformed or fields are truncated to invalid JSON
}

Custom check for field length
if [bash][ModifiedProperties] {
 If the field representation is suspiciously short, drop to DLQ
if [bash][ModifiedProperties].length < 50 {
mutate {
add_tag => ["DROPPED_TRUNCATED"]
}
}
}
}

output {
if "DROPPED_TRUNCATED" in [bash] {
 Send to Dead Letter Queue (File output)
file {
path => "/var/log/dlq/oauth_failures/%{+YYYY-MM-dd}.log"
codec => json
}
} else {
 Send to Elasticsearch/Splunk/etc.
elasticsearch { ... }
}
}

4. Detection Engineering: Hunting for the Ghost App

While fixing the pipeline is paramount, you must hunt for past compromises that were missed due to the ingestion gap.

Linux/Windows Query Concept (via API or SIEM):

If you have raw logs in a data lake (like a DLQ that was recently implemented), you can use command-line tools to sift through historical data.

Using `jq` on Linux to parse historical JSON logs for truncated consent events:

 Find all consent events where the ModifiedProperties field might be truncated (ends abruptly)
 This is a heuristic search.
grep -l "Consent to application" /path/to/raw/logs/.json | xargs -I {} jq 'select(.AuditData.ModifiedProperties | type == "string" and endswith("...")) | {Time: .CreationTime, User: .UserId, AppId: .AuditData.TargetResources[bash].AppId}' {}

Windows PowerShell (for archived logs):

Get-ChildItem -Path "C:\RawLogs.json" -Recurse | Select-String -Pattern "Consent to application" | ForEach-Object {
$log = $_ | ConvertFrom-Json
if ($log.AuditData.ModifiedProperties -is [bash] -and $log.AuditData.ModifiedProperties.EndsWith("...")) {
[bash]@{
Time = $log.CreationTime
User = $log.UserId
AppHint = $log.AuditData.TargetResources[bash].AppId
}
}
}

5. Proactive Defense: Implementing “Canary Events”

To ensure your pipeline remains intact, inject known test events weekly. This is a form of synthetic monitoring for security telemetry.

How to inject a benign canary:

Create a test user in Azure AD and a small PowerShell script that generates a known log entry.

 Connect to Azure AD
Connect-AzureAD

Create a temporary dummy application (or update an existing test app's permissions)
 This generates an "Update application" or "Consent to application" audit log.
$testApp = Get-AzureADApplication -Filter "DisplayName eq 'SIEM_Canary_App'"
if (-not $testApp) {
$testApp = New-AzureADApplication -DisplayName "SIEM_Canary_App" -IdentifierUris "https://siemcanary.local"
}

Add a dummy required resource access (this triggers an audit log)
$req = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$req.ResourceAppId = "00000003-0000-0000-c000-000000000000"  Microsoft Graph
$access = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess"
$access.Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"  User.Read (dummy scope)
$access.Type = "Scope"
$req.ResourceAccess = $access

Set-AzureADApplication -ObjectId $testApp.ObjectId -RequiredResourceAccess $req

Write-Host "Canary event triggered. Check SIEM for 'Consent to application' or 'Update application' within 30 minutes."

Your monitoring team should then verify that this specific event appears in the SIEM with all fields intact.

6. Mitigation: Blocking Malicious OAuth Grants

Once you trust your logs, you can move to prevention.

Azure AD Conditional Access:

Block all OAuth app permissions except those explicitly approved.
– Navigate to Azure AD > Security > Conditional Access.
– Create a new policy: “Block OAuth Apps Outside Approval”.
– Assignments: All users and workloads.
– Cloud apps or actions: Include “All apps”.
– Conditions: Filter for “Client apps” and select “Mobile apps and desktop clients” (which includes modern OAuth flows).
– Grant: Block access.

PowerShell to Audit and Revoke:

 Install the AzureADPreview module for OAuth grant management
Install-Module -Name AzureADPreview
Connect-AzureAD

List all OAuth2PermissionGrants (delegated permissions)
Get-AzureADOAuth2PermissionGrant | Where-Object {$_.ClientId -eq "ClientAppObjectId"}

Remove a malicious grant
Remove-AzureADOAuth2PermissionGrant -ObjectId "PermissionGrantObjectId"

What Undercode Say:

  • Trust, but verify the pipeline: The most well-crafted Sigma rule is useless if the underlying telemetry is silently corrupted. Data ingestion is not just an IT operations task; it is a core security responsibility that demands rigorous validation, including schema enforcement and dead-letter queues.
  • Shift left in detection engineering: Security teams must extend their testing upstream. By implementing “canary events,” teams move from reactive monitoring to proactive validation of the entire data flow, from source to SIEM. This ensures that when an attack occurs, the evidence is present and actionable.

Prediction:

As identity-based attacks like OAuth abuse become the default vector for sophisticated adversaries, we will see a market shift toward “Data Observability for Security.” Tools that currently monitor application performance (APM) will converge with SIEM to provide real-time telemetry integrity scoring. The next evolution of the SOC will include “Data Reliability Engineers” dedicated solely to ensuring that the raw material for detection is complete, untruncated, and trustworthy, preventing the “silent drop” of critical evidence during live attacks.

▶️ Related Video (76% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Guhan Sureshbabu – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky