13.1 Understanding AiTM Attacks
What Makes AiTM Different
Adversary-in-the-middle (AiTM) phishing is not traditional credential phishing. In a traditional attack, the attacker creates a fake login page, captures the username and password, and MFA stops them — they have credentials but cannot complete the second factor. AiTM defeats MFA entirely.
The attacker deploys a reverse proxy between the victim and the real Microsoft login page. The victim sees the genuine Microsoft interface. They enter their credentials. They complete MFA. Every step passes through the attacker’s proxy, which captures the complete session token — including the MFA claim. When the attacker replays that token, Azure AD sees a valid, MFA-authenticated session. No new MFA challenge is issued.
Figure 13.1: The complete AiTM flow. The victim completes a normal login through the proxy. The proxy captures the session token at step 8.
Session tokens vs refresh tokens
Understanding what the attacker captures is critical for containment:
Session token (access token): Short-lived (typically 60-90 minutes). Grants access to a specific resource (Exchange Online, SharePoint). Expires quickly — the attacker has a narrow window.
Refresh token: Longer-lived (up to 90 days). Used to request new access tokens without re-authentication. If the attacker captures the refresh token, they can maintain access for days or weeks — generating new access tokens silently.
Modern AiTM kits capture the refresh token, not just the session token. This means revoking the session token alone is not sufficient — you must revoke all refresh tokens. In Entra ID, "Revoke sessions" invalidates both. But if you only sign the user out of active sessions without revoking refresh tokens, the attacker can silently re-authenticate.
AiTM phishing kits in the wild
| Kit | Model | Key characteristics | Prevalence |
|---|---|---|---|
| EvilGinx2 | Open-source | Highly customisable, community “phishlets” for M365/Google/Okta, self-hosted | High — foundation for many custom deployments |
| Tycoon 2FA | Phishing-as-a-Service | Cloudflare turnstile CAPTCHA (blocks scanners), rotating domains, Telegram exfil | Very high — dominant kit in 2025-2026 |
| Greatness | Service | M365-focused, built-in MFA relay, Telegram bot for stolen sessions | Moderate |
| Mamba 2FA | Service | Socket.io relay (newer technique), handles multiple MFA methods | Growing |
| NakedPages | Open-source | Go-based, lightweight, Docker deployment | Moderate |
The commercial kits (Tycoon, Greatness) lower the barrier to entry significantly. An attacker does not need to understand reverse proxying — they subscribe to the service, configure the target domain, and receive stolen tokens via Telegram.
Tycoon 2FA places a Cloudflare turnstile CAPTCHA before the proxy page. This prevents automated URL scanners (including Microsoft's Safe Links detonation) from reaching the phishing page. The URL appears clean to automated analysis — only a human who completes the CAPTCHA reaches the proxy. This is why Wave 1's URL was clean at delivery and only flagged 23 minutes later.
Why MFA alone fails — and what works
| MFA method | Stops traditional phishing? | Stops AiTM? | Why? |
|---|---|---|---|
| SMS OTP | Yes | No | OTP passes through the proxy |
| Authenticator push | Yes | No | User approves thinking it’s the real site |
| Authenticator OTP | Yes | No | OTP passes through the proxy |
| Phone call | Yes | No | Approval passes through the proxy |
| FIDO2 security key | Yes | Yes | Cryptographically bound to the real domain — proxy cannot complete the handshake |
| Certificate-based auth | Yes | Yes | Certificate verifies the server’s domain — proxy fails verification |
| Windows Hello for Business | Yes | Yes | TPM-bound, device-specific — cannot be proxied |
Check your understanding
1. An attacker captures a refresh token via AiTM. You revoke the user's active sessions but do not revoke refresh tokens. What happens?
2. Why did the phishing URL appear clean to Safe Links at delivery time?
3. FIDO2 stops AiTM but authenticator app push does not. What is the fundamental difference?