MFA stopped a lot of phishing campaigns. Adversary-in-the-Middle (AiTM) phishing exists specifically to get around that. The technique doesn’t break MFA — it lets the legitimate user complete MFA normally, then steals the session cookie the IdP issues afterward. The attacker replays that cookie from their own infrastructure. At that point, the MFA has already happened.

Toolkits like Evilginx2, Modlishka, W3LL Panel, and Caffeine have made AiTM infrastructure accessible to actors well below the nation-state tier. Storm-2372’s device code phishing campaign and financially motivated BEC operators have both used AiTM variants in 2025-2026. Detection coverage for this technique should be in every Entra ID-connected SOC.

How the Attack Works

The attacker stands up a reverse proxy that transparently relays traffic between the victim and the legitimate IdP (Microsoft, Google, Okta). The victim visits the phishing URL, sees a pixel-perfect replica of the real login page, enters their credentials, and completes MFA. The proxy forwards everything to the real IdP and returns the real session.

The proxy also captures the session cookies the IdP sets on successful authentication. These are real, valid, MFA-satisfied tokens. The attacker extracts them and replays them in their browser — authenticated as the victim, no further challenge required.

The result: the sign-in logs show a successful MFA event. From a naive audit perspective, the user authenticated legitimately. The attack leaves traces, but you have to look for the right signals.

Detection Signal 1: High-Risk MFA-Satisfied Sign-in

Microsoft Entra ID Identity Protection applies risk scores to sign-ins based on signals including suspicious IP, unfamiliar location, anomalous token characteristics, and known malicious infrastructure. AiTM sessions often trigger risk signals even when MFA is satisfied — because the session cookie replay from a different IP is anomalous.

Sigma rule — Entra ID sign-in with satisfied MFA and elevated risk:

title: AiTM Phishing - MFA-Satisfied High-Risk Sign-in
id: f2a4c6e8-1b3d-5f7a-9c2e-4d6b8a0c2e4f
status: experimental
description: >
  Detects sign-ins where MFA was satisfied but Entra ID Identity Protection
  flagged the session as medium or high risk. Indicates possible AiTM session
  cookie theft and replay.
references:
  - https://learn.microsoft.com/en-us/entra/id-protection/concept-identity-protection-risks
author: SOC Analyst Hub
date: 2026/05/31
tags:
  - attack.credential_access
  - attack.t1557.002
  - attack.t1078.004
logsource:
  product: azure
  service: signinlogs
detection:
  selection:
    ResultType: '0'
    AuthenticationRequirement: 'multiFactorAuthentication'
    RiskLevelDuringSignIn|contains:
      - 'high'
      - 'medium'
  filter_known_vpn:
    IPAddress|cidr:
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
  condition: selection and not filter_known_vpn
falsepositives:
  - Users authenticating from Tor exit nodes or anonymising VPNs
  - Corporate VPN exit nodes with changing IP pools
level: high

Detection Signal 2: Impossible Travel on Token Replay

AiTM proxies are typically hosted in a different country or ASN from the victim. After the victim completes MFA from (say) London, the attacker’s cookie replay comes from a hosting provider’s IP in Eastern Europe or a cloud region. The initial auth and the follow-on session activity appear to originate from physically impossible locations in a short time window.

KQL — Impossible travel between initial sign-in and follow-on activity:

// Detect: user MFA-signs in from Location A, then interactive session from Location B
// within 15 minutes from a different country
let timeWindow = 15m;
let mfaSignins = SigninLogs
    | where TimeGenerated > ago(1d)
    | where ResultType == 0
    | where AuthenticationRequirement == "multiFactorAuthentication"
    | where ConditionalAccessStatus == "success"
    | project AuthTime = TimeGenerated, 
              UserId, UserPrincipalName, 
              AuthIP = IPAddress,
              AuthCountry = tostring(LocationDetails.countryOrRegion),
              AuthASN = tostring(NetworkLocationDetails[0].networkNames);
let followOnSignins = SigninLogs
    | where TimeGenerated > ago(1d)
    | where ResultType == 0
    | where IsInteractive == true
    | project FollowTime = TimeGenerated, 
              UserId, 
              FollowIP = IPAddress,
              FollowCountry = tostring(LocationDetails.countryOrRegion),
              FollowASN = tostring(NetworkLocationDetails[0].networkNames);
