Attack Chokepoints 2 invariant stages
Each stage is an invariant condition the attacker must satisfy, regardless of tool, variant, or threat actor. Detection at any stage breaks the chain.
1 Kit Relay Sign-In (Node.js UA) ▶
- Victim must visit a phishing page that loads the kit's JavaScript (delivered via email link, QR code, PDF/SVG/HTML attachment lure)
- Kit server must be running and reachable from victim's browser
- Target must be a cloud identity tenant (Microsoft 365 / Entra ID or Google Workspace) where the kit can proxy the login flow to the real IdP
- Victim must complete MFA challenge (kit relays all MFA methods except FIDO2/passkeys, which cryptographically bind to the legitimate origin domain)
- Entra ID Sign-in Logs (SigninLogs table in Microsoft Sentinel)
- Google Workspace Login Audit (login, token activity events)
2 Two-Tier ASN Transition ▶
- Entra ID Sign-in Logs with ASN enrichment (GeoIP/ASN database required)
- Microsoft Graph Activity Logs (c_sid correlation across /24 IPs)
Variations 2 variants tracked
Tools and methods that exploit this chokepoint. The list grows. The chokepoint doesn't change.
Tycoon 2FA (Storm-1747) - WebSocket Variant 2023-Q3 Active ▶
# Kit relay tier (cloud VPS) - server-to-server calls:
# User-Agent: axios/1.15.2
POST https://login.microsoftonline.com/common/oauth2/token [Kit relay]
# Socket.IO relay events:
# send_to_browser / response_from_browser / recieveid (typo fingerprint)
#
# Google variant - 4-event sequence within ~1s:
# login_success → login_verification(is_second_factor:true) →
# token:authorize(client:77185425430) → DEVICE_REGISTER_UNREGISTER_EVENT
- Entra ID SigninLogs: userAgent contains axios/1.15.2 on appDisplayName OfficeHome/Microsoft Authentication Broker
- Entra ID SigninLogs: Residential ASN sign-in 10-20 min after cloud-VPS sign-in, same UPN
- Graph Activity Logs: shared c_sid across multiple /24 IPs (Tier 2 operator console)
- Google Workspace Login Audit: 4-event sequence compressed to <1.2 seconds
EvilProxy 2022-Q3 Active ▶
# EvilProxy architecture similar to Tycoon 2FA
# Server-side relay generates non-browser UA on IdP sign-in events
- Entra ID SigninLogs: non-browser user agent on O365 sign-in events
- Two-tier ASN pattern when operator console is distinct from relay infra
Detection Strategy
Rules organized by the chokepoint stage they detect. Each stage has one or more rules at different maturity levels.
Node.js user agent on Entra sign-in to high-value M365 apps (OfficeHome, Auth...
Hunt
▶
resultType == "0" AND userAgent contains_any [node, axios, undici, node-fetch] AND appDisplayName contains_any [OfficeHome, Microsoft Authentication Broker, Microsoft Graph, Microsoft Exchange Online]. Exclude known-good service accounts with documented Node.js automation.
title: Entra ID AiTM Kit Relay via Node.js User Agent on High-Value M365 App
id: a2b3c4d5-e6f7-4a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: >
Detects Entra ID sign-ins with Node.js HTTP client user agents (node, axios, undici,
node-fetch) on high-value Microsoft 365 applications (OfficeHome, Microsoft Authentication
Broker, Microsoft Graph, Exchange Online). Characteristic of Tycoon 2FA and other AiTM
kit relay tiers making server-to-server HTTP calls to relay victim sessions.
Normal M365 sign-ins use browser user agents — Node.js on these apps indicates
a server-side relay component, not an end-user browser session.
references:
- https://www.elastic.co/security-labs/tycoon-2fa-aitm-detection-engineering
author: '@iimp0ster'
date: 2026-05-27
tags:
- attack.credential-access
- attack.t1539
- attack.t1078.004
- detection.maturity.hunt
logsource:
product: azure
service: signinlogs
detection:
selection_success:
ResultType: '0'
selection_ua:
UserAgent|contains:
- 'node'
- 'axios'
- 'undici'
- 'node-fetch'
selection_app:
AppDisplayName|contains:
- 'OfficeHome'
- 'Microsoft Authentication Broker'
- 'Microsoft Graph'
- 'Microsoft Exchange Online'
filter_legit_automation:
# PENDING: Add known-good service account UPNs with documented Node.js automation
# UserPrincipalName|contains:
# - 'svc-graphapi@tenant.onmicrosoft.com'
UserPrincipalName: '' # placeholder — remove and populate before production
condition: selection_success and selection_ua and selection_app and not filter_legit_automation
falsepositives:
- Legitimate server-side automation using Node.js Graph SDK targeting these apps
- DevOps pipelines with documented Graph API integration to Exchange/OfficeHome
- Exclude known-good service accounts in filter_legit_automation
level: high
Two-tier ASN correlation: cloud-VPS ASN and residential/ISP ASN both authenti...
Analyst
Low FP
▶
Requires ASN enrichment lookup on source IP. Alert when same UPN has two successful sign-ins within 20 minutes where ASN1 is a cloud-hosting provider (Alibaba Cloud, M247, DigitalOcean, Linode, OVH, Hetzner, Clouvider, Host Telecom) AND ASN2 is a residential ISP or small proxy ASN. Exclude known corporate VPN egress ASNs.
title: Entra ID Two-Tier ASN AiTM Pattern — Same UPN Cloud-VPS and Residential within 20 Minutes
id: b3c4d5e6-f7a8-4b9c-0d1e-2f3a4b5c6d7e
status: experimental
description: >
Detects two successful Entra ID sign-ins by the same UPN within 20 minutes where one
source IP is from a cloud-hosting/VPS ASN and the other is from a residential or small-ISP
ASN. This two-tier ASN pattern is structurally required by AiTM kits: cloud-VPS for the
high-throughput kit relay, residential proxy for the operator console. Single-ASN rules
miss one tier. This rule targets the architectural requirement and survives user agent rotation.
REQUIRES ASN enrichment lookup on source IP against a cloud-provider ASN list.
NOTE: This rule requires correlation across two sign-in events and ASN enrichment --
implement in SIEM with lookup table or KQL join rather than standard Sigma evaluation.
references:
- https://www.elastic.co/security-labs/tycoon-2fa-aitm-detection-engineering
author: '@iimp0ster'
date: 2026-05-27
tags:
- attack.credential-access
- attack.t1539
- attack.t1078.004
- detection.maturity.analyst
logsource:
product: azure
service: signinlogs
detection:
# This rule requires correlation and ASN enrichment — the detection block below
# is a conceptual stub. Implement via KQL join or SIEM correlation rule.
selection_cloud_vps:
ResultType: '0'
# EnrichedASN field (requires lookup table enrichment):
# EnrichedASNCategory: 'cloud-hosting'
# Cloud-hosting ASN examples: Alibaba Cloud (AS37963), M247 (AS9009),
# DigitalOcean (AS14061), Linode/Akamai (AS63949), OVH (AS16276),
# Hetzner (AS24940), Clouvider (AS62240), Host Telecom
UserAgent|contains:
- 'node'
- 'axios'
- 'undici'
- 'node-fetch'
selection_residential:
ResultType: '0'
# EnrichedASNCategory: 'residential-isp'
UserAgent|contains:
- 'Mozilla'
AppDisplayName|contains:
- 'OfficeHome'
- 'My Signins'
- 'Microsoft Approval Management'
- 'Outlook Web'
# CORRELATION: same UserPrincipalName across both sign-ins within 1200 seconds (20 min)
# STUB -- verify log source and field names against lab data; implement as SIEM correlation
condition: selection_cloud_vps
falsepositives:
- Corporate VPN egress shared across multiple ASN categories (exclude corporate VPN IPs)
- Legitimate split-routing scenarios (mobile + desktop same UPN)
- Known corporate proxies in non-cloud ASNs
level: high
OSINT Pivots
page.ip.asn:"AS37963" OR page.ip.asn:"AS9009" AND filename:*.js AND page.status:200