In March 2025, a campaign tracked as Storm-1167 hit over 10,000 organizations using adversary-in-the-middle (AiTM) phishing to bypass MFA and steal Microsoft 365 session cookies. The attack didn’t crack passwords — it hijacked authenticated sessions after the victim logged in legitimately. If your detection strategy stops at failed logins, you’re already behind.
How AiTM Phishing Steals Sessions — Not Just Passwords
AiTM phishing proxies a real Microsoft login page between the victim and Microsoft’s servers. The victim authenticates — including completing MFA — and the attacker’s proxy captures the session cookie in real time. Tools like Evilginx (a reverse proxy framework) automate this entirely.
Here’s what a captured session looks like in an Evilginx session log after a victim clicks a phishing link and logs in:
[session] id: 8f3a1c
target: microsoft365
username: j.harris@contoso.com
password: W!nter2025$
tokens:
.AspNetCore.Cookies: AQABAAIAAAD...[truncated]
ESTSAUTH: 0.AXoAk...[truncated]
remote_addr: 192.0.2.47
user_agent: Mozilla/5.0 (Windows NT 10.0; Win64)
That ESTSAUTH cookie is the prize. It represents a fully authenticated Microsoft session — MFA already satisfied. An attacker imports this into a browser using a tool like Cookie Editor or a Burp Suite extension, navigates to outlook.office365.com, and lands directly in the victim’s inbox. No password needed. No MFA prompt.
From there, the attacker moves fast: they search the mailbox for finance threads, password reset emails, and VPN credentials. They also set inbox rules to forward email silently or hide replies — a classic business email compromise setup.
OAuth App Abuse: Persistence After the Cookie Expires
Session cookies expire. Attackers who want persistent access use a smarter technique: OAuth application consent abuse. They trick users into granting a malicious third-party app access to their Microsoft 365 data. The app gets an OAuth refresh token — which can last months.
The phishing email contains a link to a Microsoft-hosted consent page for a registered Azure AD app the attacker controls. The URL looks completely legitimate:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?client_id=4f9a2b31-cc87-4e10-91d3-0fa8b2c3e5d1
&response_type=code
&redirect_uri=https://mail-preview.contoso-helpdesk.com/callback
&scope=Mail.Read%20Mail.Send%20Contacts.Read%20offline_access
&state=abc123
The scope parameter is the tell. Mail.Read, Mail.Send, and offline_access together mean the app can read and send email on the user’s behalf — indefinitely, via refresh tokens. The redirect_uri domain looks plausible but is attacker-controlled.
Once granted, you can enumerate what was authorized using the Microsoft Graph API or PowerShell:
# List OAuth grants for a user in Entra ID (Azure AD)
Get-MgUserOAuth2PermissionGrant -UserId j.harris@contoso.com |
Select-Object ClientId, Scope, ConsentType
# Output:
ClientId Scope ConsentType
-------- ----- -----------
4f9a2b31-cc87-4e10-91d3-0fa8b2c3e5d1 Mail.Read Mail.Send offline_access Principal
b82c5e00-1234-4abc-9def-aabbccddeeff Calendars.Read Principal
That first entry is the malicious app. ConsentType: Principal means the individual user — not an admin — approved it. Your conditional access policies and MFA never saw this handoff. The attacker now calls Graph API endpoints like GET /v1.0/users/j.harris@contoso.com/messages using a valid access token. This generates logs that look like normal application traffic.
The detection hook: look for OAuth grants to apps with low tenant prevalence, unknown client_id values, or redirect URIs pointing outside your organization’s domains. Microsoft Defender for Cloud Apps has a built-in OAuth app policy for exactly this.
What Defenders Should Look For in Unified Audit Logs
Both attacks leave traces in Microsoft 365’s Unified Audit Log — if you know what to query. For AiTM session hijacking, watch for impossible travel: a session starting in one geography and resuming seconds later from a different IP.
# Query UAL for suspicious sign-in activity via Microsoft Graph
Search-UnifiedAuditLog -StartDate 2026-07-10 -EndDate 2026-07-11 \
-Operations "UserLoggedIn" \
-UserIds j.harris@contoso.com |
Select-Object -ExpandProperty AuditData |
ConvertFrom-Json |
Select-Object CreationTime, ClientIP, UserAgent, ResultStatus
# Suspicious output snippet:
CreationTime : 2026-07-10T14:22:11Z ClientIP: 192.0.2.47 ResultStatus: Success
CreationTime : 2026-07-10T14:22:58Z ClientIP: 192.0.2.213 ResultStatus: Success
Same user, two successful logins 47 seconds apart, two different IPs. That’s the victim completing MFA at 192.0.2.47 and the attacker immediately replaying the session cookie from 192.0.2.213. Neither event looks suspicious in isolation. Together, they’re a confirmed AiTM hit.
Pair this with any subsequent New-InboxRule operations in the audit log and you have a complete attack chain to present in your incident report.
What To Do Right Now
Pull the OAuth app inventory for your tenant today. Run Get-MgServicePrincipal -All | Where-Object {$_.AppOwnerOrganizationId -ne 'your-tenant-id'} in Microsoft Graph PowerShell and review every third-party app that holds Mail.Send or offline_access permissions. Revoke anything you don’t recognize. Then enable the Risky OAuth App policy in Defender for Cloud Apps to alert on future grants automatically. This single action closes the persistence door that outlasts every stolen session cookie.