mfaSignins
| join kind=inner followOnSignins on UserId
| where FollowTime between (AuthTime .. AuthTime + timeWindow)
| where AuthIP != FollowIP
| where AuthCountry != FollowCountry
| project UserPrincipalName, AuthTime, AuthIP, AuthCountry, 
          FollowTime, FollowIP, FollowCountry,
          TimeDelta = FollowTime - AuthTime
| sort by TimeDelta asc

Detection Signal 3: New Inbox Rules Post-Compromise

AiTM attacks against M365 frequently precede business email compromise — the attacker creates inbox rules to hide replies to fraudulent payment redirect emails. Detecting inbox rule creation from an unusual client or IP shortly after a risky sign-in is a high-value compound signal.

KQL — Inbox rule creation following a high-risk sign-in:

let riskySessions = SigninLogs
    | where TimeGenerated > ago(1d)
    | where ResultType == 0
    | where RiskLevelDuringSignIn in ("high", "medium")
    | project AuthTime = TimeGenerated, UserId, UserPrincipalName, IPAddress;
OfficeActivity
    | where TimeGenerated > ago(1d)
    | where Operation in ("New-InboxRule", "Set-InboxRule")
    | extend RuleParams = parse_json(Parameters)
    | where RuleParams has_any ("DeleteMessage", "MoveToFolder", "ForwardTo", "RedirectTo")
    | project RuleTime = TimeGenerated, UserId, Operation, ClientIP
    | join kind=inner riskySessions on UserId
    | where RuleTime between (AuthTime .. AuthTime + 30m)
    | project UserPrincipalName, AuthTime, RuleTime, Operation, 
              AuthIP = IPAddress, RuleCreationIP = ClientIP

Detection Signal 4: Phishing Infrastructure Indicators

Evilginx2 and similar tools have characteristic HTTP response patterns and X-Evilginx headers that can be detected at the network layer if your email security or web proxy captures them. Also watch for:

  • Domain registrations matching your brand with TLD variations (.live, .cloud, .page)
  • Certificate Transparency log monitoring for your domain name appearing in certificates registered for lookalike domains
  • Referrer headers in sign-in logs pointing to external domains right before successful authentication

Hunting Query: Token Age Anomaly

Microsoft Entra ID signs tokens with an issued-at claim (iat). If a session token is used significantly later than its issue time and from a different IP than the original auth, this is a token replay indicator.

// Hunt for sessions where token iat doesn't match first-use timing
// Requires AADUserRiskEvents and SigninLogs correlation
AADUserRiskEvents
| where TimeGenerated > ago(7d)
| where RiskEventType == "unfamiliarFeatures"
| where RiskLevel in ("high", "medium")
| project RiskTime = TimeGenerated, UserId, IPAddress, RiskDetail, CorrelationId
| join kind=inner (
    SigninLogs
    | where TimeGenerated > ago(7d)
    | where ResultType == 0
    | project UserId, AuthTime = TimeGenerated, AuthIP = IPAddress, 
              CorrelationId, UserPrincipalName
) on UserId, CorrelationId
| where IPAddress != AuthIP
| project UserPrincipalName, AuthTime, AuthIP, RiskTime, RiskIP = IPAddress, RiskDetail
| sort by AuthTime desc

Response Playbook

When AiTM token theft is confirmed or highly suspected:

  1. Revoke all active sessions for the affected user via Entra ID (Revoke-AzureADUserAllRefreshToken or portal “Revoke Sessions”)
  2. Reset credentials — the victim’s password may have been captured by the proxy
  3. Audit inbox rules created in the prior 24 hours for the affected account
  4. Review mail forwarding settings and any delegated access changes
  5. Check for OAuth app consent grants — AiTM attackers sometimes add persistent OAuth app access
  6. Enable Conditional Access phishing-resistant MFA (FIDO2 hardware keys or certificate-based auth) — these are immune to AiTM because the token is bound to the origin URL

Conditional Access policies requiring phishing-resistant authentication for privileged roles and sensitive applications are the strongest prevention control. FIDO2 tokens include the RP origin in the signed challenge — a proxy serving a different domain cannot produce a valid FIDO2 assertion.