Performing Adversary-in-the-Middle Phishing Detection Overview Adversary-in-the-Middle (AiTM) phishing attacks use reverse-proxy infrastructure to sit between the victim and the legitimate authentication service, intercepting both credentials and session cookies in real time. This allows attackers to bypass multi-factor authentication (MFA). The most prevalent PhaaS kits in 2025 include Tycoon 2FA, Sneaky 2FA, EvilProxy, and Evilginx. Over 1 million PhaaS attacks were detected in January-February 2025 alone. These attacks have evolved from QR codes to HTML attachments and SVG files for link d…

,\n r'.*\\.pages\\.dev

Performing Adversary-in-the-Middle Phishing Detection Overview Adversary-in-the-Middle (AiTM) phishing attacks use reverse-proxy infrastructure to sit between the victim and the legitimate authentication service, intercepting both credentials and session cookies in real time. This allows attackers to bypass multi-factor authentication (MFA). The most prevalent PhaaS kits in 2025 include Tycoon 2FA, Sneaky 2FA, EvilProxy, and Evilginx. Over 1 million PhaaS attacks were detected in January-February 2025 alone. These attacks have evolved from QR codes to HTML attachments and SVG files for link d…

,\n r'.*-login-.*\\.(com|net|org)',\n]\n\n# Known PhaaS hosting patterns\nPHAAS_INFRA = [\n 'cloudflare-ipfs.com',\n 'workers.dev',\n 'pages.dev',\n 'web.app',\n 'firebaseapp.com',\n 'glitch.me',\n 'netlify.app',\n 'vercel.app',\n]\n\n\ndef haversine_distance(lat1, lon1, lat2, lon2):\n \"\"\"Calculate distance in km between two coordinates.\"\"\"\n R = 6371 # Earth radius in km\n lat1_r, lat2_r = math.radians(lat1), math.radians(lat2)\n dlat = math.radians(lat2 - lat1)\n dlon = math.radians(lon2 - lon1)\n a = (math.sin(dlat / 2) ** 2 +\n math.cos(lat1_r) * math.cos(lat2_r) * math.sin(dlon / 2) ** 2)\n c = 2 * math.asin(math.sqrt(a))\n return R * c\n\n\ndef detect_aitm_signins(signins: list) -> AiTMAnalysis:\n \"\"\"Analyze sign-in logs for AiTM indicators.\"\"\"\n analysis = AiTMAnalysis()\n analysis.total_signins = len(signins)\n\n user_signins = defaultdict(list)\n for signin in signins:\n user = signin.get(\"userPrincipalName\", \"\")\n user_signins[user].append(signin)\n\n affected = set()\n\n for user, events in user_signins.items():\n sorted_events = sorted(events, key=lambda x: x.get(\"createdDateTime\", \"\"))\n\n for i in range(len(sorted_events)):\n event = sorted_events[i]\n ip = event.get(\"ipAddress\", \"\")\n location = event.get(\"location\", {})\n risk_level = event.get(\"riskLevelDuringSignIn\", \"none\")\n is_interactive = event.get(\"isInteractive\", True)\n app = event.get(\"appDisplayName\", \"\")\n timestamp = event.get(\"createdDateTime\", \"\")\n\n # Check for anonymous proxy\n if event.get(\"isFromAnonymousProxy\", False):\n analysis.indicators.append(AiTMIndicator(\n indicator_type=\"anonymous_proxy\",\n description=f\"Sign-in from anonymous proxy/VPN\",\n severity=\"high\",\n confidence=0.7,\n user=user,\n timestamp=timestamp,\n details={\"ip\": ip}\n ))\n analysis.suspicious_signins += 1\n affected.add(user)\n\n # Check for impossible travel\n if i > 0:\n prev = sorted_events[i - 1]\n prev_loc = prev.get(\"location\", {})\n prev_time = prev.get(\"createdDateTime\", \"\")\n\n if (location.get(\"geoCoordinates\") and\n prev_loc.get(\"geoCoordinates\")):\n lat1 = prev_loc[\"geoCoordinates\"].get(\"latitude\", 0)\n lon1 = prev_loc[\"geoCoordinates\"].get(\"longitude\", 0)\n lat2 = location[\"geoCoordinates\"].get(\"latitude\", 0)\n lon2 = location[\"geoCoordinates\"].get(\"longitude\", 0)\n\n distance = haversine_distance(lat1, lon1, lat2, lon2)\n\n try:\n t1 = datetime.fromisoformat(prev_time.replace('Z', '+00:00'))\n t2 = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))\n hours = (t2 - t1).total_seconds() / 3600\n\n if hours > 0 and distance > 0:\n speed = distance / hours\n if speed > 900: # Faster than commercial flight\n analysis.indicators.append(AiTMIndicator(\n indicator_type=\"impossible_travel\",\n description=(\n f\"Impossible travel: {distance:.0f}km in \"\n f\"{hours:.1f}h ({speed:.0f}km/h)\"\n ),\n severity=\"high\",\n confidence=0.85,\n user=user,\n timestamp=timestamp,\n details={\n \"from_ip\": prev.get(\"ipAddress\"),\n \"to_ip\": ip,\n \"distance_km\": round(distance),\n \"speed_kmh\": round(speed)\n }\n ))\n analysis.impossible_travel_detected += 1\n affected.add(user)\n except (ValueError, TypeError):\n pass\n\n # Check for session from different IP shortly after auth\n if i \u003c len(sorted_events) - 1:\n next_event = sorted_events[i + 1]\n next_ip = next_event.get(\"ipAddress\", \"\")\n next_time = next_event.get(\"createdDateTime\", \"\")\n\n if ip and next_ip and ip != next_ip:\n try:\n t1 = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))\n t2 = datetime.fromisoformat(next_time.replace('Z', '+00:00'))\n minutes = (t2 - t1).total_seconds() / 60\n\n if 0 \u003c minutes \u003c 10:\n analysis.indicators.append(AiTMIndicator(\n indicator_type=\"session_ip_switch\",\n description=(\n f\"Session IP changed within {minutes:.0f}min \"\n f\"({ip} -> {next_ip})\"\n ),\n severity=\"critical\",\n confidence=0.9,\n user=user,\n timestamp=timestamp,\n details={\n \"auth_ip\": ip,\n \"session_ip\": next_ip,\n \"time_delta_min\": round(minutes)\n }\n ))\n analysis.session_replays_detected += 1\n affected.add(user)\n except (ValueError, TypeError):\n pass\n\n analysis.affected_users = list(affected)\n if affected:\n analysis.recommended_actions = [\n \"Revoke all sessions for affected users\",\n \"Force password reset with phishing-resistant MFA\",\n \"Check for inbox forwarding rules created post-compromise\",\n \"Review OAuth app consents for affected accounts\",\n \"Block source IPs at firewall\",\n \"Retract phishing email from all mailboxes\"\n ]\n\n return analysis\n\n\ndef analyze_domain(domain: str) -> dict:\n \"\"\"Check if domain matches known AiTM/PhaaS patterns.\"\"\"\n result = {\n \"domain\": domain,\n \"is_suspicious\": False,\n \"indicators\": [],\n \"risk_score\": 0\n }\n\n domain_lower = domain.lower()\n\n for pattern in AITM_DOMAIN_PATTERNS:\n if re.search(pattern, domain_lower):\n result[\"indicators\"].append(f\"Matches AiTM domain pattern: {pattern}\")\n result[\"risk_score\"] += 30\n result[\"is_suspicious\"] = True\n\n for infra in PHAAS_INFRA:\n if domain_lower.endswith(infra):\n result[\"indicators\"].append(f\"Hosted on known PhaaS infrastructure: {infra}\")\n result[\"risk_score\"] += 25\n result[\"is_suspicious\"] = True\n\n # Check for brand impersonation in domain\n brands = ['microsoft', 'office', 'outlook', 'google', 'okta', 'azure']\n for brand in brands:\n if brand in domain_lower and not domain_lower.endswith(f'.{brand}.com'):\n result[\"indicators\"].append(f\"Contains brand name '{brand}' in non-official domain\")\n result[\"risk_score\"] += 20\n result[\"is_suspicious\"] = True\n\n result[\"risk_score\"] = min(result[\"risk_score\"], 100)\n return result\n\n\ndef main():\n parser = argparse.ArgumentParser(description=\"AiTM Phishing Detection\")\n subparsers = parser.add_subparsers(dest=\"command\")\n\n detect_parser = subparsers.add_parser(\"detect\", help=\"Detect AiTM in sign-in logs\")\n detect_parser.add_argument(\"--signin-log\", required=True)\n\n domain_parser = subparsers.add_parser(\"analyze-domain\", help=\"Check domain for AiTM\")\n domain_parser.add_argument(\"--domain\", required=True)\n\n parser.add_argument(\"--json\", action=\"store_true\")\n args = parser.parse_args()\n\n if args.command == \"detect\":\n with open(args.signin_log) as f:\n signins = json.load(f)\n result = detect_aitm_signins(signins)\n if args.json:\n print(json.dumps(asdict(result), indent=2, default=str))\n else:\n print(f\"Total sign-ins: {result.total_signins}\")\n print(f\"Suspicious: {result.suspicious_signins}\")\n print(f\"Session replays: {result.session_replays_detected}\")\n print(f\"Impossible travel: {result.impossible_travel_detected}\")\n print(f\"Affected users: {len(result.affected_users)}\")\n for ind in result.indicators:\n print(f\" [{ind.severity.upper()}] {ind.description} (user: {ind.user})\")\n\n elif args.command == \"analyze-domain\":\n result = analyze_domain(args.domain)\n print(json.dumps(result, indent=2))\n\n else:\n parser.print_help()\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":11016,"content_sha256":"d7880877d3702a2e66c6c57a794382ad363961428f6eb01724b21597bad7b0fc"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Performing Adversary-in-the-Middle Phishing Detection","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"Adversary-in-the-Middle (AiTM) phishing attacks use reverse-proxy infrastructure to sit between the victim and the legitimate authentication service, intercepting both credentials and session cookies in real time. This allows attackers to bypass multi-factor authentication (MFA). The most prevalent PhaaS kits in 2025 include Tycoon 2FA, Sneaky 2FA, EvilProxy, and Evilginx. Over 1 million PhaaS attacks were detected in January-February 2025 alone. These attacks have evolved from QR codes to HTML attachments and SVG files for link distribution.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When conducting security assessments that involve performing adversary in the middle phishing detection","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When following incident response procedures for related security events","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When performing scheduled security testing or auditing activities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When validating security controls through hands-on testing","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Prerequisites","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Azure AD / Entra ID Conditional Access policies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SIEM with authentication log ingestion (Azure AD sign-in logs)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Web proxy with SSL inspection and URL categorization","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Endpoint Detection and Response (EDR) solution","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FIDO2/phishing-resistant MFA capability","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Key Concepts","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"How AiTM Works","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Victim receives phishing email with link to attacker-controlled domain","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Attacker domain runs reverse proxy that mirrors legitimate login page","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Victim enters credentials on proxied page; credentials captured in transit","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Reverse proxy forwards credentials to real authentication service","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"MFA challenge sent to victim; victim completes MFA on proxied page","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Attacker captures session cookie returned by legitimate service","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Attacker replays session cookie to access victim's account without MFA","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Major AiTM Kits (2025)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Kit","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Primary Targets","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Evasion","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tycoon 2FA","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PhaaS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microsoft 365, Google","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"CAPTCHA, Cloudflare turnstile","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"EvilProxy","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PhaaS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microsoft 365, Google, Okta","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Random URLs, IP rotation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Evilginx","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Open-source","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Any web application","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Custom phishlets","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Sneaky 2FA","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PhaaS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Microsoft 365","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anti-bot checks","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NakedPages","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PhaaS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multiple","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Minimal infrastructure","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Detection Indicators","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authentication from unusual IP not matching user profile","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Session cookie reuse from different IP/device than authentication","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Login page served from non-Microsoft/non-Google infrastructure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CDN requests to legitimate auth providers from phishing domains","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Impossible travel between authentication and session usage","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Workflow","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Deploy Phishing-Resistant MFA","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement FIDO2 security keys or Windows Hello for Business for high-value accounts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure Conditional Access to require phishing-resistant MFA for admins","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enable certificate-based authentication where possible","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Disable SMS and voice MFA for privileged accounts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"AiTM cannot intercept FIDO2 because authentication is bound to origin domain","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Configure Conditional Access Policies","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Require compliant/managed device for sensitive application access","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Block authentication from anonymous proxies and Tor exit nodes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Enforce token binding to limit session cookie replay","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configure continuous access evaluation (CAE) for real-time token revocation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement sign-in risk policies that require re-authentication for risky sign-ins","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Build AiTM Detection Rules","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Alert on sign-in followed by session from different IP within 10 minutes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect authentication where proxy IP does not match user's expected location","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Monitor for impossible travel patterns in session usage","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Alert on inbox rules created immediately after authentication (common post-compromise)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect new MFA method registration from suspicious sign-in","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Monitor Web Proxy for AiTM Infrastructure","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Log and analyze DNS queries to newly registered domains","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect connections to known PhaaS infrastructure IPs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Alert on authentication page backgrounds loaded from legitimate CDNs through proxy domains","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Monitor for SSL certificates issued to domains mimicking corporate login pages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Block access to known EvilProxy/Evilginx infrastructure via threat intelligence","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Implement Post-Compromise Detection","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Alert on mailbox forwarding rules created after suspicious authentication","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detect OAuth app consent after AiTM sign-in","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Monitor for email sending patterns indicating BEC follow-up","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Alert on SharePoint/OneDrive mass download after session hijack","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Track lateral movement from compromised account","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Tools & Resources","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Microsoft Entra ID Protection","type":"text","marks":[{"type":"strong"}]},{"text":": Risk-based Conditional Access","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Azure AD Sign-in Logs","type":"text","marks":[{"type":"strong"}]},{"text":": Authentication event analysis","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Okta ThreatInsight","type":"text","marks":[{"type":"strong"}]},{"text":": AiTM proxy detection at IdP level","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Sekoia TDR","type":"text","marks":[{"type":"strong"}]},{"text":": AiTM campaign tracking and intelligence","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Evilginx (defensive)","type":"text","marks":[{"type":"strong"}]},{"text":": Understanding attack mechanics for detection","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Validation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Phishing-resistant MFA blocks AiTM session capture in test scenario","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Conditional Access denies session replay from different device/IP","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SIEM alerts fire on simulated AiTM sign-in patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Web proxy blocks connections to known PhaaS infrastructure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Post-compromise rules detect inbox rule creation after suspicious auth","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"performing-adversary-in-the-middle-phishing-detection","tags":["aitm","evilproxy","evilginx","phishing","mfa-bypass","session-hijacking","reverse-proxy","credential-theft"],"author":"@skillopedia","domain":"cybersecurity","source":{"stars":13207,"repo_name":"anthropic-cybersecurity-skills","origin_url":"https://github.com/mukul975/anthropic-cybersecurity-skills/blob/HEAD/skills/performing-adversary-in-the-middle-phishing-detection/SKILL.md","repo_owner":"mukul975","body_sha256":"1fd2206353afdc65508b42a170dea3599a31699c70303a6a8dcf8a6a5041c5fc","cluster_key":"128c7fac97c76580a7605b60130aea4040ebceb7e29d7a67b9ab8a6e1c933b1e","clean_bundle":{"format":"clean-skill-bundle-v1","source":"mukul975/anthropic-cybersecurity-skills/skills/performing-adversary-in-the-middle-phishing-detection/SKILL.md","attachments":[{"id":"ffd076ee-e5c1-5f74-b004-00b6e52889a7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/ffd076ee-e5c1-5f74-b004-00b6e52889a7/attachment.md","path":"assets/template.md","size":1375,"sha256":"910a0fb9324f5feb101b4c8c47ddd3eeec15f3b2001250ea9ad00f2f7b02873c","contentType":"text/markdown; charset=utf-8"},{"id":"f2a210af-0d79-5ab3-85be-9f1e8b4fb52e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f2a210af-0d79-5ab3-85be-9f1e8b4fb52e/attachment.md","path":"references/api-reference.md","size":2815,"sha256":"a8e243f79a568c9c89bc18db3bd5e1d323d39086b3d8ad781c4ce6f45908f0cd","contentType":"text/markdown; charset=utf-8"},{"id":"78f761ec-1e5d-575a-b35e-e1e378dade59","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/78f761ec-1e5d-575a-b35e-e1e378dade59/attachment.md","path":"references/standards.md","size":1446,"sha256":"3e8bcbc422fac1c99dca0642c11fbcba232b4d49f89af099664cd12e913eae0f","contentType":"text/markdown; charset=utf-8"},{"id":"787e1a82-a082-5b15-9552-1e41b77e1c06","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/787e1a82-a082-5b15-9552-1e41b77e1c06/attachment.md","path":"references/workflows.md","size":1994,"sha256":"fd7edf1a73aad0087192718f747cc4906842f0df19c3cafa8704ba65ccf01488","contentType":"text/markdown; charset=utf-8"},{"id":"29d602f6-3513-5625-8ebe-fd3828447998","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/29d602f6-3513-5625-8ebe-fd3828447998/attachment.py","path":"scripts/agent.py","size":7073,"sha256":"31289e27bd4a5eaf12ebefee22a0b19ee777621cf42906964e12e1af16927c9b","contentType":"text/x-python; charset=utf-8"},{"id":"fb4ff552-6917-562b-8192-26434dcb8b09","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/fb4ff552-6917-562b-8192-26434dcb8b09/attachment.py","path":"scripts/process.py","size":11016,"sha256":"d7880877d3702a2e66c6c57a794382ad363961428f6eb01724b21597bad7b0fc","contentType":"text/x-python; charset=utf-8"}],"bundle_sha256":"6fca52bae1bb427b5a0426c8cc04779fa4c9e76d1a8843aef04904eb8030f824","attachment_count":6,"text_attachments":6,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/performing-adversary-in-the-middle-phishing-detection/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":0},"license":"Apache-2.0","version":"v1","category":"security","nist_csf":["PR.AT-01","DE.CM-09","RS.CO-02","DE.AE-02"],"subdomain":"phishing-defense","import_tag":"clean-skills-v1","description":"Detect and respond to Adversary-in-the-Middle (AiTM) phishing attacks that use reverse proxy kits like EvilProxy, Evilginx, and Tycoon 2FA to bypass MFA and steal session tokens."}},"renderedAt":1782982060019}

Performing Adversary-in-the-Middle Phishing Detection Overview Adversary-in-the-Middle (AiTM) phishing attacks use reverse-proxy infrastructure to sit between the victim and the legitimate authentication service, intercepting both credentials and session cookies in real time. This allows attackers to bypass multi-factor authentication (MFA). The most prevalent PhaaS kits in 2025 include Tycoon 2FA, Sneaky 2FA, EvilProxy, and Evilginx. Over 1 million PhaaS attacks were detected in January-February 2025 alone. These attacks have evolved from QR codes to HTML attachments and SVG files for link d…